aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarin Ivanov <[email protected]>2024-05-01 23:46:37 +0300
committerMarin Ivanov <[email protected]>2024-05-02 01:04:58 +0300
commitd96142014d0f11af33d42ce0f1084d0810794d8b (patch)
tree5fbeed53434e1386847c5488a5b6b75a9d9367c1 /src
parentbf67bb3b39cf8acad442bc4731c6f300697ad992 (diff)
wip: assembly to switch to long-mode
Diffstat (limited to 'src')
-rw-r--r--src/boot.s17
-rw-r--r--src/boot32.s143
-rw-r--r--src/boot64.s16
-rw-r--r--src/main.zig7
4 files changed, 165 insertions, 18 deletions
diff --git a/src/boot.s b/src/boot.s
deleted file mode 100644
index 2530d18..0000000
--- a/src/boot.s
+++ /dev/null
@@ -1,17 +0,0 @@
-.global _start
-.type _start, @function
-
-.code32
-// Entry point. It puts the machine into a consistent state,
-// starts the kernel and then waits forever.
-_start:
- mov _sstack, %esp // Setup the stack.
-
- push %ebx // Pass multiboot info structure.
- push %eax // Pass multiboot magic code.
- call kmain // Call the kernel.
-
- // Halt the CPU.
- cli
- hlt
-
diff --git a/src/boot32.s b/src/boot32.s
new file mode 100644
index 0000000..04b509f
--- /dev/null
+++ b/src/boot32.s
@@ -0,0 +1,143 @@
+.global _start
+.extern long_mode_start
+
+.section .text
+.code32
+
+// Entry point. It puts the machine into a consistent state and starts long mode.
+_start:
+ mov $0x80000, %esp // Setup the stack.
+ push %ebx // Pass multiboot info structure.
+ push %eax // Pass multiboot magic code.
+
+ call check_multiboot
+ call check_cpuid
+ call check_long_mode
+
+ //call setup_page_tables
+ //call enable_paging
+
+ //lgdt [gdt64.pointer]
+ //jmp gdt64.code_segment:long_mode_start
+
+ call halt
+halt:
+ hlt
+
+check_multiboot:
+ cmp $0x36d76289, %eax
+ jne .no_multiboot
+ ret
+.no_multiboot:
+ mov 'M', %al
+ jmp error
+
+check_cpuid:
+ pushfd
+ pop %eax
+ mov %eax, %ecx
+ xor $(1 << 21), %eax
+ push %eax
+ popfd
+ pushfd
+ pop %eax
+ push %ecx
+ popfd
+ cmp %eax, %ecx
+ je .no_cpuid
+ ret
+.no_cpuid:
+ mov 'C', %al
+ jmp error
+
+check_long_mode:
+ mov $0x80000000, %eax
+ cpuid
+ cmp $0x80000001, %eax
+ jb .no_long_mode
+
+ mov $0x80000001, %eax
+ cpuid
+ test $(1 << 29), %edx
+ jz .no_long_mode
+
+ ret
+.no_long_mode:
+ mov 'L', %al
+ jmp error
+
+//setup_page_tables:
+// mov eax, page_table_l3
+// or eax, 0b11 ; present, writable
+// mov [page_table_l4], eax
+//
+// mov eax, page_table_l2
+// or eax, 0b11 ; present, writable
+// mov [page_table_l3], eax
+//
+// mov ecx, 0 ; counter
+//.loop:
+//
+// mov eax, 0x200000 ; 2MiB
+// mul ecx
+// or eax, 0b10000011 ; present, writable, huge page
+// mov [page_table_l2 + ecx * 8], eax
+//
+// inc ecx ; increment counter
+// cmp ecx, 512 ; checks if the whole table is mapped
+// jne .loop ; if not, continue
+//
+// ret
+//
+//enable_paging:
+// ; pass page table location to cpu
+// mov eax, page_table_l4
+// mov cr3, eax
+//
+// ; enable PAE
+// mov eax, cr4
+// or eax, 1 << 5
+// mov cr4, eax
+//
+// ; enable long mode
+// mov ecx, 0xC0000080
+// rdmsr
+// or eax, 1 << 8
+// wrmsr
+//
+// ; enable paging
+// mov eax, cr0
+// or eax, 1 << 31
+// mov cr0, eax
+//
+// ret
+
+error:
+ // // print "ERR: X" where X is the error code
+ movl $0x4f524f45, 0xb8000
+ // mov dword [0xb8004], 0x4f3a4f52
+ // mov dword [0xb8008], 0x4f204f20
+ // mov byte [0xb800a], al
+ hlt
+
+//section .bss
+//align 4096
+//page_table_l4:
+// resb 4096
+//page_table_l3:
+// resb 4096
+//page_table_l2:
+// resb 4096
+//stack_bottom:
+// resb 4096 * 4
+//stack_top:
+//
+//section .rodata
+//gdt64:
+// dq 0 ; zero entry
+//.code_segment: equ $ - gdt64
+// dq (1 << 43) | (1 << 44) | (1 << 47) | (1 << 53) ; code segment
+//.pointer:
+// dw $ - gdt64 - 1 ; length
+// dq gdt64 ; address
+// \ No newline at end of file
diff --git a/src/boot64.s b/src/boot64.s
new file mode 100644
index 0000000..493912b
--- /dev/null
+++ b/src/boot64.s
@@ -0,0 +1,16 @@
+.global long_mode_start
+.extern kmain
+
+.section .text
+.code64
+long_mode_start:
+ // load null into all data segment registers
+ mov $0, %ax
+ mov %ax, %ss
+ mov %ax, %ds
+ mov %ax, %es
+ mov %ax, %fs
+ mov %ax, %gs
+
+ call kmain
+ hlt \ No newline at end of file
diff --git a/src/main.zig b/src/main.zig
index f3ea424..5534a84 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,8 +1,10 @@
comptime {
- asm (@embedFile("boot.s"));
+ asm (@embedFile("boot64.s"));
+ asm (@embedFile("boot32.s"));
}
const debug = @import("debugcon.zig");
+const console = @import("console.zig");
const ALIGN = 1 << 0;
const MEMINFO = 1 << 1;
@@ -37,6 +39,9 @@ export fn kmain() noreturn {
vga[0] = 0x2f4f;
vga[1] = 0x2f4b;
+ console.initialize();
+ console.puts("test");
+
// write debug data
debug.outb(0xe9, 'H');
debug.outb(0xe9, 'i');