Skip to content

Commit 1fcc18c

Browse files
committed
[FREELDR] Adapt some assembly code for i386 position independent code (reactos#7530)
CORE-19882
1 parent a59e8f5 commit 1fcc18c

File tree

5 files changed

+163
-97
lines changed

5 files changed

+163
-97
lines changed

boot/freeldr/freeldr/arch/realmode/fathelp.inc

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414
#define BiosCHSDriveSizeHigh 6
1515
#define BiosCHSDriveSizeLow 8
1616
#define BiosCHSDriveSize 8
17-
#define ReadSectorsOffset 10
18-
#define ReadClusterOffset 12
19-
#define PutCharsOffset 14
17+
#define ReadSectorsOffset 12
18+
#define ReadClusterOffset 16
19+
#define PutCharsOffset 20
20+
21+
#define ReadSectors far ptr ss:[bp-ReadSectorsOffset]
22+
#define ReadCluster far ptr ss:[bp-ReadClusterOffset]
23+
#define PutChars far ptr ss:[bp-PutCharsOffset]
2024

2125
#define OEMName 3
2226
#define BytesPerSector 11
@@ -65,8 +69,8 @@ FatHelperEntryPoint:
6569
push ax
6670

6771
/* Display "Loading FreeLoader..." message */
68-
mov si, offset msgLoading
69-
call word ptr [bp-PutCharsOffset]
72+
mov si, offset msgLoading
73+
call CS_PutChars
7074

7175
call ReadFatIntoMemory
7276

@@ -92,7 +96,7 @@ LoadFile3:
9296
push ax
9397
xor bx,bx // Load ROSLDR starting at 0000:8000h
9498
push es
95-
call word ptr [bp-ReadClusterOffset]
99+
call ReadCluster
96100
pop es
97101

98102
xor bx,bx
@@ -133,7 +137,7 @@ ReadFatIntoMemory:
133137
mov bx, HEX(7000)
134138
mov es,bx
135139
xor bx,bx
136-
call word ptr [bp-ReadSectorsOffset]
140+
call ReadSectors
137141
ret
138142

139143

@@ -216,6 +220,22 @@ IsFat12_2:
216220
IsFat12_Done:
217221
ret
218222

223+
CS_PutChars:
224+
/* Save necessary registers */
225+
push ax
226+
push ds
227+
228+
/* Prepare ds before PutChars call */
229+
mov ax, cs
230+
mov ds, ax
231+
232+
/* Display the message */
233+
call PutChars
234+
235+
/* Restore necessary registers and return */
236+
pop ds
237+
pop ax
238+
ret
219239

220240
msgLoading:
221241
.ascii "Loading FreeLoader...", CR, LF, NUL

boot/freeldr/freeldr/arch/realmode/helpers.inc

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ Relocator16Boot:
144144
and cx, not (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
145145

146146
/* Get flags CF, ZF and SF from the REGS structure */
147-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_EFLAGS]
147+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_EFLAGS]
148148
and ax, (EFLAGS_CF or EFLAGS_ZF or EFLAGS_SF)
149149

150150
/* Combine flags and set them */
@@ -153,36 +153,47 @@ Relocator16Boot:
153153
popf
154154

155155
/* Setup the segment registers */
156-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
156+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_DS]
157157
mov ds, ax
158-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
158+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_ES]
159159
mov es, ax
160-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
160+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_FS]
161161
mov fs, ax
162-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
162+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_GS]
163163
mov gs, ax
164164

165165
/* Patch the jump address (segment:offset) */
166-
mov eax, dword ptr cs:[BSS_RealModeEntry]
166+
mov eax, dword ptr ss:[BSS_RealModeEntry]
167167
mov dword ptr cs:[Relocator16Address], eax
168168

169-
/* Switch the stack (segment:offset) */
169+
/* Store the stack (segment:offset) */
170170
mov eax, dword ptr cs:[BSS_CallbackReturn]
171171
shr eax, 16
172-
mov ss, ax
172+
mov word ptr cs:[Relocator16SS], ax
173173
mov eax, dword ptr cs:[BSS_CallbackReturn]
174174
and eax, HEX(0FFFF)
175-
mov esp, eax
175+
mov dword ptr cs:[Relocator16ESP], eax
176176

177177
/* Setup the registers */
178-
mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX]
179-
mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX]
180-
mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX]
181-
mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX]
182-
mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI]
183-
mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI]
178+
mov eax, dword ptr ss:[BSS_RegisterSet + REGS_EAX]
179+
mov ebx, dword ptr ss:[BSS_RegisterSet + REGS_EBX]
180+
mov ecx, dword ptr ss:[BSS_RegisterSet + REGS_ECX]
181+
mov edx, dword ptr ss:[BSS_RegisterSet + REGS_EDX]
182+
mov esi, dword ptr ss:[BSS_RegisterSet + REGS_ESI]
183+
mov edi, dword ptr ss:[BSS_RegisterSet + REGS_EDI]
184184
// Don't setup ebp, we only use it as output! <-- FIXME!
185185

186+
/* Save eax */
187+
mov dword ptr cs:[Relocator16EAX], eax
188+
189+
/* Switch the stack (segment:offset) */
190+
mov esp, dword ptr cs:[Relocator16ESP]
191+
mov ax, word ptr cs:[Relocator16SS]
192+
mov ss, ax
193+
194+
/* Restore eax */
195+
mov eax, dword ptr cs:[Relocator16EAX]
196+
186197
/* Jump to the new CS:IP (e.g. jump to bootsector code...) */
187198
.byte HEX(0EA) // ljmp16 segment:offset
188199
Relocator16Address:

boot/freeldr/freeldr/arch/realmode/helpers_pc98.inc

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -207,35 +207,46 @@ Relocator16Boot:
207207
popf
208208

209209
/* Setup the segment registers */
210-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_DS]
210+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_DS]
211211
mov ds, ax
212-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_ES]
212+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_ES]
213213
mov es, ax
214-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_FS]
214+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_FS]
215215
mov fs, ax
216-
mov ax, word ptr cs:[BSS_RegisterSet + REGS_GS]
216+
mov ax, word ptr ss:[BSS_RegisterSet + REGS_GS]
217217
mov gs, ax
218218

219219
/* Patch the jump address (segment:offset) */
220-
mov eax, dword ptr cs:[BSS_RealModeEntry]
220+
mov eax, dword ptr ss:[BSS_RealModeEntry]
221221
mov dword ptr cs:[Relocator16Address], eax
222222

223-
/* Switch the stack (segment:offset) */
223+
/* Store the stack (segment:offset) */
224224
mov eax, dword ptr cs:[BSS_CallbackReturn]
225225
shr eax, 16
226-
mov ss, ax
226+
mov word ptr cs:[Relocator16SS], ax
227227
mov eax, dword ptr cs:[BSS_CallbackReturn]
228228
and eax, HEX(0FFFF)
229-
mov esp, eax
229+
mov dword ptr cs:[Relocator16ESP], eax
230230

231231
/* Setup the registers */
232-
mov eax, dword ptr cs:[BSS_RegisterSet + REGS_EAX]
233-
mov ebx, dword ptr cs:[BSS_RegisterSet + REGS_EBX]
234-
mov ecx, dword ptr cs:[BSS_RegisterSet + REGS_ECX]
235-
mov edx, dword ptr cs:[BSS_RegisterSet + REGS_EDX]
236-
mov esi, dword ptr cs:[BSS_RegisterSet + REGS_ESI]
237-
mov edi, dword ptr cs:[BSS_RegisterSet + REGS_EDI]
238-
mov ebp, dword ptr cs:[BSS_RegisterSet + REGS_EBP]
232+
mov eax, dword ptr ss:[BSS_RegisterSet + REGS_EAX]
233+
mov ebx, dword ptr ss:[BSS_RegisterSet + REGS_EBX]
234+
mov ecx, dword ptr ss:[BSS_RegisterSet + REGS_ECX]
235+
mov edx, dword ptr ss:[BSS_RegisterSet + REGS_EDX]
236+
mov esi, dword ptr ss:[BSS_RegisterSet + REGS_ESI]
237+
mov edi, dword ptr ss:[BSS_RegisterSet + REGS_EDI]
238+
mov ebp, dword ptr ss:[BSS_RegisterSet + REGS_EBP]
239+
240+
/* Save eax */
241+
mov dword ptr cs:[Relocator16EAX], eax
242+
243+
/* Switch the stack (segment:offset) */
244+
mov esp, dword ptr cs:[Relocator16ESP]
245+
mov ax, word ptr cs:[Relocator16SS]
246+
mov ss, ax
247+
248+
/* Restore eax */
249+
mov eax, dword ptr cs:[Relocator16EAX]
239250

240251
/* Jump to the new CS:IP */
241252
.byte HEX(0EA) /* ljmp16 segment:offset */

boot/freeldr/freeldr/arch/realmode/i386.S

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,54 +25,55 @@ RealModeEntryPoint:
2525
mov ss, ax
2626

2727
/* Setup the stack */
28-
mov sp, word ptr ds:[stack16]
28+
mov sp, STACK16ADDR
2929

3030
/* Enable A20 address line */
3131
call EnableA20
3232

33+
/* Update BSS_CurrentBaseAddress, instruction pointer and code segment */
34+
call UpdateCurrentCodeSegment
35+
36+
/* Output first status */
37+
mov si, offset Msg_Starting
38+
call cs_writestr
39+
3340
/* Save real mode entry point in shared memory */
34-
mov dword ptr ds:[BSS_RealModeEntry], offset switch_to_real16
41+
mov dword ptr ds:[BSS_RealModeEntry], offset switch_to_real16 + FREELDR_BASE
3542

3643
/* Address the image with es segment */
37-
mov ax, FREELDR_PE_BASE / 16
44+
mov ax, cs
45+
add ax, (FREELDR_PE_BASE - FREELDR_BASE) / 16
3846
mov es, ax
3947

4048
/* Get address of optional header */
4149
mov eax, dword ptr es:[IMAGE_DOS_HEADER_e_lfanew]
4250
add eax, 4 + IMAGE_FILE_HEADER_SIZE
4351

44-
/* Get address of entry point */
52+
/* Get offset of entry point */
4553
mov eax, dword ptr es:[eax + IMAGE_OPTIONAL_HEADER_AddressOfEntryPoint]
46-
add eax, FREELDR_PE_BASE
4754

4855
/* Save entry point */
49-
mov dword ptr ds:[pm_entrypoint], eax
56+
mov dword ptr cs:[pm_entrypoint], eax
5057

5158
/* Restore es */
5259
xor ax, ax
5360
mov es, ax
5461

5562
jmp exit_to_protected
5663

64+
Msg_Starting:
65+
.ascii "Starting FreeLoader...", CR, LF, NUL
5766

5867
/* This is the entry point from protected mode */
5968
switch_to_real16:
6069

61-
/* Restore segment registers to correct limit */
62-
mov ax, RMODE_DS
63-
mov ds, ax
64-
mov es, ax
65-
mov fs, ax
66-
mov gs, ax
67-
mov ss, ax
68-
6970
/* Disable Protected Mode */
7071
mov eax, cr0
7172
and eax, CR0_PE_CLR
7273
mov cr0, eax
7374

7475
/* Clear prefetch queue & correct CS */
75-
ljmp16 0, inrmode
76+
ljmp16 FREELDR_BASE / 16, inrmode
7677

7778
inrmode:
7879
/* Set real mode segments */
@@ -92,20 +93,16 @@ inrmode:
9293
xor esp, esp
9394

9495
/* Restore real mode stack */
95-
mov sp, word ptr ds:[stack16]
96+
mov sp, word ptr cs:[stack16]
9697

9798
/* Load IDTR with real mode value */
98-
#ifdef _USE_ML
99-
lidt fword ptr rmode_idtptr
100-
#else
101-
lidt rmode_idtptr
102-
#endif
99+
lidt lXdtPrefix cs:[rmode_idtptr]
103100

104101
sti /* These are ok now */
105102

106103
/* Do the callback, specified by bx */
107104
shl bx, 1
108-
call word ptr ds:CallbackTable[bx]
105+
call word ptr cs:CallbackTable[bx]
109106

110107

111108
/*
@@ -117,28 +114,54 @@ exit_to_protected:
117114
cli
118115

119116
/* Save current stack pointer */
120-
mov word ptr ds:[stack16], sp
117+
mov word ptr cs:[stack16], sp
118+
119+
/* Set ds to cs segment register */
120+
mov ax, cs
121+
mov ds, ax
122+
123+
/* Copy the gdt entries to GDTDATA_BASE */
124+
mov cx, offset gdt_end - gdt
125+
mov si, offset gdt
126+
mov di, GDTDATA_BASE
127+
rep movsb
128+
129+
/* Copy the protected mode code to TEMPCODE16_BASE */
130+
mov cx, offset pm_entrypoint_end - inpmode
131+
mov si, offset inpmode
132+
mov di, TEMPCODE16_BASE
133+
rep movsb
134+
135+
/* Convert the entry point offset to absolute address */
136+
mov eax, dword ptr ss:[BSS_CurrentBaseAddress]
137+
add eax, FREELDR_PE_BASE - FREELDR_BASE
138+
add dword ptr ss:[(pm_entrypoint - inpmode) + TEMPCODE16_BASE], eax
139+
140+
/* Reset ds */
141+
xor ax, ax
142+
mov ds, ax
121143

122144
/* Load the GDT */
123-
#ifdef _USE_ML
124-
lgdt fword ptr gdtptr
125-
#else
126-
lgdt gdtptr
127-
#endif
145+
lgdt lXdtPrefix cs:[gdtptr]
128146

129147
/* Enable Protected Mode */
130148
mov eax, cr0
131149
or eax, CR0_PE_SET
132150
mov cr0, eax
133151

134152
/* Clear prefetch queue & correct CS */
135-
ljmp16 PMODE_CS, inpmode
153+
ljmp16 PMODE_CS, TEMPCODE16_BASE
136154
inpmode:
137155
.byte HEX(0ff), HEX(25) // opcode of indirect jump
138-
.word pm_entrypoint, 0
156+
#ifdef _USE_ML
157+
.long (offset pm_entrypoint - inpmode) + TEMPCODE16_BASE
158+
#else
159+
.long (pm_entrypoint - inpmode) + TEMPCODE16_BASE
160+
#endif
139161
pm_entrypoint:
140162
.long 0 // receives address of PE entry point
141163
nop
164+
pm_entrypoint_end:
142165

143166
/* FNID_* functions */
144167
CallbackTable:
@@ -176,22 +199,23 @@ gdt:
176199
.word HEX(9200)
177200
.word HEX(00CF)
178201

179-
/* 16-bit real mode CS */
202+
/* 16-bit flat CS (!) */
180203
.word HEX(FFFF)
181204
.word HEX(0000)
182-
.word HEX(9E00)
183-
.word HEX(0000)
205+
.word HEX(9B00)
206+
.word HEX(008F)
184207

185208
/* 16-bit real mode DS */
186209
.word HEX(FFFF)
187210
.word HEX(0000)
188211
.word HEX(9200)
189212
.word HEX(0000)
213+
gdt_end:
190214

191215
/* GDT table pointer */
192216
gdtptr:
193217
.word HEX(27) /* Limit */
194-
.word gdt, 0 /* Base Address */
218+
.long GDTDATA_BASE /* Base Address */
195219

196220
/* Real-mode IDT pointer */
197221
rmode_idtptr:

0 commit comments

Comments
 (0)