@@ -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,65 +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- .long OFF(gdt) / * Base Address * /
106+ .long GDTDATA_BASE / * Base Address * /
120107
121108
122109CheckFor64BitSupport:
@@ -134,7 +121,7 @@ CheckFor64BitSupport:
134121 jnz .CheckForPAE
135122
136123 mov si , offset .Msg_NoCpuidSupport
137- call writestr
124+ call cs_writestr
138125 popad
139126 xor al , al
140127 ret
@@ -151,7 +138,7 @@ CheckFor64BitSupport:
151138 je .CheckForLongMode
152139
153140 mov si , offset .Msg_NoPAE
154- call writestr
141+ call cs_writestr
155142 popad
156143 xor al , al
157144 ret
@@ -175,7 +162,7 @@ CheckFor64BitSupport:
175162
176163.NoLongMode:
177164 mov si , offset .Msg_NoLongMode
178- call writestr
165+ call cs_writestr
179166 popad
180167 xor al , al
181168 ret
@@ -265,7 +252,7 @@ RealModeEntryPoint:
265252 mov cr0 , eax
266253
267254 / * Clear prefetch queue & correct CS * /
268- ljmp16 0 , InRealMode
255+ ljmp16 FREELDR_BASE / 16 , InRealMode
269256
270257InRealMode:
271258
@@ -290,28 +277,56 @@ InRealMode:
290277 xor esp , esp
291278
292279 / * Restore real mode stack * /
293- mov sp , word ptr ds : [ stack16 ]
280+ mov sp , word ptr cs : [ stack16 ]
294281
295282 // sti / * These are ok now * /
296283
297284 / * Do the callback , specified by bx * /
298285 shl bx , 1
299- call word ptr ds :CallbackTable [ bx ]
286+ call word ptr cs :CallbackTable [ bx ]
300287
301288ExitToLongMode:
302289 / * Disable interrupts * /
303290 cli
304291
305292 / * Set correct segment registers * /
306- xor ax , ax
307- mov ds , ax
308- mov es , ax
309- mov fs , ax
310- mov gs , ax
311- 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
312299
313300 / * Save current stack pointer * /
314- 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 ]
315330
316331 / * Set PAE and PGE: 10100000b * /
317332 mov eax , cr4
@@ -335,7 +350,7 @@ ExitToLongMode:
335350 mov cr0 , eax
336351
337352 / * Clear prefetch queue & correct CS * /
338- ljmp16 LMODE_CS , InLongMode
353+ ljmp16 LMODE_CS , TEMPCODE16_BASE
339354InLongMode:
340355 // DB 66h , 0B8h , 18h , 00h // mov ax , LMODE_DS
341356 // DB 66h , 8Eh , 0D8h // mov ds , ax
@@ -350,6 +365,7 @@ LongModeEntryPoint:
350365
351366 int HEX( 16 )
352367 jmp Reboot
368+ LongModeEntryPointEnd:
353369
354370/ * FNID_ * functions * /
355371CallbackTable:
@@ -363,7 +379,7 @@ CallbackTable:
363379
364380 / * 16 - bit stack pointer * /
365381stack16:
366- . word STACK16ADDR
382+ . word 0
367383
368384
369385#include "int386.inc"
0 commit comments