Skip to content

Commit 0ac5ca2

Browse files
committed
[FREELDR] Adapt some assembly code for amd64 position relative code (reactos#7530)
CORE-19882
1 parent abb8632 commit 0ac5ca2

File tree

1 file changed

+64
-34
lines changed
  • boot/freeldr/freeldr/arch/realmode

1 file changed

+64
-34
lines changed

boot/freeldr/freeldr/arch/realmode/amd64.S

Lines changed: 64 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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 flat 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: compat mode CS */
115+
gdt_end:
115116

116117
/* GDT table pointer */
117118
gdtptr:
118119
.word HEX(37) /* Limit */
119-
.long OFF(gdt) /* Base Address */
120+
.long GDTDATA_BASE /* Base Address */
120121

121122

122123
CheckFor64BitSupport:
@@ -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

270271
InRealMode:
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

301302
ExitToLongMode:
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
339368
InLongMode:
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 */
355385
CallbackTable:
@@ -363,7 +393,7 @@ CallbackTable:
363393

364394
/* 16-bit stack pointer */
365395
stack16:
366-
.word STACK16ADDR
396+
.word 0
367397

368398

369399
#include "int386.inc"

0 commit comments

Comments
 (0)