@@ -28,24 +28,27 @@ Startup:
2828 mov byte ptr ds : [ BSS_BootDrive ], dl
2929 mov byte ptr ds : [ BSS_BootPartition ], dh
3030
31- / * Setup a real mode stack * /
32- mov sp , word ptr ds : [ stack16 ]
33-
34- / * Output first status * /
35- mov si , offset Msg_Starting
36- call writestr
31+ / * Setup the stack * /
32+ mov sp , STACK16ADDR
3733
3834 / * Enable A20 address line * /
3935 call EnableA20
4036
37+ / * Update BSS_CurrentBaseAddress , instruction pointer and code segment * /
38+ call UpdateCurrentCodeSegment
39+
40+ / * Output first status * /
41+ mov si , offset Msg_Starting
42+ call cs_writestr
43+
4144 / * Check the CPU * /
4245 call CheckFor64BitSupport
4346 test al , al
4447 jnz .LongModeSupported
4548
4649 / * Output failure message * /
4750 mov si , offset Msg_Unsupported
48- call writestr
51+ call cs_writestr
4952
5053 / * Wait for a keypress * /
5154 int HEX( 16 )
@@ -58,69 +61,49 @@ Msg_Unsupported:
5861Msg_Starting:
5962 .ascii "Starting FreeLoader..." , CR , LF , NUL
6063
61- Msg_LongModeSupported:
62- .ascii "Long mode support detected." , CR , LF , NUL
63-
6464.LongModeSupported:
65- / * Output status * /
66- mov si , offset Msg_LongModeSupported
67- call writestr
68-
69- / * Load the GDT * /
70- lgdt lXdtPrefix ds : [ gdtptr ]
71-
7265 / * Build the startup page tables * /
7366 call BuildPageTables
7467
7568 / * Store real mode entry point in shared memory * /
76- mov dword ptr ds : [ BSS_RealModeEntry ], offset RealModeEntryPoint
69+ mov dword ptr ds : [ BSS_RealModeEntry ], offset RealModeEntryPoint + FREELDR_BASE
7770
7871 / * Address the image with es segment * /
79- mov ax , FREELDR_PE_BASE / 16
72+ mov ax , cs
73+ add ax , (FREELDR_PE_BASE - FREELDR_BASE) / 16
8074 mov es , ax
8175
8276 / * Get address of optional header * /
8377 mov eax , dword ptr es : [ IMAGE_DOS_HEADER_e_lfanew ]
8478 add eax , 4 + IMAGE_FILE_HEADER_SIZE
8579
86- / * Get address of entry point * /
80+ / * Get offset of entry point * /
8781 mov eax , dword ptr es : [ eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint ]
88- add eax , FREELDR_PE_BASE
8982
9083 / * Save entry point * /
91- mov dword ptr ds : [ LongModeEntryPoint ], eax
84+ mov dword ptr cs : [ LongModeEntryPoint ], eax
9285
9386 / * Restore es * /
9487 xor ax , ax
9588 mov es , ax
9689
97- / * Output status * /
98- mov si , offset Msg_SwitchToLongMode
99- call writestr
100-
10190 jmp ExitToLongMode
10291
103- Msg_SwitchToLongMode:
104- .ascii "Switching to long mode...." , CR , LF , NUL
105-
10692. align 8
10793gdt:
10894 . word HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) / * 00 : NULL descriptor * /
10995 . word HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) / * 08 : * /
11096 . word HEX( 0000 ) , HEX( 0000 ) , HEX( 9800 ) , HEX( 0020 ) / * 10 : long mode CS * /
11197 . word HEX(FFFF) , HEX( 0000 ) , HEX(F300) , HEX(00CF) / * 18 : long mode DS * /
112- . word HEX(FFFF) , HEX( 0000 ) , HEX(9E00 ) , HEX( 0000 ) / * 20 : 16 - bit real mode CS * /
98+ . word HEX(FFFF) , HEX( 0000 ) , HEX(9B00 ) , HEX(008F ) / * 20 : 16 - bit fl at CS (!) * /
11399 . word HEX(FFFF) , HEX( 0000 ) , HEX( 9200 ) , HEX( 0000 ) / * 28 : 16 - bit real mode DS * /
114100 . word HEX(FFFF) , HEX( 0000 ) , HEX(9B00) , HEX(00CF) / * 30 : comp at mode CS * /
101+ gdt_end:
115102
116103/ * GDT table pointer * /
117104gdtptr:
118105 . word HEX( 37 ) / * Limit * /
119- #ifdef _USE_ML
120- .long offset gdt / * Base Address * /
121- #else
122- .long gdt / * Base Address * /
123- #endif
106+ .long GDTDATA_BASE / * Base Address * /
124107
125108
126109CheckFor64BitSupport:
@@ -138,7 +121,7 @@ CheckFor64BitSupport:
138121 jnz .CheckForPAE
139122
140123 mov si , offset .Msg_NoCpuidSupport
141- call writestr
124+ call cs_writestr
142125 popad
143126 xor al , al
144127 ret
@@ -155,7 +138,7 @@ CheckFor64BitSupport:
155138 je .CheckForLongMode
156139
157140 mov si , offset .Msg_NoPAE
158- call writestr
141+ call cs_writestr
159142 popad
160143 xor al , al
161144 ret
@@ -179,7 +162,7 @@ CheckFor64BitSupport:
179162
180163.NoLongMode:
181164 mov si , offset .Msg_NoLongMode
182- call writestr
165+ call cs_writestr
183166 popad
184167 xor al , al
185168 ret
@@ -269,7 +252,7 @@ RealModeEntryPoint:
269252 mov cr0 , eax
270253
271254 / * Clear prefetch queue & correct CS * /
272- ljmp16 0 , InRealMode
255+ ljmp16 FREELDR_BASE / 16 , InRealMode
273256
274257InRealMode:
275258
@@ -294,28 +277,56 @@ InRealMode:
294277 xor esp , esp
295278
296279 / * Restore real mode stack * /
297- mov sp , word ptr ds : [ stack16 ]
280+ mov sp , word ptr cs : [ stack16 ]
298281
299282 // sti / * These are ok now * /
300283
301284 / * Do the callback , specified by bx * /
302285 shl bx , 1
303- call word ptr ds :CallbackTable [ bx ]
286+ call word ptr cs :CallbackTable [ bx ]
304287
305288ExitToLongMode:
306289 / * Disable interrupts * /
307290 cli
308291
309292 / * Set correct segment registers * /
310- xor ax , ax
311- mov ds , ax
312- mov es , ax
313- mov fs , ax
314- mov gs , ax
315- mov ss , ax
293+ xor ax , ax
294+ mov ds , ax
295+ mov es , ax
296+ mov fs , ax
297+ mov gs , ax
298+ mov ss , ax
316299
317300 / * Save current stack pointer * /
318- mov word ptr ds : [ stack16 ], sp
301+ mov word ptr cs : [ stack16 ], sp
302+
303+ / * Set ds to cs segment register * /
304+ mov ax , cs
305+ mov ds , ax
306+
307+ / * Copy the gdt entries to GDTDATA_BASE * /
308+ mov cx , offset gdt_end - gdt
309+ mov si , offset gdt
310+ mov di , GDTDATA_BASE
311+ rep movsb
312+
313+ / * Copy the long mode code to TEMPCODE16_BASE * /
314+ mov cx , offset LongModeEntryPointEnd - InLongMode
315+ mov si , offset InLongMode
316+ mov di , TEMPCODE16_BASE
317+ rep movsb
318+
319+ / * Convert the entry point offset to absolute address * /
320+ mov eax , dword ptr ss : [ BSS_CurrentBaseAddress ]
321+ add eax , FREELDR_PE_BASE - FREELDR_BASE
322+ add dword ptr ss : [ (LongModeEntryPoint - InLongMode) + TEMPCODE16_BASE ], eax
323+
324+ / * Reset ds * /
325+ xor ax , ax
326+ mov ds , ax
327+
328+ / * Load the GDT * /
329+ lgdt lXdtPrefix cs : [ gdtptr ]
319330
320331 / * Set PAE and PGE: 10100000b * /
321332 mov eax , cr4
@@ -339,7 +350,7 @@ ExitToLongMode:
339350 mov cr0 , eax
340351
341352 / * Clear prefetch queue & correct CS * /
342- ljmp16 LMODE_CS , InLongMode
353+ ljmp16 LMODE_CS , TEMPCODE16_BASE
343354InLongMode:
344355 // DB 66h , 0B8h , 18h , 00h // mov ax , LMODE_DS
345356 // DB 66h , 8Eh , 0D8h // mov ds , ax
@@ -354,6 +365,7 @@ LongModeEntryPoint:
354365
355366 int HEX( 16 )
356367 jmp Reboot
368+ LongModeEntryPointEnd:
357369
358370/ * FNID_ * functions * /
359371CallbackTable:
0 commit comments