Skip to content

Commit 201247c

Browse files
committed
[FREELDR] Adapt some assembly code for i386 position relative code (reactos#7530)
CORE-19882
1 parent 3c79792 commit 201247c

File tree

6 files changed

+137
-98
lines changed

6 files changed

+137
-98
lines changed

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

Lines changed: 26 additions & 6 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 dword ptr ss:[bp-ReadSectorsOffset]
22+
#define ReadCluster dword ptr ss:[bp-ReadClusterOffset]
23+
#define PutChars dword ptr ss:[bp-PutCharsOffset]
2024

2125
#define OEMName 3
2226
#define BytesPerSector 11
@@ -66,7 +70,7 @@ FatHelperEntryPoint:
6670

6771
/* Display "Loading FreeLoader..." message */
6872
mov si, offset msgLoading
69-
call word ptr [bp-PutCharsOffset]
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: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@ 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+
/* Relocate FreeLdr if necessary */
34+
call RelocateFreeLdr
35+
ljmp16 FREELDR_BASE / 16, .SegmentRelocationPoint
36+
.SegmentRelocationPoint:
37+
38+
/* Output first status */
39+
mov si, offset Msg_Starting
40+
call cs_writestr
41+
3342
/* Save real mode entry point in shared memory */
34-
mov dword ptr ds:[BSS_RealModeEntry], offset switch_to_real16
43+
mov dword ptr ds:[BSS_RealModeEntry], offset switch_to_real16 + FREELDR_BASE
3544

3645
/* Address the image with es segment */
3746
mov ax, FREELDR_PE_BASE / 16
@@ -46,33 +55,27 @@ RealModeEntryPoint:
4655
add eax, FREELDR_PE_BASE
4756

4857
/* Save entry point */
49-
mov dword ptr ds:[pm_entrypoint], eax
58+
mov dword ptr cs:[pm_entrypoint], eax
5059

5160
/* Restore es */
5261
xor ax, ax
5362
mov es, ax
5463

5564
jmp exit_to_protected
5665

66+
Msg_Starting:
67+
.ascii "Starting FreeLoader...", CR, LF, NUL
5768

5869
/* This is the entry point from protected mode */
5970
switch_to_real16:
6071

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-
6972
/* Disable Protected Mode */
7073
mov eax, cr0
7174
and eax, CR0_PE_CLR
7275
mov cr0, eax
7376

7477
/* Clear prefetch queue & correct CS */
75-
ljmp16 0, inrmode
78+
ljmp16 FREELDR_BASE / 16, inrmode
7679

7780
inrmode:
7881
/* Set real mode segments */
@@ -92,20 +95,16 @@ inrmode:
9295
xor esp, esp
9396

9497
/* Restore real mode stack */
95-
mov sp, word ptr ds:[stack16]
98+
mov sp, word ptr cs:[stack16]
9699

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

104103
sti /* These are ok now */
105104

106105
/* Do the callback, specified by bx */
107106
shl bx, 1
108-
call word ptr ds:CallbackTable[bx]
107+
call word ptr cs:CallbackTable[bx]
109108

110109

111110
/*
@@ -117,28 +116,25 @@ exit_to_protected:
117116
cli
118117

119118
/* Save current stack pointer */
120-
mov word ptr ds:[stack16], sp
119+
mov word ptr cs:[stack16], sp
121120

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

129124
/* Enable Protected Mode */
130125
mov eax, cr0
131126
or eax, CR0_PE_SET
132127
mov cr0, eax
133128

134129
/* Clear prefetch queue & correct CS */
135-
ljmp16 PMODE_CS, inpmode
130+
ljmp16 PMODE_CS, inpmode + FREELDR_BASE
136131
inpmode:
137132
.byte HEX(0ff), HEX(25) // opcode of indirect jump
138-
.word pm_entrypoint, 0
133+
.long OFF(pm_entrypoint) + FREELDR_BASE
139134
pm_entrypoint:
140135
.long 0 // receives address of PE entry point
141136
nop
137+
pm_entrypoint_end:
142138

143139
/* FNID_* functions */
144140
CallbackTable:
@@ -153,7 +149,7 @@ CallbackTable:
153149

154150
/* 16-bit stack pointer */
155151
stack16:
156-
.word STACK16ADDR
152+
.word 0
157153

158154

159155
.align 4 /* force 4-byte alignment */
@@ -176,22 +172,23 @@ gdt:
176172
.word HEX(9200)
177173
.word HEX(00CF)
178174

179-
/* 16-bit real mode CS */
175+
/* 16-bit flat CS (!) */
180176
.word HEX(FFFF)
181177
.word HEX(0000)
182-
.word HEX(9E00)
183-
.word HEX(0000)
178+
.word HEX(9B00)
179+
.word HEX(008F)
184180

185181
/* 16-bit real mode DS */
186182
.word HEX(FFFF)
187183
.word HEX(0000)
188184
.word HEX(9200)
189185
.word HEX(0000)
186+
gdt_end:
190187

191188
/* GDT table pointer */
192189
gdtptr:
193-
.word HEX(27) /* Limit */
194-
.long OFF(gdt) /* Base Address */
190+
.word HEX(27) /* Limit */
191+
.long OFF(gdt) + FREELDR_BASE /* Base Address */
195192

196193
/* Real-mode IDT pointer */
197194
rmode_idtptr:

0 commit comments

Comments
 (0)