diff options
Diffstat (limited to 'kernel/boot.S')
| -rw-r--r-- | kernel/boot.S | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/kernel/boot.S b/kernel/boot.S new file mode 100644 index 0000000..4276c98 --- /dev/null +++ b/kernel/boot.S @@ -0,0 +1,138 @@ +.global _start +.extern begin_long_mode + +.section .text +.code32 + +_start: + mov $stack_top, %esp + + call check_multiboot + call check_cpuid + call check_long_mode + + call setup_page_tables + call enable_paging + + lgdt gdt64_pointer + ljmp $gdt64_code_segment, $begin_long_mode + + +check_multiboot: + cmp $0x36d76289, %eax + jne no_multiboot + + ret + +check_cpuid: + pushfl + pop %eax + mov %eax, %ecx + xor $1<<21, %eax + push %eax + popfl + pushfl + pop %eax + push %ecx + popfl + cmp %eax, %ecx + je no_cpuid + + ret + +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 + +setup_page_tables: + mov $page_table_lvl3, %eax + or $0x3, %eax + mov %eax, page_table_lvl4 + + mov $page_table_lvl2, %eax + or $0x3, %eax + mov %eax, page_table_lvl3 + + movl $0, %ecx +1: + movl $0x200000, %eax + mul %ecx + or $0b10000011, %eax + movl $page_table_lvl2, %edx + leal (%edx, %ecx, 8), %edx + movl %eax, (%edx) + inc %ecx + cmp $512, %ecx + jne 1b + + ret + +enable_paging: + // enable PAE + mov %cr4, %edx + or $1<<5 ,%edx + mov %edx, %cr4 + + // set LME (long mode enable) + mov $0xC0000080, %ecx + rdmsr + or $1<<8, %eax + wrmsr + + // page_table_lvl4 + mov $page_table_lvl4, %eax + mov %eax, %cr3 + + // enable paging (+ protected mode if not already enabled) + mov %cr0, %eax + or $1<<31 + 1<<0, %eax + mov %eax, %cr0 + + ret + +no_multiboot: + movl $0x4f4d, 0xb8000 + hlt + +no_cpuid: + movl $0x4f43, 0xb8000 + hlt + +no_long_mode: + movl $0x4f4c, 0xb8000 + hlt + + +.section .bss +.align 4096 + +// stack +stack_bottom: + .skip 4096*4 +stack_top: + +// page tables +page_table_lvl4: + .skip 4096 +page_table_lvl3: + .skip 4096 +page_table_lvl2: + .skip 4096 + +.section .rodata +gdt64: + .quad 0 +gdt64_code_segment = . - gdt64 + .quad 1<<43 + 1<<44 + 1<<47 + 1<<53 +gdt64_pointer: + .word . - gdt64 - 1 + .quad gdt64 |
