.globl _start .globl MB_INFO .extern _bss_start .extern _bss_end .extern higherhalf .section .multiboot .set MB_MAGIC, 0xE85250D6 .set MB_ARCH, 0x00000000 .set MB_HEADER_LENGTH, (mb_header_end-mb_header_start) .set MB_CHECKSUM, -(MB_MAGIC+MB_ARCH+MB_HEADER_LENGTH) mb_header_start: .align 8 .int MB_MAGIC .int MB_ARCH .int MB_HEADER_LENGTH .int MB_CHECKSUM # ----------- Address tag .align 8 .short 2 .short 0 # Not optional .int 24 # Size .int mb_header_start # header_addr .int mb_header_start # load_addr .int 0x0 # load_end_addr .int 0x0 # bss_end_addr # ----------- Addr tag .align 8 .short 0x3 .short 0 .int 12 .int _start # ----------- End tag # ----------- Ask framebuffer tag .align 8 .short 6 .short 1 .int 20 .int 0 .int 0 .int 0 # ----------- End framebuffer .align 8 .int 0x0 .int 0x8 mb_header_end: .section .text .code32 # Require since grub do not enable long mode MB_INFO: # Will contains the Multiboot2 information data structure address .long 0x0 _start: mov %ebx, (MB_INFO) # ----- Setup PAE Paging (identity on the first 10MB) mov $8192, %ecx # 8*4096/4 (8 tables of 4096 byte each divide by 4 because of movl) mov $0, %eax zeroing_paging: movl $0, (%eax) add $4, %eax loop zeroing_paging # Setup PML4 Table (Address 0x0) mov $0x0, %edi mov %edi, %cr3 # Setup PML4 location movl $0x1003, (%edi) # Setup PDPT location # Setup PDPT mov $0x1000, %edi movl $0x2003, (%edi) # Setup PDPT location # Setup PDT (5 PT = 10MB) mov $0x2000, %edi mov $0x3003, %eax mov $5, %ecx pdt_fill: movl %eax, (%edi) # Setup PDPT location add $8, %edi # Goto next entry add $0x1000, %eax # Next PT loop pdt_fill # Setup the 5 PT mov $0x3000, %edi mov $0x3, %ebx # First map to 0 mov $2560, %ecx # 512*5 pt_fill: mov %ebx, (%edi) add $8, %edi # Next entry add $0x1000, %ebx # Next Page loop pt_fill # ----- Switch to compatibility mode # Set CR4.PAE mov %cr4, %eax bts $5, %eax mov %eax, %cr4 # Set EFER.LME mov $0xC0000080, %ecx rdmsr bts $8, %eax wrmsr # Set CR0.PG mov %cr0, %eax bts $31, %eax mov %eax, %cr0 # Now we are in Compatibility mode # Now we need to set CS.L=1 (setting up a 64 bit GDT) lgdt (boot_gdtr) ljmp $0x08, $new_cs new_cs: # Pay attention here! # You are in long mode here # Thus if you want to add any instructions # You should use .code64 before .code64 mov $0x10, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs mov %ax, %ss mov $__stack_pma, %esp # Setup call trampoline mov $__kernel_vma, %rsp # Zeroing the .bss section mov $__bss_start, %rax mov $__bss_end, %rbx start_zeroing: movb $0x0, (%rax) cmp %rax, %rbx je end_zeroing inc %rax jmp start_zeroing end_zeroing: # Launch kernel call boucane # GDT boot_gdt64: boot_gdt64_null: .long 0 .long 0 boot_gdt64_cs: .long 0 .byte 0 .byte 0b10011100 .byte 0b00100000 .byte 0 boot_gdt64_ds: .long 0 .byte 0 .byte 0b10010010 .word 0 boot_gdtr: .word . - boot_gdt64 - 1 .quad boot_gdt64