Skip to content

Commit bc10285

Browse files
committed
[FREELDR] Add/change necessary code for the initial position relative code (reactos#7530)
CORE-19882
1 parent 81edd1f commit bc10285

File tree

6 files changed

+158
-8
lines changed

6 files changed

+158
-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: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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+
/* This function will Update BSS_CurrentBaseAddress, instruction pointer, code segment and relocate if necessary */
16+
RelocateFreeLdr:
17+
/* Clear direction flag */
18+
cld
19+
20+
/* Clear necessary registers */
21+
xor eax, eax
22+
xor ebx, ebx
23+
xor ecx, ecx
24+
25+
/* Call the sub function to get the base address */
26+
call .SubCall
27+
.SubCall:
28+
/* Pop the return address into bx. Since the return address is consumed,
29+
* this function does not return to UpdateCurrentCodeSegment */
30+
pop bx
31+
32+
/* Calculate the base address by adjusting the offset */
33+
sub bx, offset .SubCall - FREELDR_BASE
34+
35+
/* Load the current code segment into eax */
36+
mov ax, cs
37+
38+
/* Shift the segment address to get its physical address (real mode calculation) */
39+
shl eax, 4
40+
41+
/* Add the physical segment base to the relative base address */
42+
add eax, ebx
43+
44+
/* Store the calculated base address (low 32 bits) */
45+
mov dword ptr ds:[BSS_CurrentBaseAddress], eax
46+
47+
.FixBaseAddress:
48+
/* Don't relocate if it's not necessary */
49+
cmp eax, FREELDR_BASE
50+
jz .NotNecessaryRelocation
51+
52+
/* Setup source segment */
53+
shr eax, 4
54+
mov ds, ax
55+
56+
/* Move the realmode FREELDR code to TEMPCODE16_BASE */
57+
mov di, TEMPCODE16_BASE
58+
xor si, si
59+
mov cx, FREELDR_PE_BASE - FREELDR_BASE
60+
rep movsb
61+
62+
ljmp16 TEMPCODE16_BASE / 16, (.FixBaseAddress2 - FREELDR_BASE)
63+
.FixBaseAddress2:
64+
/* Prepare the registers for relocation */
65+
mov cx, (MEMORY_MARGIN - FREELDR_BASE) / 16
66+
mov eax, dword ptr es:[BSS_CurrentBaseAddress]
67+
shr eax, 4
68+
mov ds, ax
69+
mov ax, FREELDR_BASE / 16
70+
mov es, ax
71+
72+
/* If current base address is lower than the final one then just copy it backwards */
73+
cmp dword ptr fs:[BSS_CurrentBaseAddress], FREELDR_BASE
74+
jb .PreFixLoopInverted
75+
.FixLoop:
76+
/* Save CX */
77+
push cx
78+
79+
/* Copy 16 bytes from source to destination */
80+
xor di, di
81+
xor si, si
82+
mov cx, HEX(10) / 4
83+
rep movsd
84+
85+
/* Restore CX */
86+
pop cx
87+
88+
/* Increment DS */
89+
mov ax, ds
90+
inc ax
91+
mov ds, ax
92+
93+
/* Increment ES */
94+
mov ax, es
95+
inc ax
96+
mov es, ax
97+
98+
/* Repeat the loop while decrementing cx */
99+
loop .FixLoop
100+
jmp .FinishedRelocation
101+
.PreFixLoopInverted:
102+
/* Move DS to the end */
103+
mov ax, ds
104+
add ax, cx
105+
mov ds, ax
106+
107+
/* Move ES to the end */
108+
mov ax, es
109+
add ax, cx
110+
mov es, ax
111+
.FixLoopInverted:
112+
/* Decrement DS */
113+
mov ax, ds
114+
dec ax
115+
mov ds, ax
116+
117+
/* Decrement ES */
118+
mov ax, es
119+
dec ax
120+
mov es, ax
121+
122+
/* Save CX */
123+
push cx
124+
125+
/* Copy 16 bytes from source to destination */
126+
xor di, di
127+
xor si, si
128+
mov cx, HEX(10) / 4
129+
rep movsd
130+
131+
/* Restore CX */
132+
pop cx
133+
134+
/* Repeat the loop while decrementing cx */
135+
loop .FixLoopInverted
136+
137+
.FinishedRelocation:
138+
add sp, 2
139+
ljmp16 0, .AfterRelocation
140+
141+
.NotNecessaryRelocation:
142+
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: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
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)
17+
#define FREELDR_BASE HEX(F600)
1818
#define FREELDR_PE_BASE HEX(10000)
19+
#define TEMPDATA16_BASE HEX(7000)
20+
#define TEMPCODE16_BASE HEX(7400)
21+
#define TEMPCODE_BASE HEX(200000)
1922
#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 */
@@ -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

boot/freeldr/freeldr/pcat.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ if(ARCH STREQUAL "i386")
1313
CreateBootSectorTarget(frldr16
1414
${CMAKE_CURRENT_SOURCE_DIR}/arch/realmode/i386.S
1515
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
16-
F800)
16+
F600)
1717
elseif(ARCH STREQUAL "amd64")
1818
CreateBootSectorTarget(frldr16
1919
${CMAKE_CURRENT_SOURCE_DIR}/arch/realmode/amd64.S
2020
${CMAKE_CURRENT_BINARY_DIR}/frldr16.bin
21-
F800)
21+
F600)
2222
endif()
2323

2424

0 commit comments

Comments
 (0)