.globl _start .globl MB_INFO .extern _bss_start .extern _bss_end .extern boucane .set STACK_LOCATION, 0x1FFFFF .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 .align 8 .int 0x0 .int 0x8 mb_header_end: .section .text .code32 # Require since grub do not enable long mode MB_INFO: .int 0xABCDEF # Will contains the Multiboot2 information data structure address _start: mov %ebx,(MB_INFO) # Zeroing the .bss section mov $_bss_start, %eax mov $_bss_end, %ebx start_zeroing: movb $0x0, (%eax) cmp %eax, %ebx je end_zeroing inc %eax jmp start_zeroing end_zeroing: # ----- 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 (gdtr) jmp $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_LOCATION, %esp # Run boucane jmp boucane # GDT gdt64: gdt64_null: .long 0 .long 0 gdt64_cs: .long 0 .byte 0 .byte 0b10011100 .byte 0b00100000 .byte 0 gdt64_ds: .long 0 .byte 0 .byte 0b10010010 .word 0 gdtr: .word . - gdt64 - 1 .quad gdt64