#include "boot.h" #include "processor_flags.h" #define rva(x) ((x)-startup_32) #define __BOOT_DS (3*8) #define __KERNEL32_CS (1*8) #define __KERNEL_CS (2*8) .section .head.text, "ax" .global _start _start: // just make linker happy .code32 .global startup_32 .type startup_32, %function startup_32: movl $0x50000, %edx movl $0xdeadbeef, (%edx) cld cli // Actually multiboot doesn't give us a scartch area to use as stack, // so we temporaily save the 2nd 32bit of boot information and use it as the stack. movl 4(%ebx), %ecx leal 8(%ebx), %esp call 1f 1: popl %ebp movl %ecx, 4(%ebx) subl $rva(1b), %ebp leal rva(gdt)(%ebp), %eax mov %eax, 2(%eax) lgdt (%eax) mov $__BOOT_DS, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs mov %ax, %ss leal rva(boot_stack_end)(%ebp), %esp pushl $__KERNEL32_CS leal rva(1f)(%ebp), %eax pushl %eax lret 1: movl %cr4, %eax orl $X86_CR4_PAE, %eax movl %eax, %cr4 leal rva(pgtable)(%ebp), %edi xorl %eax, %eax movl $(BOOT_INIT_PGTABLE_SIZE/4), %ecx rep stosl leal rva(pgtable)(%ebp), %edi leal 0x1007(%edi), %eax movl %eax, 0(%edi) leal rva(pgtable + 0x1000)(%ebp), %edi leal 0x1007(%edi), %eax movl $4, %ecx 1: movl %eax, 0(%edi) addl $0x1000, %eax addl $8, %edi decl %ecx jnz 1b leal rva(pgtable + 0x2000)(%ebp), %edi movl $0x183, %eax movl $2048, %ecx 1: movl %eax, 0(%edi) addl $0x200000, %eax addl $8, %edi decl %ecx jnz 1b leal rva(pgtable)(%ebp), %eax movl %eax, %cr3 movl $MSR_EFER, %ecx rdmsr btsl $_EFER_LME, %eax wrmsr leal rva(startup_64)(%ebp), %eax pushl $__KERNEL_CS pushl %eax movl $CR0_STATE, %eax movl %eax, %cr0 lret #define rva64(x) ((x)-startup_64) #define STARTUP64_OFFSET 0x200 .code64 .global startup_64 .type startup_64, %function .org STARTUP64_OFFSET startup_64: cld cli xorl %eax, %eax movl %eax, %ds movl %eax, %es movl %eax, %ss movl %eax, %fs movl %eax, %gs movq %rbx, %rsi movq $LOAD_PHYSICAL_ADDR, %rbp // movl has the side effect of zero-extending the upper 32 bits of rbx movl $uncompressed_kernel_size, %ebx // there's no need to copy the code before startup_64 addq %rbp, %rbx leaq rva64(boot_stack_end)(%rbx), %rsp movq %rsi, %r15 leaq (_bss - 8)(%rip), %rsi leaq rva64(_bss - 8)(%rbx), %rdi movl $rva64(_bss), %ecx shrl $3, %ecx std rep movsq cld leaq rva64(gdt64)(%rbx), %rax leaq rva64(gdt)(%rbx), %rdx movq %rdx, 2(%rax) lgdt (%rax) leaq rva64(relocated)(%rbx), %rax jmp *%rax .text relocated: // clear bss xorl %eax, %eax leaq _bss(%rip), %rdi leaq _ebss(%rip), %rcx subq %rdi, %rcx shrq $3, %rcx rep stosq mov %rbx, %rdi subq $STARTUP64_OFFSET, %rdi call relocateSelf movq %r15, %rdi // boot params pointer movq %rbp, %rsi // load physical address call extractKernel hlt .data gdt64: .word gdt_end - gdt - 1 .quad gdt - gdt64 gdt64_end: .balign 8 gdt: .word gdt_end - gdt - 1 .long 0 .word 0 .quad 0x00cf9a000000ffff // __KERNEL32_CS .quad 0x00af9a000000ffff // __KERNEL_CS .quad 0x00cf92000000ffff // __KERNEL_DS gdt_end: .bss .balign 4 boot_heap: .space BOOT_HEAP_SIZE boot_stack: .space BOOT_STACK_SIZE boot_stack_end: .section ".pgtable","aw",@nobits .balign 4096 pgtable: .space BOOT_PGTABLE_SIZE pgtable_end: