C to C++ migration and refactoring #17
@@ -8,8 +8,9 @@ include_directories(
|
|||||||
|
|
||||||
# Specify list of source code files
|
# Specify list of source code files
|
||||||
list(APPEND XTLDR_XTOS_O_SOURCE
|
list(APPEND XTLDR_XTOS_O_SOURCE
|
||||||
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c
|
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.cc
|
||||||
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c)
|
${XTLDR_XTOS_O_SOURCE_DIR}/data.cc
|
||||||
|
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.cc)
|
||||||
|
|
||||||
# Link bootloader executable
|
# Link bootloader executable
|
||||||
add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})
|
add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtldr/amd64/memory.c
|
* FILE: xtldr/amd64/memory.cc
|
||||||
* DESCRIPTION: EFI memory management for AMD64 target
|
* DESCRIPTION: EFI memory management for AMD64 target
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.h>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
ULONG
|
ULONG
|
||||||
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
|
||||||
{
|
{
|
||||||
CPUID_REGISTERS CpuRegisters;
|
CPUID_REGISTERS CpuRegisters;
|
||||||
|
|
||||||
@@ -56,6 +56,99 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
||||||
|
*
|
||||||
|
* @param PageMap
|
||||||
|
* Supplies a pointer to the page mapping structure.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_PHYSICAL_ADDRESS TrampolineAddress;
|
||||||
|
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
|
||||||
|
ULONG_PTR TrampolineSize;
|
||||||
|
|
||||||
|
/* Build page map */
|
||||||
|
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to build page map */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map memory for hardware layer */
|
||||||
|
Status = MapHardwareMemoryPool(PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to map memory for hardware layer */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configured page map level to set the LA57 state accordingly */
|
||||||
|
if(PageMap->PageMapLevel == 5)
|
||||||
|
{
|
||||||
|
/* Set the address of the trampoline code below 1MB */
|
||||||
|
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
|
||||||
|
|
||||||
|
/* Calculate the size of the trampoline code */
|
||||||
|
TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
|
||||||
|
|
||||||
|
/* Allocate pages for the trampoline */
|
||||||
|
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to allocate memory for trampoline code */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the trampoline entry point and copy its code into the allocated buffer */
|
||||||
|
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
|
||||||
|
RtlCopyMemory((PVOID)TrampolineEntry, (PVOID)ArEnableExtendedPhysicalAddressing, TrampolineSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit EFI Boot Services */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||||
|
Status = XtLdrProtocol->Util.ExitBootServices();
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to exit boot services */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
||||||
|
return STATUS_EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the configured page map level to set the LA57 state accordingly */
|
||||||
|
if(PageMap->PageMapLevel == 5)
|
||||||
|
{
|
||||||
|
/* Enable Linear Address 57-bit (LA57) extension */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
|
||||||
|
|
||||||
|
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
|
||||||
|
TrampolineEntry((UINT64)PageMap->PtePointer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable Linear Address 57-bit (LA57) extension */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
|
||||||
|
|
||||||
|
/* Write PML4 to CR3 and enable paging */
|
||||||
|
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
||||||
|
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps the page table for hardware layer addess space.
|
* Maps the page table for hardware layer addess space.
|
||||||
*
|
*
|
||||||
@@ -68,7 +161,7 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
{
|
{
|
||||||
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
PHARDWARE_PTE P5eBase, PdeBase, PpeBase, PxeBase;
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
@@ -196,96 +289,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
|
||||||
*
|
|
||||||
* @param PageMap
|
|
||||||
* Supplies a pointer to the page mapping structure.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
EFI_PHYSICAL_ADDRESS TrampolineAddress;
|
|
||||||
PXT_TRAMPOLINE_ENTRY TrampolineEntry;
|
|
||||||
ULONG_PTR TrampolineSize;
|
|
||||||
|
|
||||||
/* Build page map */
|
|
||||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, (PageMap->PageMapLevel > 4) ? MM_P5E_LA57_BASE : MM_PXE_BASE);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to build page map */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map memory for hardware layer */
|
|
||||||
Status = XtpMapHardwareMemoryPool(PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map memory for hardware layer */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware leyer (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the configured page map level to set the LA57 state accordingly */
|
|
||||||
if(PageMap->PageMapLevel == 5)
|
|
||||||
{
|
|
||||||
/* Set the address of the trampoline code below 1MB */
|
|
||||||
TrampolineAddress = MM_TRAMPOLINE_ADDRESS;
|
|
||||||
|
|
||||||
/* Calculate the size of the trampoline code */
|
|
||||||
TrampolineSize = (ULONG_PTR)ArEnableExtendedPhysicalAddressingEnd - (ULONG_PTR)ArEnableExtendedPhysicalAddressing;
|
|
||||||
|
|
||||||
/* Allocate pages for the trampoline */
|
|
||||||
Status = XtLdrProtocol->Memory.AllocatePages(AllocateAddress, EFI_SIZE_TO_PAGES(TrampolineSize), &TrampolineAddress);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to allocate memory for trampoline code */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to allocate memory for trampoline code (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the trampoline entry point and copy its code into the allocated buffer */
|
|
||||||
TrampolineEntry = (PXT_TRAMPOLINE_ENTRY)(UINT_PTR)TrampolineAddress;
|
|
||||||
RtlCopyMemory(TrampolineEntry, ArEnableExtendedPhysicalAddressing, TrampolineSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Exit EFI Boot Services */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
|
||||||
Status = XtLdrProtocol->Util.ExitBootServices();
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to exit boot services */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
|
||||||
return STATUS_EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the configured page map level to set the LA57 state accordingly */
|
|
||||||
if(PageMap->PageMapLevel == 5)
|
|
||||||
{
|
|
||||||
/* Enable Linear Address 57-bit (LA57) extension */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Enabling Linear Address 57-bit (LA57)\n");
|
|
||||||
|
|
||||||
/* Execute the trampoline to enable LA57 and write PML5 to CR3 */
|
|
||||||
TrampolineEntry((UINT64)PageMap->PtePointer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Disable Linear Address 57-bit (LA57) extension */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Disabling Linear Address 57-bit (LA57)\n");
|
|
||||||
|
|
||||||
/* Write PML4 to CR3 and enable paging */
|
|
||||||
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
|
||||||
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
19
xtldr/modules/xtos_o/data.cc
Normal file
19
xtldr/modules/xtos_o/data.cc
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/xtos/data.cc
|
||||||
|
* DESCRIPTION: XTOS module global and static data
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* XTOS Boot Protocol */
|
||||||
|
XTBL_BOOT_PROTOCOL Xtos::BootProtocol;
|
||||||
|
|
||||||
|
/* XTOS PE/COFF Image Protocol */
|
||||||
|
PXTBL_EXECUTABLE_IMAGE_PROTOCOL Xtos::PeCoffProtocol;
|
||||||
|
|
||||||
|
/* EFI XT Loader Protocol */
|
||||||
|
PXTBL_LOADER_PROTOCOL Xtos::XtLdrProtocol;
|
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtldr/i686/memory.c
|
* FILE: xtldr/i686/memory.cc
|
||||||
* DESCRIPTION: EFI memory management for i686 target
|
* DESCRIPTION: EFI memory management for i686 target
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.h>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
ULONG
|
ULONG
|
||||||
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
Xtos::DeterminePagingLevel(IN CONST PWCHAR Parameters)
|
||||||
{
|
{
|
||||||
CPUID_REGISTERS CpuRegisters;
|
CPUID_REGISTERS CpuRegisters;
|
||||||
|
|
||||||
@@ -44,6 +44,77 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
||||||
|
*
|
||||||
|
* @param PageMap
|
||||||
|
* Supplies a pointer to the page mapping structure.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::EnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Build page map */
|
||||||
|
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to build page map */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map memory for hardware layer */
|
||||||
|
Status = MapHardwareMemoryPool(PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to map memory for hardware layer */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit EFI Boot Services */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||||
|
Status = XtLdrProtocol->Util.ExitBootServices();
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to exit boot services */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
||||||
|
return STATUS_EFI_ABORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable paging */
|
||||||
|
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_PG);
|
||||||
|
|
||||||
|
/* Check the configured page map level to set the PAE state accordingly */
|
||||||
|
if(PageMap->PageMapLevel == 3)
|
||||||
|
{
|
||||||
|
/* Enable Physical Address Extension (PAE) */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
|
||||||
|
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Disable Physical Address Extension (PAE) */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Disabling Physical Address Extension (PAE)\n");
|
||||||
|
ArWriteControlRegister(4, ArReadControlRegister(4) & ~CR4_PAE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write page mappings to CR3 */
|
||||||
|
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
||||||
|
|
||||||
|
/* Enable paging */
|
||||||
|
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps the page table for hardware layer addess space.
|
* Maps the page table for hardware layer addess space.
|
||||||
*
|
*
|
||||||
@@ -56,7 +127,7 @@ XtpDeterminePagingLevel(IN CONST PWCHAR Parameters)
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
Xtos::MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
{
|
{
|
||||||
EFI_PHYSICAL_ADDRESS Address;
|
EFI_PHYSICAL_ADDRESS Address;
|
||||||
PHARDWARE_LEGACY_PTE LegacyPdeBase;
|
PHARDWARE_LEGACY_PTE LegacyPdeBase;
|
||||||
@@ -108,74 +179,3 @@ XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
|
|
||||||
*
|
|
||||||
* @param PageMap
|
|
||||||
* Supplies a pointer to the page mapping structure.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Build page map */
|
|
||||||
Status = XtLdrProtocol->Memory.BuildPageMap(PageMap, MM_PTE_BASE);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to build page map */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to build page map (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Map memory for hardware layer */
|
|
||||||
Status = XtpMapHardwareMemoryPool(PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to map memory for hardware layer */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to map memory for hardware layer (Status code: %zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Exit EFI Boot Services */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
|
||||||
Status = XtLdrProtocol->Util.ExitBootServices();
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to exit boot services */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %zX)\n", Status);
|
|
||||||
return STATUS_EFI_ABORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable paging */
|
|
||||||
ArWriteControlRegister(0, ArReadControlRegister(0) & ~CR0_PG);
|
|
||||||
|
|
||||||
/* Check the configured page map level to set the PAE state accordingly */
|
|
||||||
if(PageMap->PageMapLevel == 3)
|
|
||||||
{
|
|
||||||
/* Enable Physical Address Extension (PAE) */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Enabling Physical Address Extension (PAE)\n");
|
|
||||||
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Disable Physical Address Extension (PAE) */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Disabling Physical Address Extension (PAE)\n");
|
|
||||||
ArWriteControlRegister(4, ArReadControlRegister(4) & ~CR4_PAE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write page mappings to CR3 */
|
|
||||||
ArWriteControlRegister(3, (UINT_PTR)PageMap->PtePointer);
|
|
||||||
|
|
||||||
/* Enable paging */
|
|
||||||
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
@@ -1,118 +0,0 @@
|
|||||||
/**
|
|
||||||
* PROJECT: ExectOS
|
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
|
||||||
* FILE: xtldr/modules/xtos/includes/xtos.h
|
|
||||||
* DESCRIPTION: XTOS boot protocol support header
|
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __XTLDR_MODULES_XTOS_H
|
|
||||||
#define __XTLDR_MODULES_XTOS_H
|
|
||||||
|
|
||||||
#include <xtblapi.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER)(OUT PWCHAR DriverName);
|
|
||||||
typedef VOID (*PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION)(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock);
|
|
||||||
typedef EFI_STATUS (*PXT_FRAMEBUFFER_INITIALIZE)();
|
|
||||||
typedef VOID (*PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION)();
|
|
||||||
|
|
||||||
/* XT framebuffer support protocol */
|
|
||||||
typedef struct _XT_FRAMEBUFFER_PROTOCOL
|
|
||||||
{
|
|
||||||
PXT_FRAMEBUFFER_GET_DISPLAY_DRIVER GetDisplayDriver;
|
|
||||||
PXT_FRAMEBUFFER_GET_DISPLAY_INFORMATION GetDisplayInformation;
|
|
||||||
PXT_FRAMEBUFFER_INITIALIZE Initialize;
|
|
||||||
PXT_FRAMEBUFFER_PRINT_DISPLAY_INFORMATION PrintDisplayInformation;
|
|
||||||
} XT_FRAMEBUFFER_PROTOCOL, *PXT_FRAMEBUFFER_PROTOCOL;
|
|
||||||
|
|
||||||
/* EFI XT Loader Protocol */
|
|
||||||
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
|
||||||
|
|
||||||
/* XTOS trampoline end address to calculate trampoline size */
|
|
||||||
EXTERN PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
|
||||||
|
|
||||||
/* XTOS kernel entry point */
|
|
||||||
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
|
|
||||||
|
|
||||||
/* XTOS trampoline entry point */
|
|
||||||
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
|
|
||||||
|
|
||||||
/* XTOS boot protocol related routines forward references */
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
|
|
||||||
IN PVOID VirtualAddress,
|
|
||||||
IN PVOID PhysicalAddress,
|
|
||||||
IN UINT NumberOfPages,
|
|
||||||
IN LOADER_MEMORY_TYPE MemoryType);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
LOADER_MEMORY_TYPE
|
|
||||||
XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
ULONG
|
|
||||||
XtpDeterminePagingLevel(IN CONST PWCHAR Parameters);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtEnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtGetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
|
||||||
IN PVOID PhysicalAddress,
|
|
||||||
OUT PVOID *VirtualAddress);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
|
|
||||||
IN OUT PVOID *MemoryMapAddress);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
|
||||||
IN UINT_PTR VirtualAddress,
|
|
||||||
IN UINT_PTR PhysicalAddress,
|
|
||||||
IN UINT NumberOfPages,
|
|
||||||
IN OUT PVOID *PtePointer);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters);
|
|
||||||
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|
||||||
IN PVOID *VirtualAddress,
|
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpLoadModule(IN PEFI_FILE_HANDLE BootDir,
|
|
||||||
IN PWCHAR FileName,
|
|
||||||
IN PVOID VirtualAddress,
|
|
||||||
IN LOADER_MEMORY_TYPE MemoryType,
|
|
||||||
OUT PPECOFF_IMAGE_CONTEXT *ImageContext);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpMapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);
|
|
||||||
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
|
||||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
|
||||||
|
|
||||||
#endif /* __XTLDR_MODULES_XTOS_H */
|
|
81
xtldr/modules/xtos_o/includes/xtos.hh
Normal file
81
xtldr/modules/xtos_o/includes/xtos.hh
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: ExectOS
|
||||||
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
|
* FILE: xtldr/modules/xtos/includes/xtos.hh
|
||||||
|
* DESCRIPTION: XTOS boot protocol support header
|
||||||
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTLDR_MODULES_XTOS_HH
|
||||||
|
#define __XTLDR_MODULES_XTOS_HH
|
||||||
|
|
||||||
|
#include <xtblapi.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* XTOS kernel entry point */
|
||||||
|
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
|
||||||
|
|
||||||
|
/* XTOS trampoline entry point */
|
||||||
|
typedef VOID (*PXT_TRAMPOLINE_ENTRY)(UINT64 PageMap);
|
||||||
|
|
||||||
|
/* XTOS trampoline end address to calculate trampoline size */
|
||||||
|
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
|
||||||
|
|
||||||
|
|
||||||
|
/* XTOS module for XTLDR */
|
||||||
|
class Xtos
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
STATIC XTBL_BOOT_PROTOCOL BootProtocol;
|
||||||
|
STATIC PXTBL_EXECUTABLE_IMAGE_PROTOCOL PeCoffProtocol;
|
||||||
|
STATIC PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
||||||
|
|
||||||
|
public:
|
||||||
|
STATIC XTCDECL EFI_STATUS BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
STATIC XTCDECL EFI_STATUS InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
STATIC XTCDECL EFI_STATUS AddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN PVOID PhysicalAddress,
|
||||||
|
IN UINT NumberOfPages,
|
||||||
|
IN LOADER_MEMORY_TYPE MemoryType);
|
||||||
|
STATIC XTCDECL LOADER_MEMORY_TYPE ConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||||
|
STATIC XTCDECL ULONG DeterminePagingLevel(IN CONST PWCHAR Parameters);
|
||||||
|
STATIC XTCDECL EFI_STATUS EnablePaging(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
|
STATIC XTCDECL VOID GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||||
|
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
||||||
|
IN PULONG_PTR FrameBufferSize,
|
||||||
|
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo);
|
||||||
|
STATIC XTCDECL EFI_STATUS GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
|
IN PVOID *VirtualAddress,
|
||||||
|
OUT PLIST_ENTRY MemoryDescriptorList);
|
||||||
|
STATIC XTCDECL EFI_STATUS GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
|
IN PVOID *VirtualAddress,
|
||||||
|
OUT PLIST_ENTRY SystemResourcesList);
|
||||||
|
STATIC XTCDECL EFI_STATUS GetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||||
|
IN PVOID PhysicalAddress,
|
||||||
|
OUT PVOID *VirtualAddress);
|
||||||
|
STATIC XTCDECL EFI_STATUS InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
|
STATIC XTCDECL EFI_STATUS InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
|
IN PVOID *VirtualAddress,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
STATIC XTCDECL EFI_STATUS InitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
|
||||||
|
IN OUT PVOID *MemoryMapAddress);
|
||||||
|
STATIC XTCDECL EFI_STATUS LoadModule(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PWCHAR FileName,
|
||||||
|
IN PVOID VirtualAddress,
|
||||||
|
IN LOADER_MEMORY_TYPE MemoryType,
|
||||||
|
OUT PPECOFF_IMAGE_CONTEXT *ImageContext);
|
||||||
|
STATIC XTCDECL EFI_STATUS MapHardwareMemoryPool(IN PXTBL_PAGE_MAPPING PageMap);
|
||||||
|
STATIC XTCDECL EFI_STATUS MapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||||
|
IN UINT_PTR VirtualAddress,
|
||||||
|
IN UINT_PTR PhysicalAddress,
|
||||||
|
IN UINT NumberOfPages,
|
||||||
|
IN OUT PVOID *PtePointer);
|
||||||
|
STATIC XTCDECL EFI_STATUS RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __XTLDR_MODULES_XTOS_HH */
|
@@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtldr/modules/xtos/xtos.c
|
* FILE: xtldr/modules/xtos/xtos.cc
|
||||||
* DESCRIPTION: XTOS boot protocol support
|
* DESCRIPTION: XTOS boot protocol support
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <xtos.h>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
/* XTOS module information */
|
/* XTOS module information */
|
||||||
@@ -16,14 +16,139 @@ MODULE_DEPENDENCY(L"acpi framebuf pecoff");
|
|||||||
MODULE_LICENSE(L"GPLv3");
|
MODULE_LICENSE(L"GPLv3");
|
||||||
MODULE_VERSION(L"0.1");
|
MODULE_VERSION(L"0.1");
|
||||||
|
|
||||||
/* EFI XT Loader Protocol */
|
|
||||||
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
|
|
||||||
|
|
||||||
/* XTOS PE/COFF Image Protocol */
|
/**
|
||||||
PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol;
|
* Starts the operating system according to the provided parameters using XTOS boot protocol.
|
||||||
|
*
|
||||||
|
* @param Parameters
|
||||||
|
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::BootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
|
{
|
||||||
|
EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
|
||||||
|
EFI_HANDLE DiskHandle, ProtocolHandle;
|
||||||
|
PEFI_FILE_HANDLE FsHandle, BootDir;
|
||||||
|
PWCHAR SystemPath;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
/* XTOS Boot Protocol */
|
/* Print debug message */
|
||||||
XTBL_BOOT_PROTOCOL XtBootProtocol;
|
XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n");
|
||||||
|
|
||||||
|
/* Open the XT PE/COFF protocol */
|
||||||
|
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&PeCoffProtocol, &PeCoffProtocolGuid);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open loader protocol */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n");
|
||||||
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check device path */
|
||||||
|
if(Parameters->DevicePath == NULLPTR)
|
||||||
|
{
|
||||||
|
/* No device path set */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if system path is set */
|
||||||
|
if(Parameters->SystemPath != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Make sure system path begins with backslash, the only separator supported by EFI */
|
||||||
|
if(Parameters->SystemPath[0] == '/')
|
||||||
|
{
|
||||||
|
/* Replace directory separator if needed */
|
||||||
|
Parameters->SystemPath[0] = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate system path */
|
||||||
|
SystemPath = &Parameters->SystemPath[1];
|
||||||
|
while(*SystemPath)
|
||||||
|
{
|
||||||
|
/* Make sure it does not point to any subdirectory and not contains special characters */
|
||||||
|
if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))
|
||||||
|
{
|
||||||
|
/* Invalid path specified */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n");
|
||||||
|
return STATUS_EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
/* Check next character in the path */
|
||||||
|
SystemPath++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fallback to '/ExectOS' by default */
|
||||||
|
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
|
||||||
|
Parameters->SystemPath = (PWCHAR)L"\\ExectOS";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if kernel file is set */
|
||||||
|
if(Parameters->KernelFile == NULLPTR)
|
||||||
|
{
|
||||||
|
/* No kernel filename set, fallback to default */
|
||||||
|
XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n");
|
||||||
|
Parameters->KernelFile = (PWCHAR)L"xtoskrnl.exe";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if provided any kernel boot arguments */
|
||||||
|
if(Parameters->Parameters == NULLPTR)
|
||||||
|
{
|
||||||
|
/* No argument supplied */
|
||||||
|
Parameters->Parameters = (PWCHAR)L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a debug message */
|
||||||
|
XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n"
|
||||||
|
L"[XTOS] System Path: %S\n"
|
||||||
|
L"[XTOS] Kernel File: %S\n"
|
||||||
|
L"[XTOS] Boot Arguments: %S\n",
|
||||||
|
Parameters->ArcName, Parameters->SystemPath,
|
||||||
|
Parameters->KernelFile, Parameters->Parameters);
|
||||||
|
|
||||||
|
/* Open EFI volume */
|
||||||
|
Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open a volume */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* System path has to point to the boot directory */
|
||||||
|
RtlConcatenateWideString(Parameters->SystemPath, (PWCHAR)L"\\Boot", 0);
|
||||||
|
|
||||||
|
/* Open XTOS system boot directory */
|
||||||
|
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);
|
||||||
|
FsHandle->Close(FsHandle);
|
||||||
|
|
||||||
|
/* Check if system path directory opened successfully */
|
||||||
|
if(Status == STATUS_EFI_NOT_FOUND)
|
||||||
|
{
|
||||||
|
/* Directory not found, nothing to load */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
|
||||||
|
|
||||||
|
/* Close volume */
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
else if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open directory */
|
||||||
|
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
|
||||||
|
XtLdrProtocol->Disk.CloseVolume(&DiskHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start boot sequence */
|
||||||
|
return RunBootSequence(BootDir, Parameters);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns information about frame buffer in XTOS compatible format.
|
* Returns information about frame buffer in XTOS compatible format.
|
||||||
@@ -37,7 +162,7 @@ XTBL_BOOT_PROTOCOL XtBootProtocol;
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
VOID
|
VOID
|
||||||
XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
Xtos::GetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
||||||
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
IN PEFI_PHYSICAL_ADDRESS FrameBufferBase,
|
||||||
IN PULONG_PTR FrameBufferSize,
|
IN PULONG_PTR FrameBufferSize,
|
||||||
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
|
IN PXTBL_FRAMEBUFFER_MODE_INFORMATION FrameBufferModeInfo)
|
||||||
@@ -65,7 +190,7 @@ XtGetDisplayInformation(OUT PSYSTEM_RESOURCE_FRAMEBUFFER FrameBufferResource,
|
|||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::GetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PLIST_ENTRY MemoryDescriptorList)
|
OUT PLIST_ENTRY MemoryDescriptorList)
|
||||||
{
|
{
|
||||||
@@ -114,7 +239,7 @@ XtGetMemoryDescriptorList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
|
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::GetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
OUT PLIST_ENTRY SystemResourcesList)
|
OUT PLIST_ENTRY SystemResourcesList)
|
||||||
{
|
{
|
||||||
@@ -152,7 +277,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
VirtualBase = *VirtualAddress;
|
VirtualBase = *VirtualAddress;
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
/* Calculate next valid virtual address */
|
||||||
*VirtualAddress += (UINT_PTR)(Pages * EFI_PAGE_SIZE);
|
*VirtualAddress = (PUINT8)*VirtualAddress + (Pages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
|
AcpiResource = (PSYSTEM_RESOURCE_ACPI)Address;
|
||||||
|
|
||||||
@@ -178,7 +303,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
RtlInsertTailList(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
RtlInsertTailList(SystemResourcesList, &AcpiResource->Header.ListEntry);
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
/* Close FrameBuffer protocol */
|
||||||
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
Address = Address + sizeof(SYSTEM_RESOURCE_ACPI);
|
||||||
|
|
||||||
@@ -196,7 +321,7 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* Store information about FrameBuffer device */
|
/* Store information about FrameBuffer device */
|
||||||
XtGetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo);
|
GetDisplayInformation(FrameBufferResource, &FbAddress, &FbSize, &FbModeInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
@@ -216,9 +341,9 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
FrameBufferPages, LoaderFirmwarePermanent);
|
FrameBufferPages, LoaderFirmwarePermanent);
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
/* Close FrameBuffer protocol */
|
||||||
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
*VirtualAddress += (UINT_PTR)(FrameBufferPages * EFI_PAGE_SIZE);
|
*VirtualAddress = (PUINT8)*VirtualAddress + (FrameBufferPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
RtlInsertTailList(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
RtlInsertTailList(SystemResourcesList, &FrameBufferResource->Header.ListEntry);
|
||||||
|
|
||||||
@@ -227,261 +352,6 @@ XtGetSystemResourcesList(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the operating system according to the provided parameters using XTOS boot protocol.
|
|
||||||
*
|
|
||||||
* @param Parameters
|
|
||||||
* Input parameters with detailed system configuration like boot device or kernel path.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
|
|
||||||
{
|
|
||||||
EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
|
|
||||||
EFI_HANDLE DiskHandle, ProtocolHandle;
|
|
||||||
PEFI_FILE_HANDLE FsHandle, BootDir;
|
|
||||||
PWCHAR SystemPath;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
|
|
||||||
/* Print debug message */
|
|
||||||
XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n");
|
|
||||||
|
|
||||||
/* Open the XT PE/COFF protocol */
|
|
||||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open loader protocol */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n");
|
|
||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check device path */
|
|
||||||
if(Parameters->DevicePath == NULLPTR)
|
|
||||||
{
|
|
||||||
/* No device path set */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
|
|
||||||
return STATUS_EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if system path is set */
|
|
||||||
if(Parameters->SystemPath != NULLPTR)
|
|
||||||
{
|
|
||||||
/* Make sure system path begins with backslash, the only separator supported by EFI */
|
|
||||||
if(Parameters->SystemPath[0] == '/')
|
|
||||||
{
|
|
||||||
/* Replace directory separator if needed */
|
|
||||||
Parameters->SystemPath[0] = '\\';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Validate system path */
|
|
||||||
SystemPath = &Parameters->SystemPath[1];
|
|
||||||
while(*SystemPath)
|
|
||||||
{
|
|
||||||
/* Make sure it does not point to any subdirectory and not contains special characters */
|
|
||||||
if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))
|
|
||||||
{
|
|
||||||
/* Invalid path specified */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: System path does not point to the valid XTOS installation\n");
|
|
||||||
return STATUS_EFI_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
/* Check next character in the path */
|
|
||||||
SystemPath++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Fallback to '/ExectOS' by default */
|
|
||||||
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
|
|
||||||
Parameters->SystemPath = L"\\ExectOS";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if kernel file is set */
|
|
||||||
if(Parameters->KernelFile == NULLPTR)
|
|
||||||
{
|
|
||||||
/* No kernel filename set, fallback to default */
|
|
||||||
XtLdrProtocol->Debug.Print(L"WARNING: No kernel file specified, falling back to defaults\n");
|
|
||||||
Parameters->KernelFile = L"xtoskrnl.exe";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if provided any kernel boot arguments */
|
|
||||||
if(Parameters->Parameters == NULLPTR)
|
|
||||||
{
|
|
||||||
/* No argument supplied */
|
|
||||||
Parameters->Parameters = L"";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print a debug message */
|
|
||||||
XtLdrProtocol->Debug.Print(L"[XTOS] ARC Path: %S\n"
|
|
||||||
L"[XTOS] System Path: %S\n"
|
|
||||||
L"[XTOS] Kernel File: %S\n"
|
|
||||||
L"[XTOS] Boot Arguments: %S\n",
|
|
||||||
Parameters->ArcName, Parameters->SystemPath,
|
|
||||||
Parameters->KernelFile, Parameters->Parameters);
|
|
||||||
|
|
||||||
/* Open EFI volume */
|
|
||||||
Status = XtLdrProtocol->Disk.OpenVolume(Parameters->DevicePath, &DiskHandle, &FsHandle);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open a volume */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n");
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* System path has to point to the boot directory */
|
|
||||||
RtlConcatenateWideString(Parameters->SystemPath, L"\\Boot", 0);
|
|
||||||
|
|
||||||
/* Open XTOS system boot directory */
|
|
||||||
Status = FsHandle->Open(FsHandle, &BootDir, Parameters->SystemPath, EFI_FILE_MODE_READ, 0);
|
|
||||||
FsHandle->Close(FsHandle);
|
|
||||||
|
|
||||||
/* Check if system path directory opened successfully */
|
|
||||||
if(Status == STATUS_EFI_NOT_FOUND)
|
|
||||||
{
|
|
||||||
/* Directory not found, nothing to load */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
|
|
||||||
|
|
||||||
/* Close volume */
|
|
||||||
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
else if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open directory */
|
|
||||||
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
|
|
||||||
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start boot sequence */
|
|
||||||
return XtpBootSequence(BootDir, Parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This routine initiates an XTOS boot sequence.
|
|
||||||
*
|
|
||||||
* @param BootDir
|
|
||||||
* An EFI handle to the XTOS boot directory.
|
|
||||||
*
|
|
||||||
* @param Parameters
|
|
||||||
* Input parameters with detailed system configuration like boot device or kernel path.
|
|
||||||
*
|
|
||||||
* @return This routine returns a status code.
|
|
||||||
*
|
|
||||||
* @since XT 1.0
|
|
||||||
*/
|
|
||||||
XTCDECL
|
|
||||||
EFI_STATUS
|
|
||||||
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
|
||||||
{
|
|
||||||
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
|
||||||
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
|
||||||
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
|
|
||||||
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
|
||||||
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
|
||||||
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
|
||||||
PVOID VirtualAddress, VirtualMemoryArea;
|
|
||||||
PXT_ENTRY_POINT KernelEntryPoint;
|
|
||||||
EFI_HANDLE ProtocolHandle;
|
|
||||||
EFI_STATUS Status;
|
|
||||||
XTBL_PAGE_MAPPING PageMap;
|
|
||||||
|
|
||||||
/* Initialize XTOS startup sequence */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
|
||||||
|
|
||||||
/* Load FrameBuffer protocol */
|
|
||||||
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
|
|
||||||
if(Status == STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Make sure FrameBuffer is initialized */
|
|
||||||
FrameBufProtocol->Initialize();
|
|
||||||
FrameBufProtocol->SetScreenResolution(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close FrameBuffer protocol */
|
|
||||||
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
|
|
||||||
|
|
||||||
/* Set base virtual memory area for the kernel mappings */
|
|
||||||
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
|
||||||
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
|
||||||
|
|
||||||
/* Initialize virtual memory mappings */
|
|
||||||
XtLdrProtocol->Memory.InitializePageMap(&PageMap, XtpDeterminePagingLevel(Parameters->Parameters), Size4K);
|
|
||||||
|
|
||||||
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the kernel */
|
|
||||||
Status = XtpLoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to load the kernel */
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add kernel image memory mapping */
|
|
||||||
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
|
|
||||||
ImageContext->PhysicalAddress, ImageContext->ImagePages, 0);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set next valid virtual address right after the kernel */
|
|
||||||
VirtualAddress += ImageContext->ImagePages * EFI_PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Find and map APIC base address */
|
|
||||||
Status = XtpInitializeApicBase(&PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to setup kernel initialization block */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: 0x%zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store virtual address of kernel initialization block for future kernel call */
|
|
||||||
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
|
||||||
|
|
||||||
/* Setup and map kernel initialization block */
|
|
||||||
Status = XtpInitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to setup kernel initialization block */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: 0x%zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get kernel entry point */
|
|
||||||
XtPeCoffProtocol->GetEntryPoint(ImageContext, (PVOID)&KernelEntryPoint);
|
|
||||||
|
|
||||||
/* Close boot directory handle */
|
|
||||||
BootDir->Close(BootDir);
|
|
||||||
|
|
||||||
/* Enable paging */
|
|
||||||
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
|
|
||||||
Status = XtEnablePaging(&PageMap);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to enable paging */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: 0x%zX)\n", Status);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call XTOS kernel */
|
|
||||||
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
|
|
||||||
KernelEntryPoint(KernelParameters);
|
|
||||||
|
|
||||||
/* Return success */
|
|
||||||
return STATUS_EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if APIC is present in the system and finds its base address.
|
* Checks if APIC is present in the system and finds its base address.
|
||||||
*
|
*
|
||||||
@@ -494,7 +364,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
Xtos::InitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
||||||
{
|
{
|
||||||
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
|
EFI_GUID AcpiGuid = XT_ACPI_PROTOCOL_GUID;
|
||||||
PXTBL_ACPI_PROTOCOL AcpiProtocol;
|
PXTBL_ACPI_PROTOCOL AcpiProtocol;
|
||||||
@@ -538,7 +408,7 @@ XtpInitializeApicBase(IN PXTBL_PAGE_MAPPING PageMap)
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
Xtos::InitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
||||||
IN PVOID *VirtualAddress,
|
IN PVOID *VirtualAddress,
|
||||||
IN PXTBL_BOOT_PARAMETERS Parameters)
|
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
{
|
{
|
||||||
@@ -573,7 +443,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
|
||||||
|
|
||||||
/* Set LoaderInformation block properties */
|
/* Set LoaderInformation block properties */
|
||||||
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print;
|
LoaderBlock->LoaderInformation.DbgPrint = (PVOID)XtLdrProtocol->Debug.Print;
|
||||||
|
|
||||||
/* Attempt to find virtual address of the EFI Runtime Services */
|
/* Attempt to find virtual address of the EFI Runtime Services */
|
||||||
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
|
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
|
||||||
@@ -601,19 +471,45 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
BlockPages, LoaderSystemBlock);
|
BlockPages, LoaderSystemBlock);
|
||||||
|
|
||||||
/* Calculate next valid virtual address */
|
/* Calculate next valid virtual address */
|
||||||
*VirtualAddress += (UINT_PTR)(BlockPages * EFI_PAGE_SIZE);
|
*VirtualAddress = (PUINT8)*VirtualAddress + (BlockPages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
RtlInitializeListHead(&LoaderBlock->SystemResourcesListHead);
|
RtlInitializeListHead(&LoaderBlock->SystemResourcesListHead);
|
||||||
XtGetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
GetSystemResourcesList(PageMap, VirtualAddress, &LoaderBlock->SystemResourcesListHead);
|
||||||
|
|
||||||
/* Initialize memory descriptor list */
|
/* Initialize memory descriptor list */
|
||||||
RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
|
RtlInitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
|
||||||
XtGetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
GetMemoryDescriptorList(PageMap, VirtualAddress, &LoaderBlock->MemoryDescriptorListHead);
|
||||||
|
|
||||||
/* Return success */
|
/* Return success */
|
||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::InitializeModule(IN EFI_HANDLE ImageHandle,
|
||||||
|
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||||
|
{
|
||||||
|
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
/* Open the XTLDR protocol */
|
||||||
|
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to open loader protocol */
|
||||||
|
return STATUS_EFI_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set routines available via XTOS boot protocol */
|
||||||
|
BootProtocol.BootSystem = Xtos::BootSystem;
|
||||||
|
|
||||||
|
/* Register XTOS boot protocol */
|
||||||
|
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
|
||||||
|
|
||||||
|
/* Install XTOS protocol */
|
||||||
|
return XtLdrProtocol->Protocol.Install(&BootProtocol, &Guid);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads XTOS PE/COFF module.
|
* Loads XTOS PE/COFF module.
|
||||||
*
|
*
|
||||||
@@ -638,7 +534,7 @@ XtpInitializeLoaderBlock(IN PXTBL_PAGE_MAPPING PageMap,
|
|||||||
*/
|
*/
|
||||||
XTCDECL
|
XTCDECL
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
Xtos::LoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
||||||
IN PWCHAR FileName,
|
IN PWCHAR FileName,
|
||||||
IN PVOID VirtualAddress,
|
IN PVOID VirtualAddress,
|
||||||
IN LOADER_MEMORY_TYPE MemoryType,
|
IN LOADER_MEMORY_TYPE MemoryType,
|
||||||
@@ -661,7 +557,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load the PE/COFF image file */
|
/* Load the PE/COFF image file */
|
||||||
Status = XtPeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID)ImageContext);
|
Status = PeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID*)ImageContext);
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Unable to load the file */
|
/* Unable to load the file */
|
||||||
@@ -673,7 +569,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
|||||||
ModuleHandle->Close(ModuleHandle);
|
ModuleHandle->Close(ModuleHandle);
|
||||||
|
|
||||||
/* Check PE/COFF image machine type compatibility */
|
/* Check PE/COFF image machine type compatibility */
|
||||||
XtPeCoffProtocol->GetMachineType(*ImageContext, &MachineType);
|
PeCoffProtocol->GetMachineType(*ImageContext, &MachineType);
|
||||||
if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)
|
if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)
|
||||||
{
|
{
|
||||||
/* Machine type mismatch */
|
/* Machine type mismatch */
|
||||||
@@ -682,7 +578,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check PE/COFF image subsystem */
|
/* Check PE/COFF image subsystem */
|
||||||
XtPeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem);
|
PeCoffProtocol->GetSubSystem(*ImageContext, &SubSystem);
|
||||||
if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL &&
|
if(SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_KERNEL &&
|
||||||
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&
|
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&
|
||||||
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)
|
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)
|
||||||
@@ -698,6 +594,129 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
|
|||||||
return STATUS_EFI_SUCCESS;
|
return STATUS_EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This routine initiates an XTOS boot sequence.
|
||||||
|
*
|
||||||
|
* @param BootDir
|
||||||
|
* An EFI handle to the XTOS boot directory.
|
||||||
|
*
|
||||||
|
* @param Parameters
|
||||||
|
* Input parameters with detailed system configuration like boot device or kernel path.
|
||||||
|
*
|
||||||
|
* @return This routine returns a status code.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
EFI_STATUS
|
||||||
|
Xtos::RunBootSequence(IN PEFI_FILE_HANDLE BootDir,
|
||||||
|
IN PXTBL_BOOT_PARAMETERS Parameters)
|
||||||
|
{
|
||||||
|
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||||
|
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
|
||||||
|
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
|
||||||
|
PXTBL_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
|
||||||
|
PPECOFF_IMAGE_CONTEXT ImageContext = NULLPTR;
|
||||||
|
PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol;
|
||||||
|
PVOID VirtualAddress, VirtualMemoryArea;
|
||||||
|
PXT_ENTRY_POINT KernelEntryPoint;
|
||||||
|
EFI_HANDLE ProtocolHandle;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
XTBL_PAGE_MAPPING PageMap;
|
||||||
|
|
||||||
|
/* Initialize XTOS startup sequence */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
|
||||||
|
|
||||||
|
/* Load FrameBuffer protocol */
|
||||||
|
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
|
||||||
|
if(Status == STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Make sure FrameBuffer is initialized */
|
||||||
|
FrameBufProtocol->Initialize();
|
||||||
|
FrameBufProtocol->SetScreenResolution(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close FrameBuffer protocol */
|
||||||
|
XtLdrProtocol->Protocol.Close(&ProtocolHandle, &FrameBufGuid);
|
||||||
|
|
||||||
|
/* Set base virtual memory area for the kernel mappings */
|
||||||
|
VirtualMemoryArea = (PVOID)KSEG0_BASE;
|
||||||
|
VirtualAddress = (PVOID)(KSEG0_BASE + KSEG0_KERNEL_BASE);
|
||||||
|
|
||||||
|
/* Initialize virtual memory mappings */
|
||||||
|
XtLdrProtocol->Memory.InitializePageMap(&PageMap, DeterminePagingLevel(Parameters->Parameters), Size4K);
|
||||||
|
|
||||||
|
Status = XtLdrProtocol->Memory.MapEfiMemory(&PageMap, &VirtualMemoryArea, NULLPTR);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the kernel */
|
||||||
|
Status = LoadModule(BootDir, Parameters->KernelFile, VirtualAddress, LoaderSystemCode, &ImageContext);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to load the kernel */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add kernel image memory mapping */
|
||||||
|
Status = XtLdrProtocol->Memory.MapVirtualMemory(&PageMap, ImageContext->VirtualAddress,
|
||||||
|
ImageContext->PhysicalAddress, ImageContext->ImagePages,
|
||||||
|
LoaderExceptionBlock); // 0 is LoaderExceptionBlock?! Should be LoaderSystemCode?
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set next valid virtual address right after the kernel */
|
||||||
|
VirtualAddress = (PUINT8)VirtualAddress + (ImageContext->ImagePages * EFI_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Find and map APIC base address */
|
||||||
|
Status = InitializeApicBase(&PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to setup kernel initialization block */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: 0x%zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store virtual address of kernel initialization block for future kernel call */
|
||||||
|
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
|
||||||
|
|
||||||
|
/* Setup and map kernel initialization block */
|
||||||
|
Status = InitializeLoaderBlock(&PageMap, &VirtualAddress, Parameters);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to setup kernel initialization block */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: 0x%zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get kernel entry point */
|
||||||
|
PeCoffProtocol->GetEntryPoint(ImageContext, (PVOID*)&KernelEntryPoint);
|
||||||
|
|
||||||
|
/* Close boot directory handle */
|
||||||
|
BootDir->Close(BootDir);
|
||||||
|
|
||||||
|
/* Enable paging */
|
||||||
|
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
|
||||||
|
Status = EnablePaging(&PageMap);
|
||||||
|
if(Status != STATUS_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Failed to enable paging */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: 0x%zX)\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call XTOS kernel */
|
||||||
|
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
|
||||||
|
KernelEntryPoint(KernelParameters);
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return STATUS_EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routine is the entry point of the XT EFI boot loader module.
|
* This routine is the entry point of the XT EFI boot loader module.
|
||||||
*
|
*
|
||||||
@@ -716,23 +735,6 @@ EFI_STATUS
|
|||||||
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
|
||||||
IN PEFI_SYSTEM_TABLE SystemTable)
|
IN PEFI_SYSTEM_TABLE SystemTable)
|
||||||
{
|
{
|
||||||
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;
|
/* Initialize XTOS module */
|
||||||
EFI_STATUS Status;
|
return Xtos::InitializeModule(ImageHandle, SystemTable);
|
||||||
|
|
||||||
/* Open the XTLDR protocol */
|
|
||||||
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
|
|
||||||
if(Status != STATUS_EFI_SUCCESS)
|
|
||||||
{
|
|
||||||
/* Failed to open loader protocol */
|
|
||||||
return STATUS_EFI_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set routines available via XTOS boot protocol */
|
|
||||||
XtBootProtocol.BootSystem = XtBootSystem;
|
|
||||||
|
|
||||||
/* Register XTOS boot protocol */
|
|
||||||
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
|
|
||||||
|
|
||||||
/* Install XTOS protocol */
|
|
||||||
return XtLdrProtocol->Protocol.Install(&XtBootProtocol, &Guid);
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user