1/* 2 * Multiboot Entry 3 */ 4 5#define STACK_SIZE 0x4000 6 7#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 8#define MULTIBOOT_HEADER_FLAGS 0x00010003 9//#define KERNEL_BASE 0x0000000000000000 10#define KERNEL_BASE 0xFFFF800000000000 11#define LOWMEM(_x) (_x - KERNEL_BASE) 12 13.extern mb_entry 14 15.text 16 17/** 18 * _start -- 19 * 20 * ELF entry point. 21 */ 22.globl _start 23_start: .code32 24 jmp multiboot_entry 25 26/** 27 * This header needs to be present near the start of the ELF binary that 28 * describes how the loader should load the operating system image into memory. 29 */ 30.align 4 31multiboot_header: .code32 32.long MULTIBOOT_HEADER_MAGIC 33.long MULTIBOOT_HEADER_FLAGS 34.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) 35.long LOWMEM(multiboot_header) 36.long LOWMEM(_start) 37.long LOWMEM(_edata) 38.long LOWMEM(_end) 39.long LOWMEM(multiboot_entry) 40 41// 42// Multiboot entry 43// %eax: Magic (0x2BADB002) 44// %ebx: multiboot info structure 45// 46multiboot_entry: .code32 47 // Save multiboot magic 48 movl %eax, %edx 49 50 // Setup the stack pointer 51 movl $LOWMEM(lmfarptr), %edi 52 movw $(0x7000 + 'A'), (0xB8000) 53 movl $LOWMEM(stack + STACK_SIZE), %esp 54 55 // Reset EFLAGS to a known state 56 movw $(0x7000 + 'B'), (0xB8002) 57 pushl $0 58 popf 59 60 // Configure the CPU control register cr4 61 movw $(0x7000 + 'C'), (0xB8004) 62 movl %cr4, %eax 63 orl $0x0000006A0, %eax 64 movl %eax, %cr4 65 66 // Load the 32-bit page table 67 movw $(0x7000 + 'D'), (0xB8006) 68 movl $LOWMEM(bootpgtbl1), %eax 69 movl %eax, %cr3 70 71 // Enable 64-bit mode (long mode) and no-execute (NX) support 72 movw $(0x7000 + 'E'), (0xB8008) 73 movl $0xC0000080, %ecx 74 rdmsr 75 orl $0x0900, %eax 76 wrmsr 77 78 // Load the GDT that contains segment descriptors. 79 movw $(0x7000 + 'E'), (0xB800A) 80 movl $LOWMEM(bootgdtdesc), %eax 81 lgdt (%eax) 82 83 // Configure cr0 84 movw $(0x7000 + 'F'), (0xB800C) 85 movl %cr0, %eax 86 orl $0x8005002B, %eax 87 movl %eax, %cr0 88 89 // Long jump into 64-bit mode 90 movw $(0x7000 + '0'), (0xB800E) 91 ljmp *(%edi) 92 93 // No we're playing with power 94lmenter: .code64 95 movw $(0x7000 + '1'), (0xB8010) 96 xorw %ax, %ax 97 movw %ax, %ss 98 movw %ax, %ds 99 movw %ax, %es 100 movw %ax, %fs 101 movw %ax, %gs 102 103 movq $LOWMEM(stack + STACK_SIZE), %rax 104 movq $0xFFFF8000, %rcx 105 shlq $32, %rcx 106 orq %rcx, %rax 107 movq %rax, %rsp 108 109 // Long jump into the high memory address where the kernel executes in 110 movq $LOWMEM(lmhighptr), %rdi 111 jmp *(%rdi) 112 113lmhigh: 114 movw $(0x7000 + '2'), (0xB8012) 115 116 movq %rdx, %rdi // Magic 117 movq %rbx, %rsi // Multiboot info pointer 118 119 call MachineBoot_Entry 120 121 # Print halt to the graphics memory if we return 122 movw $(0x5000 + 'H'), (0xB8098) 123 movw $(0x5000 + 'A'), (0xB809A) 124 movw $(0x5000 + 'L'), (0xB809C) 125 movw $(0x5000 + 'T'), (0xB809E) 126loop: 127 hlt 128 jmp loop 129 130.p2align 4 131lmfarptr: 132.long LOWMEM(lmenter) 133.word 0x08 134 135.p2align 4 136lmhighptr: 137.quad lmhigh 138 139.p2align 12 140bootgdt: 141.quad 0x0000000000000000 /* Null */ 142.quad 0x00AF9A000000FFFF /* Kernel CS */ 143.quad 0x00CF92000000FFFF /* Kernel DS */ 144.quad 0x0000000000000000 145.quad 0x0000000000000000 146.quad 0x0000000000000000 147.quad 0x0000000000000000 148.quad 0x0000000000000000 149 150.p2align 4 151.globl bootgdtdesc 152bootgdtdesc: 153.word 0x003F 154.quad LOWMEM(bootgdt) 155 156// Boot stack 157.p2align 12 158.globl stack 159.comm stack, STACK_SIZE 160 161