@@ -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 )
@@ -64,39 +67,36 @@ Msg_LongModeSupported:
6467.LongModeSupported:
6568 / * Output status * /
6669 mov si , offset Msg_LongModeSupported
67- call writestr
68-
69- / * Load the GDT * /
70- lgdt lXdtPrefix ds : [ gdtptr ]
70+ call cs_writestr
7171
7272 / * Build the startup page tables * /
7373 call BuildPageTables
7474
7575 / * Store real mode entry point in shared memory * /
76- mov dword ptr ds : [ BSS_RealModeEntry ], offset RealModeEntryPoint
76+ mov dword ptr ds : [ BSS_RealModeEntry ], offset RealModeEntryPoint + FREELDR_BASE
7777
7878 / * Address the image with es segment * /
79- mov ax , FREELDR_PE_BASE / 16
79+ mov ax , cs
80+ add ax , (FREELDR_PE_BASE - FREELDR_BASE) / 16
8081 mov es , ax
8182
8283 / * Get address of optional header * /
8384 mov eax , dword ptr es : [ IMAGE_DOS_HEADER_e_lfanew ]
8485 add eax , 4 + IMAGE_FILE_HEADER_SIZE
8586
86- / * Get address of entry point * /
87+ / * Get offset of entry point * /
8788 mov eax , dword ptr es : [ eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint ]
88- add eax , FREELDR_PE_BASE
8989
9090 / * Save entry point * /
91- mov dword ptr ds : [ LongModeEntryPoint ], eax
91+ mov dword ptr cs : [ LongModeEntryPoint ], eax
9292
9393 / * Restore es * /
9494 xor ax , ax
9595 mov es , ax
9696
9797 / * Output status * /
9898 mov si , offset Msg_SwitchToLongMode
99- call writestr
99+ call cs_writestr
100100
101101 jmp ExitToLongMode
102102
@@ -109,14 +109,15 @@ gdt:
109109 . word HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) , HEX( 0000 ) / * 08 : * /
110110 . word HEX( 0000 ) , HEX( 0000 ) , HEX( 9800 ) , HEX( 0020 ) / * 10 : long mode CS * /
111111 . 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 * /
112+ . word HEX(FFFF) , HEX( 0000 ) , HEX(9B00 ) , HEX(008F ) / * 20 : 16 - bit fl at CS (!) * /
113113 . word HEX(FFFF) , HEX( 0000 ) , HEX( 9200 ) , HEX( 0000 ) / * 28 : 16 - bit real mode DS * /
114114 . word HEX(FFFF) , HEX( 0000 ) , HEX(9B00) , HEX(00CF) / * 30 : comp at mode CS * /
115+ gdt_end:
115116
116117/ * GDT table pointer * /
117118gdtptr:
118119 . word HEX( 37 ) / * Limit * /
119- .long OFF(gdt) / * Base Address * /
120+ .long GDTDATA_BASE / * Base Address * /
120121
121122
122123CheckFor64BitSupport:
@@ -134,7 +135,7 @@ CheckFor64BitSupport:
134135 jnz .CheckForPAE
135136
136137 mov si , offset .Msg_NoCpuidSupport
137- call writestr
138+ call cs_writestr
138139 popad
139140 xor al , al
140141 ret
@@ -151,7 +152,7 @@ CheckFor64BitSupport:
151152 je .CheckForLongMode
152153
153154 mov si , offset .Msg_NoPAE
154- call writestr
155+ call cs_writestr
155156 popad
156157 xor al , al
157158 ret
@@ -175,7 +176,7 @@ CheckFor64BitSupport:
175176
176177.NoLongMode:
177178 mov si , offset .Msg_NoLongMode
178- call writestr
179+ call cs_writestr
179180 popad
180181 xor al , al
181182 ret
@@ -265,7 +266,7 @@ RealModeEntryPoint:
265266 mov cr0 , eax
266267
267268 / * Clear prefetch queue & correct CS * /
268- ljmp16 0 , InRealMode
269+ ljmp16 FREELDR_BASE / 16 , InRealMode
269270
270271InRealMode:
271272
@@ -290,28 +291,56 @@ InRealMode:
290291 xor esp , esp
291292
292293 / * Restore real mode stack * /
293- mov sp , word ptr ds : [ stack16 ]
294+ mov sp , word ptr cs : [ stack16 ]
294295
295296 // sti / * These are ok now * /
296297
297298 / * Do the callback , specified by bx * /
298299 shl bx , 1
299- call word ptr ds :CallbackTable [ bx ]
300+ call word ptr cs :CallbackTable [ bx ]
300301
301302ExitToLongMode:
302303 / * Disable interrupts * /
303304 cli
304305
305306 / * 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
307+ xor ax , ax
308+ mov ds , ax
309+ mov es , ax
310+ mov fs , ax
311+ mov gs , ax
312+ mov ss , ax
312313
313314 / * Save current stack pointer * /
314- mov word ptr ds : [ stack16 ], sp
315+ mov word ptr cs : [ stack16 ], sp
316+
317+ / * Set ds to cs segment register * /
318+ mov ax , cs
319+ mov ds , ax
320+
321+ / * Copy the gdt entries to GDTDATA_BASE * /
322+ mov cx , offset gdt_end - gdt
323+ mov si , offset gdt
324+ mov di , GDTDATA_BASE
325+ rep movsb
326+
327+ / * Copy the long mode code to TEMPCODE16_BASE * /
328+ mov cx , offset LongModeEntryPointEnd - InLongMode
329+ mov si , offset InLongMode
330+ mov di , TEMPCODE16_BASE
331+ rep movsb
332+
333+ / * Convert the entry point offset to absolute address * /
334+ mov eax , dword ptr ss : [ BSS_CurrentBaseAddress ]
335+ add eax , FREELDR_PE_BASE - FREELDR_BASE
336+ add dword ptr ss : [ (LongModeEntryPoint - InLongMode) + TEMPCODE16_BASE ], eax
337+
338+ / * Reset ds * /
339+ xor ax , ax
340+ mov ds , ax
341+
342+ / * Load the GDT * /
343+ lgdt lXdtPrefix cs : [ gdtptr ]
315344
316345 / * Set PAE and PGE: 10100000b * /
317346 mov eax , cr4
@@ -335,7 +364,7 @@ ExitToLongMode:
335364 mov cr0 , eax
336365
337366 / * Clear prefetch queue & correct CS * /
338- ljmp16 LMODE_CS , InLongMode
367+ ljmp16 LMODE_CS , TEMPCODE16_BASE
339368InLongMode:
340369 // DB 66h , 0B8h , 18h , 00h // mov ax , LMODE_DS
341370 // DB 66h , 8Eh , 0D8h // mov ds , ax
@@ -350,6 +379,7 @@ LongModeEntryPoint:
350379
351380 int HEX( 16 )
352381 jmp Reboot
382+ LongModeEntryPointEnd:
353383
354384/ * FNID_ * functions * /
355385CallbackTable:
@@ -363,7 +393,7 @@ CallbackTable:
363393
364394 / * 16 - bit stack pointer * /
365395stack16:
366- . word STACK16ADDR
396+ . word 0
367397
368398
369399#include "int386.inc"
0 commit comments