.section .text .set PAGE_PRESENT, 1 << 0 .set PAGE_WRITE, 1 << 1 .set PAGE_SIZE, 1 << 7 .code32 .global _start _start: mov $stack_top, %esp mov %ebx, mb_info_ptr # clear bss mov $__bss_start, %ecx jmp .bss_zero_check .bss_zero_loop: movl $0, (%ecx) add $4, %ecx .bss_zero_check: cmp $__bss_end, %ecx jb .bss_zero_loop # fail if not loaded by multiboot2 cmp $MB_BOOTLOADER_MAGIC, %eax jne .boot_failure # map first gb to page_table_l2 mov $0, %ecx .page_loop: mov %ecx, %eax shl $21, %eax or $(PAGE_PRESENT | PAGE_WRITE | PAGE_SIZE), %eax mov %eax, page_table_l2(,%ecx,8) inc %ecx cmp $512, %ecx jne .page_loop # the rest of the levels mov $page_table_l2, %eax or $(PAGE_PRESENT | PAGE_WRITE), %eax mov %eax, page_table_l3 mov $page_table_l3, %eax or $(PAGE_PRESENT | PAGE_WRITE), %eax mov %eax, page_table_l4 # page table addr to CR3 mov $page_table_l4, %eax mov %eax, %cr3 # enable PAE (CR4.PAE) mov %cr4, %eax or $(1 << 5), %eax mov %eax, %cr4 # enable long mode (EFER.LME) mov $0xc0000080, %ecx rdmsr or $(1 << 8), %eax wrmsr # enable paging (CR0.PG) mov %cr0, %eax or $(1 << 31), %eax mov %eax, %cr0 # enable GDT and jump to long mode lgdt gdt64_ptr ljmp $0x08, $long_main .boot_failure: # TODO: more failure cases liek idk cpu doesnt support long mode movb $'e', 0xb8000 movb $' ', 0xb8001 # green cli .halt32: hlt jmp .halt32 .code64 long_main: mov $stack_top, %rsp mov $0, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs mov %ax, %ss call kernel_main cli .halt64: hlt jmp .halt64 .section .rodata mb_info_ptr: .space 4 .set GDT_FL_LONG, 1 << 53 .set GDT_ACC_RDWR, 1 << 41 .set GDT_ACC_EXEC, 1 << 43 .set GDT_ACC_NOTSYS, 1 << 44 .set GDT_ACC_PRESENT, 1 << 47 gdt64: .quad 0 .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR | GDT_ACC_EXEC | GDT_FL_LONG .quad GDT_ACC_PRESENT | GDT_ACC_NOTSYS | GDT_ACC_RDWR gdt64_ptr: .word . - gdt64 - 1 .quad gdt64 .section .bss .align 4096 page_table_l4: .space 4096 page_table_l3: .space 4096 page_table_l2: .space 4096 .align 16 stack_bottom: .space 1024 * 16 stack_top: .section .multiboot, "a" .set MB_BOOTLOADER_MAGIC, 0x36d76289 .set MB_MAGIC, 0xE85250D6 .set MB_ARCH, 0 .set MB_LENGTH, (multiboot_hdr_end - multiboot_hdr) .set MB_CHECKSUM, -(MB_LENGTH + MB_ARCH + MB_MAGIC) .align 8 multiboot_hdr: .long MB_MAGIC .long MB_ARCH .long MB_LENGTH .long MB_CHECKSUM multiboot_hdr_end: .set MB_TAG_END, 0 .set MB_TAG_INFO_REQ, 1 .set MB_INFO_MMAP, 6 .align 8 .word MB_TAG_INFO_REQ .word 0 .long 8 + 4 .long MB_INFO_MMAP .align 8 .word MB_TAG_END .word 0 .long 8