Skip to content

Commit 3c79792

Browse files
committed
[FREELDR] Add/change necessary code for the initial position relative code (reactos#7530)
CORE-19882
1 parent 5a89920 commit 3c79792

File tree

5 files changed

+171
-8
lines changed

5 files changed

+171
-8
lines changed

boot/freeldr/freeldr/arch/amd64/entry.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ SwitchToRealCompSegment:
214214
.byte HEX(0EA) // 32bit long jmp
215215
AddressOfRealModeEntryPoint:
216216
.long 0 // receives address of RealModeEntryPoint
217-
.word HEX(20)//RMODE_CS
217+
.word L_RMODE_CS
218218
nop
219219

220220
CallRealMode_return:

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ stack16:
367367

368368

369369
#include "int386.inc"
370+
#include "helpers_all.inc"
370371
#include "helpers.inc"
371372
#include "pxe.inc"
372373
#include "pnp.inc"
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* PROJECT: FreeLoader
3+
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4+
* PURPOSE: Real mode helper code for all architectures
5+
* COPYRIGHT: Copyright 2024-2025 Daniel Victor <[email protected]>
6+
*/
7+
8+
Relocator16SS:
9+
.word 0
10+
Relocator16EAX:
11+
.long 0
12+
Relocator16ESP:
13+
.long 0
14+
15+
cs_writestr:
16+
/* Save necessary registers */
17+
push ax
18+
push ds
19+
20+
/* Prepare ds before writestr call */
21+
mov ax, cs
22+
mov ds, ax
23+
24+
/* Display the message */
25+
call writestr
26+
27+
/* Restore necessary registers and return */
28+
pop ds
29+
pop ax
30+
ret
31+
32+
/* This function will Update BSS_CurrentBaseAddress, instruction pointer, code segment and relocate if necessary */
33+
RelocateFreeLdr:
34+
/* Clear necessary registers */
35+
xor eax, eax
36+
xor ebx, ebx
37+
xor ecx, ecx
38+
39+
/* Call the sub function to get the base address */
40+
call .SubCall
41+
.SubCall:
42+
/* Pop the return address into bx. Since the return address is consumed,
43+
* this function does not return to UpdateCurrentCodeSegment */
44+
pop bx
45+
46+
/* Calculate the base address by adjusting the offset */
47+
sub bx, offset .SubCall
48+
49+
/* Load the current code segment into eax */
50+
mov ax, cs
51+
52+
/* Shift the segment address to get its physical address (real mode calculation) */
53+
shl eax, 4
54+
55+
/* Add the physical segment base to the relative base address */
56+
add eax, ebx
57+
58+
/* Store the calculated base address (low 32 bits) */
59+
mov dword ptr ds:[BSS_CurrentBaseAddress], eax
60+
61+
.FixBaseAddress:
62+
/* Don't relocate if it's not necessary */
63+
cmp eax, FREELDR_BASE
64+
jz .NotNecessaryRelocation
65+
66+
/* Setup source segment */
67+
shr eax, 4
68+
mov ds, ax
69+
70+
/* Move the realmode FREELDR code to TEMPCODE16_BASE */
71+
mov di, TEMPCODE16_BASE
72+
xor si, si
73+
mov cx, FREELDR_PE_BASE - FREELDR_BASE
74+
rep movsb
75+
76+
ljmp16 TEMPCODE16_BASE / 16, .FixBaseAddress2
77+
.FixBaseAddress2:
78+
/* Prepare the registers for relocation */
79+
mov cx, (MEMORY_MARGIN - FREELDR_BASE) / 16
80+
mov eax, dword ptr es:[BSS_CurrentBaseAddress]
81+
shr eax, 4
82+
mov ds, ax
83+
mov ax, FREELDR_BASE / 16
84+
mov es, ax
85+
86+
/* If current base address is lower than the final one then just copy it backwards */
87+
cmp dword ptr fs:[BSS_CurrentBaseAddress], FREELDR_BASE
88+
jb .PreFixLoopInverted
89+
.FixLoop:
90+
/* Save CX */
91+
push cx
92+
93+
/* Copy 16 bytes from source to destination */
94+
xor di, di
95+
xor si, si
96+
mov cx, HEX(10)
97+
rep movsb
98+
99+
/* Restore CX */
100+
pop cx
101+
102+
/* Increment DS */
103+
mov ax, ds
104+
inc ax
105+
mov ds, ax
106+
107+
/* Increment ES */
108+
mov ax, es
109+
inc ax
110+
mov es, ax
111+
112+
/* Repeat the loop while decrementing cx */
113+
loop .FixLoop
114+
jmp .FinishedRelocation
115+
.PreFixLoopInverted:
116+
/* Move DS to the end */
117+
mov ax, ds
118+
add ax, cx
119+
mov ds, ax
120+
121+
/* Move ES to the end */
122+
mov ax, es
123+
add ax, cx
124+
mov es, ax
125+
.FixLoopInverted:
126+
/* Decrement DS */
127+
mov ax, ds
128+
dec ax
129+
mov ds, ax
130+
131+
/* Decrement ES */
132+
mov ax, es
133+
dec ax
134+
mov es, ax
135+
136+
/* Save CX */
137+
push cx
138+
139+
/* Copy 16 bytes from source to destination */
140+
xor di, di
141+
xor si, si
142+
mov cx, HEX(10)
143+
rep movsb
144+
145+
/* Restore CX */
146+
pop cx
147+
148+
/* Repeat the loop while decrementing cx */
149+
loop .FixLoopInverted
150+
151+
.FinishedRelocation:
152+
ljmp16 FREELDR_BASE / 16, 0
153+
154+
.NotNecessaryRelocation:
155+
ret

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ rmode_idtptr:
199199
.long 0 /* Base Address */
200200

201201
#include "int386.inc"
202+
#include "helpers_all.inc"
202203
#if defined(SARCH_PC98)
203204
#include "helpers_pc98.inc"
204205
#else

boot/freeldr/freeldr/include/arch/pc/x86common.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
#define BIOSCALLBUFFER HEX(4000) /* Buffer to store temporary data for any Int386() call */
1313
#define STACK16ADDR HEX(6F00) /* The 16-bit stack top will be at 0000:6F00 */
1414
#define BSS_START HEX(6F00)
15-
#define STACKLOW HEX(7000)
15+
#define STACKLOW HEX(8000)
1616
#define STACKADDR HEX(F000) /* The 32/64-bit stack top will be at 0000:F000, or 0xF000 */
17-
#define FREELDR_BASE HEX(F800)
18-
#define FREELDR_PE_BASE HEX(10000)
19-
#define MEMORY_MARGIN HEX(88000) /* We need this much memory */
17+
#define FREELDR_BASE HEX(F600)
18+
#define FREELDR_PE_BASE HEX(10000)
19+
#define TEMPDATA16_BASE HEX(7000)
20+
#define TEMPCODE16_BASE HEX(7400)
21+
#define TEMPCODE_BASE HEX(200000)
22+
#define MEMORY_MARGIN HEX(88000) /* We need this much memory */
2023

2124
#define BIOSCALLBUFSEGMENT (BIOSCALLBUFFER/16) /* Buffer to store temporary data for any Int386() call */
2225
#define BIOSCALLBUFOFFSET HEX(0000) /* Buffer to store temporary data for any Int386() call */
@@ -49,6 +52,7 @@
4952
#define BSS_PnpResult (BSS_START + 104)
5053
#define BSS_BootDrive (BSS_START + 108) // 1 byte
5154
#define BSS_BootPartition (BSS_START + 109) // 1 byte
55+
#define BSS_CurrentBaseAddress (BSS_START + 110) // 4 bytes
5256

5357

5458
/* Realmode function IDs */
@@ -73,7 +77,9 @@
7377
#define RMODE_DS HEX(20) /* RMode data selector, base 0 limit 64k */
7478
//#else
7579
/* Long mode selectors */
76-
#define LMODE_CS HEX(10)
77-
#define LMODE_DS HEX(18)
78-
#define CMODE_CS HEX(30)
80+
#define LMODE_CS HEX(10)
81+
#define LMODE_DS HEX(18)
82+
#define L_RMODE_CS HEX(20)
83+
#define L_RMODE_DS HEX(28)
84+
#define CMODE_CS HEX(30)
7985
//#endif

0 commit comments

Comments
 (0)