3 #include <arch/pc/x86common.h>
5 #define IMAGE_DOS_HEADER_e_lfanew 36
6 #define IMAGE_FILE_HEADER_SIZE 20
7 #define IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint 16
13 #include "fathelp.inc"
20 /* Setup real mode segment registers */
28 /* checkPoint Charlie - where it all began... */
29 mov si, offset CheckPoint0
32 /* Setup a real mode stack */
35 /* Zero BootDrive and BootPartition */
38 mov BootPartition, eax
40 /* Store the boot drive */
43 /* Store the boot partition */
53 /* checkPoint Charlie - where it all began... */
54 mov si, offset CheckPoint1
57 call x86_16_BuildPageTables
59 /* checkPoint Charlie - where it all began... */
60 mov si, offset CheckPoint2
63 /* Check if CPU supports CPUID */
67 xor eax, HEX(00200000)
73 jz no_cpuid_support_detected
75 /* CPUID support detected - getting the PAE/PGE */
77 mov eax,1 // Fn0000_0001 - PAE in EDX[6]
81 test edx,edx // are PAE and PGE bits set?
82 jz no_x64_support_detected
84 /* PAE and PGE are here */
87 mov eax, HEX(80000001)
89 and edx, HEX(20000000)
91 jz no_x64_support_detected
95 /* checkPoint Charlie - where it all began... */
96 mov si, offset CheckPoint3
99 /* Get address of optional header */
100 mov eax, dword ptr ds:[FREELDR_PE_BASE + IMAGE_DOS_HEADER_e_lfanew]
101 add eax, FREELDR_PE_BASE + 4 + IMAGE_FILE_HEADER_SIZE
103 /* Get address of entry point */
104 mov eax, dword ptr ds:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
106 /* Store the address in the callback return variable */
107 mov dword ptr ds:[CallbackReturnAddress], eax
111 jmp x86_16_ReturnToLong
114 no_x64_support_detected:
115 mov si, offset NotAnX64Processor // Loading message
119 no_cpuid_support_detected:
120 mov si, offset NoCPUIDSupport // Loading message
129 * We define 512 2MB pages at the start of memory, so we can access the first
130 * 1 GB as if paging was disabled
132 x86_16_BuildPageTables:
136 /* Get segment of pml4 */
137 mov eax, offset pml4_startup
143 /* One entry in the PML4 pointing to PDP */
144 mov eax, offset pdp_startup
152 /* One entry in the PDP pointing to PD */
153 mov eax, offset pd_startup
161 /* 512 entries in the PD defining a 2MB page each */
167 mov dword ptr es: [di + 4], 0
168 add eax, 512 << 12 // add 512 4k pages
195 /* Get the return address off the stack */
196 pop word ptr code64ret
198 /* Save 16-bit stack pointer */
201 mov eax, 0x00a0 // Set PAE and PGE: 10100000b
204 mov edx, offset pml4_startup // Point cr3 at PML4
207 mov ecx, HEX(0C0000080) // Specify EFER MSR
209 rdmsr // Enable long mode
210 or eax, HEX(00000100)
213 mov ebx, cr0 // Activate long mode
214 or ebx, HEX(080000001) // by enabling paging and protection simultaneously
215 mov cr0, ebx // skipping protected mode entirely
217 //jmp LMODE_CS:offset LongCat //Load CS with 64 bit segment and flush the instruction cache
218 // Do a long jmp to the CallbackReturn address
221 #include "helpers.inc"