github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/boot/boot64.S (about) 1 .code32 2 3 .global _start 4 _start: 5 6 # zero 4 pages for our bootstrap page tables 7 xor %eax, %eax 8 mov $0x1000, %edi 9 mov $0x5000, %ecx 10 rep stosb 11 12 # P4ML[0] -> 0x2000 (PDPT-A) 13 mov $(0x2000 | 3), %eax 14 mov %eax, 0x1000 15 16 # P4ML[511] -> 0x3000 (PDPT-B) 17 mov $(0x3000 | 3), %eax 18 mov %eax, 0x1FF8 19 20 # PDPT-A[0] -> 0x4000 (PD) 21 mov $(0x4000 | 3), %eax 22 mov %eax, 0x2000 23 24 # PDPT-B[510] -> 0x4000 (PD) 25 mov $(0x4000 | 3), %eax 26 mov %eax, 0x3FF0 27 28 # PD[0..511] -> 0..1022MB 29 mov $0x83, %eax 30 mov $0x4000, %ebx 31 mov $512, %ecx 32 ptbl_loop: 33 mov %eax, (%ebx) 34 add $0x200000, %eax # 2 MB 35 add $0x8, %ebx 36 dec %ecx 37 jnz ptbl_loop 38 39 # Clear ebx for initial processor boot. 40 # When secondary processors boot, they'll call through 41 # entry32mp (from entryother), but with a nonzero ebx. 42 # We'll reuse these bootstrap pagetables and GDT. 43 xor %ebx, %ebx 44 45 .global entry32mp 46 entry32mp: 47 # CR3 -> 0x1000 (P4ML) 48 mov $0x1000, %eax 49 mov %eax, %cr3 50 51 lgdt (gdtr64) 52 53 # Enable PAE - CR4.PAE=1 54 mov %cr4, %eax 55 bts $5, %eax 56 mov %eax, %cr4 57 58 # enable long mode - EFER.LME=1 59 mov $0xc0000080, %ecx 60 rdmsr 61 bts $8, %eax 62 wrmsr 63 64 # enable paging 65 mov %cr0, %eax 66 bts $31, %eax 67 mov %eax, %cr0 68 69 # shift to 64bit segment 70 ljmp $8,$(entry64low) 71 72 .align 16 73 gdtr64: 74 .word gdt64_end - gdt64_begin - 1; 75 .quad gdt64_begin 76 77 .align 16 78 gdt64_begin: 79 .long 0x00000000 # 0: null desc 80 .long 0x00000000 81 .long 0x00000000 # 1: Code, R/X, Nonconforming 82 .long 0x00209800 83 .long 0x00000000 # 2: Data, R/W, Expand Down 84 .long 0x00009000 85 gdt64_end: 86 87 .align 16 88 .code64 89 entry64low: 90 movq $entry64high, %rax 91 jmp *%rax 92 93 entry64high: 94 95 # ensure data segment registers are sane 96 xor %rax, %rax 97 mov %ax, %ss 98 mov %ax, %ds 99 mov %ax, %es 100 mov %ax, %fs 101 mov %ax, %gs 102 103 // # check to see if we're booting a secondary core 104 // test %ebx, %ebx 105 // jnz entry64mp 106 107 # setup initial stack 108 // mov $0xFFFFFFFF80010000, %rax 109 // mov %rax, %rsp 110 111 # enter boot64main() 112 // %rdi, %rsi, %rdx, %rcx, %r8 and %r9 are args 113 movl 4(%rsp), %edi 114 movl 8(%rsp), %esi 115 movl 12(%rsp), %edx 116 jmp boot64main 117 118 .global __deadloop 119 __deadloop: 120 # we should never return here... 121 jmp . 122 123 // entry64mp: 124 // # obtain kstack from data block before entryother 125 // mov $0x7000, %rax 126 // mov -16(%rax), %rsp 127 // jmp mpenter 128 129 .global wrmsr 130 wrmsr: 131 mov %rdi, %rcx # arg0 -> msrnum 132 mov %rsi, %rax # val.low -> eax 133 shr $32, %rsi 134 mov %rsi, %rdx # val.high -> edx 135 wrmsr 136 retq