mirror of
https://github.com/reactos/reactos.git
synced 2024-06-10 14:35:31 +00:00
[FREELDR] Enable UEFI boot for x86 and amd64 (#5267)
Co-authored-by: Stanislav Motylkov <x86corez@gmail.com> Co-authored-by: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org> - Allow to boot NT kernel on UEFI systems with our 2 primary supported architectures - Implement remaining code needed to pass execution to x86 and amd64 kernels CORE-11954
This commit is contained in:
parent
a6b281c228
commit
ff3dadf89d
85
boot/freeldr/freeldr/arch/uefi/amd64/uefiasm.S
Normal file
85
boot/freeldr/freeldr/arch/uefi/amd64/uefiasm.S
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: FreeLoader UEFI Support
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: x64 assembly UEFI escape helper functions
|
||||||
|
* COPYRIGHT: Copyright 2023 Justin Miller <justinmiller100@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <arch/pc/x86common.h>
|
||||||
|
#include <arch/pc/pcbios.h>
|
||||||
|
|
||||||
|
EXTERN UefiServiceStack:QWORD
|
||||||
|
EXTERN BasicStack:QWORD
|
||||||
|
EXTERN ExecuteLoaderCleanly:PROC
|
||||||
|
EXTERN UefiExitBootServices:PROC
|
||||||
|
|
||||||
|
.code64
|
||||||
|
|
||||||
|
// void _exituefi(VOID)
|
||||||
|
PUBLIC _exituefi
|
||||||
|
_exituefi:
|
||||||
|
/* Save non-volatile registers */
|
||||||
|
push rbp
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
push rbx
|
||||||
|
|
||||||
|
/* Save the old stack */
|
||||||
|
mov rbx, rsp
|
||||||
|
|
||||||
|
/* Load the new stack */
|
||||||
|
xor rbp, rbp
|
||||||
|
mov rsp, qword ptr UefiServiceStack[rip]
|
||||||
|
|
||||||
|
/* Call the entry routine, passing the parameters */
|
||||||
|
mov rax, UefiExitBootServices[rip]
|
||||||
|
call rax
|
||||||
|
|
||||||
|
/* Retore old stack */
|
||||||
|
mov rsp, rbx
|
||||||
|
|
||||||
|
/* Retore non-volatiles */
|
||||||
|
pop rbx
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rbp
|
||||||
|
|
||||||
|
#ifdef _USE_ML
|
||||||
|
lgdt fword ptr [_gdtptr]
|
||||||
|
#else
|
||||||
|
lgdt cs:[_gdtptr][rip] /* GAS isn't my friend - avoid letting it generate absolute addressing */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
ret
|
||||||
|
|
||||||
|
// void _changestack(VOID)
|
||||||
|
PUBLIC _changestack
|
||||||
|
_changestack:
|
||||||
|
mov rax, rsp
|
||||||
|
mov rsp, BasicStack[rip]
|
||||||
|
push rax
|
||||||
|
call ExecuteLoaderCleanly[rip]
|
||||||
|
ret
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
gdt:
|
||||||
|
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 00: NULL descriptor */
|
||||||
|
.word HEX(0000), HEX(0000), HEX(0000), HEX(0000) /* 08: */
|
||||||
|
.word HEX(0000), HEX(0000), HEX(9800), HEX(0020) /* 10: long mode CS */
|
||||||
|
.word HEX(FFFF), HEX(0000), HEX(F300), HEX(00CF) /* 18: long mode DS */
|
||||||
|
.word HEX(FFFF), HEX(0000), HEX(9E00), HEX(0000) /* 20: 16-bit real mode CS */
|
||||||
|
.word HEX(FFFF), HEX(0000), HEX(9200), HEX(0000) /* 28: 16-bit real mode DS */
|
||||||
|
.word HEX(FFFF), HEX(0000), HEX(9B00), HEX(00CF) /* 30: compat mode CS */
|
||||||
|
|
||||||
|
/* GDT table pointer */
|
||||||
|
_gdtptr:
|
||||||
|
.word HEX(37) /* Limit */
|
||||||
|
#ifdef _USE_ML
|
||||||
|
.quad gdt /* Base Address */
|
||||||
|
#else
|
||||||
|
.quad gdt, 0 /* Base Address */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
END
|
109
boot/freeldr/freeldr/arch/uefi/i386/uefiasm.S
Normal file
109
boot/freeldr/freeldr/arch/uefi/i386/uefiasm.S
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: FreeLoader UEFI Support
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: i386 assembly UEFI escape helper functions
|
||||||
|
* COPYRIGHT: Copyright 2023 Justin Miller <justinmiller100@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <arch/pc/x86common.h>
|
||||||
|
#include <arch/pc/pcbios.h>
|
||||||
|
|
||||||
|
PUBLIC _gdtptr
|
||||||
|
PUBLIC _i386idtptr
|
||||||
|
PUBLIC __changestack
|
||||||
|
EXTERN _UefiServiceStack:DWORD
|
||||||
|
EXTERN _i386Idt:DWORD
|
||||||
|
EXTERN _ExecuteLoaderCleanly:PROC
|
||||||
|
EXTERN _UefiExitBootServices:PROC
|
||||||
|
EXTERN _BasicStack:DWORD
|
||||||
|
.code32
|
||||||
|
|
||||||
|
// void __exituefi(VOID)
|
||||||
|
PUBLIC __exituefi
|
||||||
|
__exituefi:
|
||||||
|
push ebp
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebx
|
||||||
|
|
||||||
|
/* Save the old stack */
|
||||||
|
mov ebx, esp
|
||||||
|
|
||||||
|
/* Load the new stack */
|
||||||
|
xor ebp, ebp
|
||||||
|
mov esp, _UefiServiceStack
|
||||||
|
|
||||||
|
/* Call the entry routine, passing the parameters */
|
||||||
|
call _UefiExitBootServices
|
||||||
|
|
||||||
|
/* Retore old stack */
|
||||||
|
mov esp, ebx
|
||||||
|
|
||||||
|
/* Retore non-volatiles */
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
|
||||||
|
#ifdef _USE_ML
|
||||||
|
lidt fword ptr ds:[_i386idtptr]
|
||||||
|
lgdt fword ptr [_gdtptr]
|
||||||
|
#else
|
||||||
|
lgdt cs:[_gdtptr]
|
||||||
|
lidt _i386idtptr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
ret
|
||||||
|
|
||||||
|
// void __reloadsegment(VOID)
|
||||||
|
PUBLIC __changestack
|
||||||
|
__changestack:
|
||||||
|
mov eax, esp
|
||||||
|
mov esp, _BasicStack
|
||||||
|
push eax
|
||||||
|
call _ExecuteLoaderCleanly
|
||||||
|
ret
|
||||||
|
|
||||||
|
.align 4 /* force 4-byte alignment */
|
||||||
|
gdt:
|
||||||
|
/* NULL Descriptor */
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(0000)
|
||||||
|
|
||||||
|
/* 32-bit flat CS */
|
||||||
|
.word HEX(FFFF)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(9A00)
|
||||||
|
.word HEX(00CF)
|
||||||
|
|
||||||
|
/* 32-bit flat DS */
|
||||||
|
.word HEX(FFFF)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(9200)
|
||||||
|
.word HEX(00CF)
|
||||||
|
|
||||||
|
/* 16-bit real mode CS */
|
||||||
|
.word HEX(FFFF)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(9E00)
|
||||||
|
.word HEX(0000)
|
||||||
|
|
||||||
|
/* 16-bit real mode DS */
|
||||||
|
.word HEX(FFFF)
|
||||||
|
.word HEX(0000)
|
||||||
|
.word HEX(9200)
|
||||||
|
.word HEX(0000)
|
||||||
|
|
||||||
|
/* GDT table pointer */
|
||||||
|
_gdtptr:
|
||||||
|
.word HEX(27) /* Limit */
|
||||||
|
.long gdt, 0 /* Base Address */
|
||||||
|
|
||||||
|
_i386idtptr:
|
||||||
|
.word 255 /* Limit */
|
||||||
|
.long _i386Idt /* Base Address */
|
||||||
|
END
|
|
@ -43,12 +43,6 @@ UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PCONFIGURATION_COMPONENT_DATA
|
|
||||||
UefiHwDetect(VOID)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
UefiPcBeep(VOID)
|
UefiPcBeep(VOID)
|
||||||
{
|
{
|
||||||
|
|
|
@ -138,6 +138,5 @@ UefiConsGetCh(VOID)
|
||||||
/* UEFI will stack input requests, we have to clear it */
|
/* UEFI will stack input requests, we have to clear it */
|
||||||
Key.UnicodeChar = 0;
|
Key.UnicodeChar = 0;
|
||||||
Key.ScanCode = 0;
|
Key.ScanCode = 0;
|
||||||
GlobalSystemTable->ConIn->Reset(GlobalSystemTable->ConIn, FALSE);
|
|
||||||
return KeyOutput;
|
return KeyOutput;
|
||||||
}
|
}
|
||||||
|
|
149
boot/freeldr/freeldr/arch/uefi/uefihw.c
Normal file
149
boot/freeldr/freeldr/arch/uefi/uefihw.c
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: FreeLoader UEFI Support
|
||||||
|
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||||
|
* PURPOSE: Hardware detection routines
|
||||||
|
* COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <uefildr.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
DBG_DEFAULT_CHANNEL(WARNING);
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
extern EFI_SYSTEM_TABLE * GlobalSystemTable;
|
||||||
|
extern EFI_HANDLE GlobalImageHandle;
|
||||||
|
extern UCHAR PcBiosDiskCount;
|
||||||
|
extern EFI_MEMORY_DESCRIPTOR* EfiMemoryMap;
|
||||||
|
extern UINT32 FreeldrDescCount;
|
||||||
|
|
||||||
|
BOOLEAN AcpiPresent = FALSE;
|
||||||
|
|
||||||
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
static
|
||||||
|
PRSDP_DESCRIPTOR
|
||||||
|
FindAcpiBios(VOID)
|
||||||
|
{
|
||||||
|
UINTN i;
|
||||||
|
RSDP_DESCRIPTOR* rsdp = NULL;
|
||||||
|
EFI_GUID acpi2_guid = EFI_ACPI_20_TABLE_GUID;
|
||||||
|
|
||||||
|
for (i = 0; i < GlobalSystemTable->NumberOfTableEntries; i++)
|
||||||
|
{
|
||||||
|
if (!memcmp(&GlobalSystemTable->ConfigurationTable[i].VendorGuid,
|
||||||
|
&acpi2_guid, sizeof(acpi2_guid)))
|
||||||
|
{
|
||||||
|
rsdp = (RSDP_DESCRIPTOR*)GlobalSystemTable->ConfigurationTable[i].VendorTable;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rsdp;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
|
||||||
|
{
|
||||||
|
PCONFIGURATION_COMPONENT_DATA BiosKey;
|
||||||
|
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
|
||||||
|
PRSDP_DESCRIPTOR Rsdp;
|
||||||
|
PACPI_BIOS_DATA AcpiBiosData;
|
||||||
|
ULONG TableSize;
|
||||||
|
|
||||||
|
Rsdp = FindAcpiBios();
|
||||||
|
|
||||||
|
if (Rsdp)
|
||||||
|
{
|
||||||
|
/* Set up the flag in the loader block */
|
||||||
|
AcpiPresent = TRUE;
|
||||||
|
|
||||||
|
/* Calculate the table size */
|
||||||
|
TableSize = FreeldrDescCount * sizeof(BIOS_MEMORY_MAP) +
|
||||||
|
sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP);
|
||||||
|
|
||||||
|
/* Set 'Configuration Data' value */
|
||||||
|
PartialResourceList = FrLdrHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) +
|
||||||
|
TableSize, TAG_HW_RESOURCE_LIST);
|
||||||
|
if (PartialResourceList == NULL)
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate resource descriptor\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(PartialResourceList, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
|
||||||
|
PartialResourceList->Version = 0;
|
||||||
|
PartialResourceList->Revision = 0;
|
||||||
|
PartialResourceList->Count = 1;
|
||||||
|
|
||||||
|
PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
|
||||||
|
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
|
||||||
|
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
|
||||||
|
PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize;
|
||||||
|
|
||||||
|
/* Fill the table */
|
||||||
|
AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
|
||||||
|
|
||||||
|
if (Rsdp->revision > 0)
|
||||||
|
{
|
||||||
|
TRACE("ACPI >1.0, using XSDT address\n");
|
||||||
|
AcpiBiosData->RSDTAddress.QuadPart = Rsdp->xsdt_physical_address;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE("ACPI 1.0, using RSDT address\n");
|
||||||
|
AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcpiBiosData->Count = FreeldrDescCount;
|
||||||
|
memcpy(AcpiBiosData->MemoryMap, EfiMemoryMap,
|
||||||
|
FreeldrDescCount * sizeof(BIOS_MEMORY_MAP));
|
||||||
|
|
||||||
|
TRACE("RSDT %p, data size %x\n", Rsdp->rsdt_physical_address, TableSize);
|
||||||
|
|
||||||
|
/* Create new bus key */
|
||||||
|
FldrCreateComponentKey(SystemKey,
|
||||||
|
AdapterClass,
|
||||||
|
MultiFunctionAdapter,
|
||||||
|
0x0,
|
||||||
|
0x0,
|
||||||
|
0xFFFFFFFF,
|
||||||
|
"ACPI BIOS",
|
||||||
|
PartialResourceList,
|
||||||
|
sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize,
|
||||||
|
&BiosKey);
|
||||||
|
|
||||||
|
/* Increment bus number */
|
||||||
|
(*BusNumber)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PCONFIGURATION_COMPONENT_DATA
|
||||||
|
UefiHwDetect(VOID)
|
||||||
|
{
|
||||||
|
PCONFIGURATION_COMPONENT_DATA SystemKey;
|
||||||
|
ULONG BusNumber = 0;
|
||||||
|
|
||||||
|
TRACE("DetectHardware()\n");
|
||||||
|
|
||||||
|
/* Create the 'System' key */
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
FldrCreateSystemKey(&SystemKey, "AT/AT COMPATIBLE");
|
||||||
|
#elif defined(_M_IA64)
|
||||||
|
FldrCreateSystemKey(&SystemKey, "Intel Itanium processor family");
|
||||||
|
#elif defined(_M_ARM) || defined(_M_ARM64)
|
||||||
|
FldrCreateSystemKey(&SystemKey, "ARM processor family");
|
||||||
|
#else
|
||||||
|
#error Please define a system key for your architecture
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Detect ACPI */
|
||||||
|
DetectAcpiBios(SystemKey, &BusNumber);
|
||||||
|
|
||||||
|
TRACE("DetectHardware() Done\n");
|
||||||
|
return SystemKey;
|
||||||
|
}
|
|
@ -8,11 +8,16 @@
|
||||||
#include <uefildr.h>
|
#include <uefildr.h>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
DBG_DEFAULT_CHANNEL(WARNING);
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
EFI_HANDLE GlobalImageHandle;
|
EFI_HANDLE GlobalImageHandle;
|
||||||
EFI_SYSTEM_TABLE *GlobalSystemTable;
|
EFI_SYSTEM_TABLE *GlobalSystemTable;
|
||||||
|
PVOID UefiServiceStack;
|
||||||
|
PVOID BasicStack;
|
||||||
|
|
||||||
|
void _changestack(VOID);
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
@ -25,15 +30,61 @@ EfiEntry(
|
||||||
GlobalImageHandle = ImageHandle;
|
GlobalImageHandle = ImageHandle;
|
||||||
GlobalSystemTable = SystemTable;
|
GlobalSystemTable = SystemTable;
|
||||||
|
|
||||||
BootMain(NULL);
|
/* Needed for default settings */
|
||||||
|
CmdLineParse("");
|
||||||
|
|
||||||
|
/* Debugger pre-initialization */
|
||||||
|
DebugInit(0);
|
||||||
|
|
||||||
|
MachInit("");
|
||||||
|
|
||||||
|
/* UI pre-initialization */
|
||||||
|
if (!UiInitialize(FALSE))
|
||||||
|
{
|
||||||
|
UiMessageBoxCritical("Unable to initialize UI.");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize memory manager */
|
||||||
|
if (!MmInitializeMemoryManager())
|
||||||
|
{
|
||||||
|
UiMessageBoxCritical("Unable to initialize memory manager.");
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize I/O subsystem */
|
||||||
|
FsInit();
|
||||||
|
|
||||||
|
/* 0x32000 is what UEFI defines, but we can go smaller if we want */
|
||||||
|
BasicStack = (PVOID)((ULONG_PTR)0x32000 + (ULONG_PTR)MmAllocateMemoryWithType(0x32000, LoaderOsloaderStack));
|
||||||
|
_changestack();
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
/* If we reach this point, something went wrong before, therefore reboot */
|
||||||
|
Reboot();
|
||||||
|
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ExecuteLoaderCleanly(PVOID PreviousStack)
|
||||||
|
{
|
||||||
|
TRACE("ExecuteLoaderCleanly Entry\n");
|
||||||
|
UefiServiceStack = PreviousStack;
|
||||||
|
|
||||||
|
RunLoader();
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _M_ARM
|
#ifndef _M_ARM
|
||||||
VOID __cdecl Reboot(VOID)
|
VOID __cdecl Reboot(VOID)
|
||||||
{
|
{
|
||||||
|
//TODO: Replace with a true firmware reboot eventually
|
||||||
|
WARN("Something has gone wrong - halting FreeLoader\n");
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
NOTHING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@ AddMemoryDescriptor(
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
extern ULONG LoaderPagesSpanned;
|
||||||
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
|
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
|
||||||
extern EFI_HANDLE GlobalImageHandle;
|
extern EFI_HANDLE GlobalImageHandle;
|
||||||
extern REACTOS_INTERNAL_BGCONTEXT framebufferData;
|
extern REACTOS_INTERNAL_BGCONTEXT framebufferData;
|
||||||
|
@ -39,6 +40,8 @@ EFI_HANDLE PublicBootHandle;
|
||||||
PVOID ExitStack;
|
PVOID ExitStack;
|
||||||
PVOID EndofExitStack;
|
PVOID EndofExitStack;
|
||||||
|
|
||||||
|
void _exituefi(VOID);
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -85,56 +88,13 @@ VOID
|
||||||
UefiSetMemory(
|
UefiSetMemory(
|
||||||
_Inout_ PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
|
_Inout_ PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
|
||||||
_In_ ULONG_PTR BaseAddress,
|
_In_ ULONG_PTR BaseAddress,
|
||||||
_In_ PFN_COUNT Size,
|
_In_ PFN_COUNT SizeInPages,
|
||||||
_In_ TYPE_OF_MEMORY MemoryType)
|
_In_ TYPE_OF_MEMORY MemoryType)
|
||||||
{
|
{
|
||||||
ULONG_PTR BasePage, PageCount;
|
ULONG_PTR BasePage, PageCount;
|
||||||
|
|
||||||
BasePage = BaseAddress / EFI_PAGE_SIZE;
|
BasePage = BaseAddress / EFI_PAGE_SIZE;
|
||||||
PageCount = Size;
|
PageCount = SizeInPages;
|
||||||
|
|
||||||
/* Add the memory descriptor */
|
|
||||||
FreeldrDescCount = AddMemoryDescriptor(MemoryMap,
|
|
||||||
UNUSED_MAX_DESCRIPTOR_COUNT,
|
|
||||||
BasePage,
|
|
||||||
PageCount,
|
|
||||||
MemoryType);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
ReserveMemory(
|
|
||||||
_Inout_ PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
|
|
||||||
_In_ ULONG_PTR BaseAddress,
|
|
||||||
_In_ PFN_NUMBER Size,
|
|
||||||
_In_ TYPE_OF_MEMORY MemoryType,
|
|
||||||
_In_ PCHAR Usage)
|
|
||||||
{
|
|
||||||
ULONG_PTR BasePage, PageCount;
|
|
||||||
ULONG i;
|
|
||||||
|
|
||||||
BasePage = BaseAddress / PAGE_SIZE;
|
|
||||||
PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
|
|
||||||
|
|
||||||
for (i = 0; i < FreeldrDescCount; i++)
|
|
||||||
{
|
|
||||||
/* Check for conflicting descriptor */
|
|
||||||
if ((MemoryMap[i].BasePage < BasePage + PageCount) &&
|
|
||||||
(MemoryMap[i].BasePage + MemoryMap[i].PageCount > BasePage))
|
|
||||||
{
|
|
||||||
/* Check if the memory is free */
|
|
||||||
if (MemoryMap[i].MemoryType != LoaderFree)
|
|
||||||
{
|
|
||||||
FrLdrBugCheckWithMessage(
|
|
||||||
MEMORY_INIT_FAILURE,
|
|
||||||
__FILE__,
|
|
||||||
__LINE__,
|
|
||||||
"Failed to reserve memory in the range 0x%Ix - 0x%Ix for %s",
|
|
||||||
BaseAddress,
|
|
||||||
Size,
|
|
||||||
Usage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the memory descriptor */
|
/* Add the memory descriptor */
|
||||||
FreeldrDescCount = AddMemoryDescriptor(MemoryMap,
|
FreeldrDescCount = AddMemoryDescriptor(MemoryMap,
|
||||||
|
@ -256,19 +216,36 @@ UefiMemGetMemoryMap(ULONG *MemoryMapSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UefiSetMemory(FreeldrMem,
|
/* Sometimes our loader can be loaded into higher memory than we ever allocate */
|
||||||
MapEntry->PhysicalStart,
|
if (MemoryType == LoaderLoadedProgram)
|
||||||
MapEntry->NumberOfPages,
|
{
|
||||||
MemoryType);
|
if (((MapEntry->PhysicalStart + (MapEntry->NumberOfPages * PAGE_SIZE)) >> EFI_PAGE_SHIFT) > LoaderPagesSpanned)
|
||||||
|
{
|
||||||
|
/* This value needs to be adjusted if this occurs */
|
||||||
|
LoaderPagesSpanned = ((MapEntry->PhysicalStart + (MapEntry->NumberOfPages * PAGE_SIZE)) >> EFI_PAGE_SHIFT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We really don't want to touch these reserved spots at all */
|
||||||
|
if (MemoryType != LoaderReserve)
|
||||||
|
{
|
||||||
|
UefiSetMemory(FreeldrMem,
|
||||||
|
MapEntry->PhysicalStart,
|
||||||
|
MapEntry->NumberOfPages,
|
||||||
|
MemoryType);
|
||||||
|
}
|
||||||
|
|
||||||
MapEntry = NEXT_MEMORY_DESCRIPTOR(MapEntry, DescriptorSize);
|
MapEntry = NEXT_MEMORY_DESCRIPTOR(MapEntry, DescriptorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Windows expects the first page to be reserved, otherwise it asserts.
|
||||||
|
* However it can be just a free page on some UEFI systems. */
|
||||||
|
UefiSetMemory(FreeldrMem, 0x000000, 1, LoaderFirmwarePermanent);
|
||||||
*MemoryMapSize = FreeldrDescCount;
|
*MemoryMapSize = FreeldrDescCount;
|
||||||
return FreeldrMem;
|
return FreeldrMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID
|
VOID
|
||||||
UefiExitBootServices(VOID)
|
UefiExitBootServices(VOID)
|
||||||
{
|
{
|
||||||
UINTN MapKey;
|
UINTN MapKey;
|
||||||
|
@ -306,7 +283,5 @@ UefiExitBootServices(VOID)
|
||||||
VOID
|
VOID
|
||||||
UefiPrepareForReactOS(VOID)
|
UefiPrepareForReactOS(VOID)
|
||||||
{
|
{
|
||||||
UefiExitBootServices();
|
_exituefi();
|
||||||
ExitStack = MmAllocateMemoryWithType(EXIT_STACK_SIZE, LoaderOsloaderStack);
|
|
||||||
EndofExitStack = (PVOID)((ULONG_PTR)ExitStack + EXIT_STACK_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ DBG_DEFAULT_CHANNEL(WARNING);
|
||||||
|
|
||||||
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
|
extern EFI_SYSTEM_TABLE* GlobalSystemTable;
|
||||||
extern EFI_HANDLE GlobalImageHandle;
|
extern EFI_HANDLE GlobalImageHandle;
|
||||||
BOOLEAN AcpiPresent = FALSE;
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ list(APPEND UEFILDR_ARC_SOURCE
|
||||||
arch/uefi/stubs.c
|
arch/uefi/stubs.c
|
||||||
arch/uefi/ueficon.c
|
arch/uefi/ueficon.c
|
||||||
arch/uefi/uefidisk.c
|
arch/uefi/uefidisk.c
|
||||||
|
arch/uefi/uefihw.c
|
||||||
arch/uefi/uefimem.c
|
arch/uefi/uefimem.c
|
||||||
arch/uefi/uefisetup.c
|
arch/uefi/uefisetup.c
|
||||||
arch/uefi/uefiutil.c
|
arch/uefi/uefiutil.c
|
||||||
|
@ -23,11 +24,14 @@ list(APPEND UEFILDR_ARC_SOURCE
|
||||||
arch/vgafont.c)
|
arch/vgafont.c)
|
||||||
|
|
||||||
if(ARCH STREQUAL "i386")
|
if(ARCH STREQUAL "i386")
|
||||||
|
list(APPEND UEFILDR_ARC_SOURCE
|
||||||
|
arch/i386/i386idt.c)
|
||||||
list(APPEND UEFILDR_COMMON_ASM_SOURCE
|
list(APPEND UEFILDR_COMMON_ASM_SOURCE
|
||||||
|
arch/uefi/i386/uefiasm.S
|
||||||
arch/i386/i386trap.S)
|
arch/i386/i386trap.S)
|
||||||
|
|
||||||
elseif(ARCH STREQUAL "amd64")
|
elseif(ARCH STREQUAL "amd64")
|
||||||
#TBD
|
list(APPEND UEFILDR_COMMON_ASM_SOURCE
|
||||||
|
arch/uefi/amd64/uefiasm.S)
|
||||||
elseif(ARCH STREQUAL "arm")
|
elseif(ARCH STREQUAL "arm")
|
||||||
list(APPEND UEFILDR_ARC_SOURCE
|
list(APPEND UEFILDR_ARC_SOURCE
|
||||||
arch/arm/macharm.c
|
arch/arm/macharm.c
|
||||||
|
@ -88,6 +92,11 @@ set_target_properties(uefildr PROPERTIES SUFFIX ".efi")
|
||||||
|
|
||||||
target_compile_definitions(uefildr PRIVATE UEFIBOOT)
|
target_compile_definitions(uefildr PRIVATE UEFIBOOT)
|
||||||
|
|
||||||
|
# On AMD64 we only map 1GB with freeloader, tell UEFI to keep us low!
|
||||||
|
if(ARCH STREQUAL "amd64")
|
||||||
|
set_image_base(uefildr 0x10000)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
if(NOT ARCH STREQUAL "arm")
|
if(NOT ARCH STREQUAL "arm")
|
||||||
target_link_options(uefildr PRIVATE /DYNAMICBASE:NO)
|
target_link_options(uefildr PRIVATE /DYNAMICBASE:NO)
|
||||||
|
|
Loading…
Reference in a new issue