Rewrite core of the XTLDR boot loader

Reviewed-on: xt-sys/exectos#7
Reviewed-by: Piotr Likoski <likoski@noreply.codingworkshop.git>
Co-authored-by: Rafal Kupiec <belliash@codingworkshop.eu.org>
Co-committed-by: Rafal Kupiec <belliash@codingworkshop.eu.org>
This commit is contained in:
2024-01-09 18:51:04 +01:00
committed by CodingWorkshop Signing Team
parent 44905bb71d
commit 4412d4fc98
63 changed files with 6282 additions and 2371 deletions

View File

@@ -1,3 +1,5 @@
add_subdirectory(framebuf)
add_subdirectory(pecoff)
add_subdirectory(xtos)
add_subdirectory(beep)
add_subdirectory(dummy)
add_subdirectory(fb_o)
add_subdirectory(pecoff_o)
add_subdirectory(xtos_o)

View File

@@ -0,0 +1,27 @@
# XT Boot Loader Beep Module
PROJECT(XTLDR_BEEP)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_BEEP_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_BEEP_SOURCE
${XTLDR_BEEP_SOURCE_DIR}/beep.c
${XTLDR_BEEP_SOURCE_DIR}/globals.c)
# Link bootloader executable
add_executable(beep ${XTLDR_BEEP_SOURCE})
# Add linker libraries
target_link_libraries(beep libxtldr libxtos)
# Set proper binary name and install target
set_target_properties(beep PROPERTIES SUFFIX .efi)
set_install_target(beep efi/boot/xtldr/modules)
# Set module entrypoint and subsystem
set_entrypoint(beep "XtLdrModuleMain")
set_linker_map(beep TRUE)
set_subsystem(beep efi_boot_service_driver)

209
xtldr/modules/beep/beep.c Normal file
View File

@@ -0,0 +1,209 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/beep.c
* DESCRIPTION: XTLDR Beep Module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <beep.h>
/* Dummy module information */
XTBL_MODINFO = L"Plays a GRUB compatible tune via PC speaker";
/**
* Disables the PC speaker.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BpDisableToneBeep()
{
UCHAR Status;
/* Stop the PC speaker */
Status = HlIoPortInByte(0x61);
HlIoPortOutByte(0x61, Status & 0xFC);
}
/**
* Enables the PC speaker and plays a sound.
*
* @param Pitch
* Specifies a pitch (in Hz) of the sound.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BpEnableToneBeep(IN UINT Pitch)
{
UINT Counter;
UCHAR Status;
/* Pitch only in range of 20..20000 */
if(Pitch < 20)
{
Pitch = 20;
}
else if(Pitch > 20000)
{
Pitch = 20000;
}
/* Set the desired frequency of the PIT clock */
Counter = 0x1234DD / Pitch;
HlIoPortOutByte(0x43, 0xB6);
HlIoPortOutByte(0x43, 0xB6);
HlIoPortOutByte(0x42, (UCHAR) Counter & 0xFF);
HlIoPortOutByte(0x42, (UCHAR) (Counter >> 8) & 0xFF);
/* Start the PC speaker */
Status = HlIoPortInByte(0x61);
HlIoPortOutByte(0x61, Status | 0x03);
}
/**
* This routine plays a tune.
*
* @param Arguments
* Optional list of parameters provided with the command.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BpPlayTune(IN PWCHAR Arguments)
{
LONG Pitch, Duration, Tempo;
PWCHAR Argument, LastArgument;
/* Reset pitch and duration */
Duration = -1;
Pitch = -1;
Tempo = -1;
/* Tokenize provided list of arguments */
Argument = RtlTokenizeWideString(Arguments, L" ", &LastArgument);
/* Iterate over all arguments */
while(Argument != NULL)
{
/* Check if tempo, pitch and duration are set */
if(Tempo < 0)
{
/* Set the tempo */
Tempo = BpWideStringToNumber(Argument);
}
else if(Pitch < 0)
{
/* Set the pitch */
Pitch = BpWideStringToNumber(Argument);
}
else
{
/* Set the duration */
Duration = BpWideStringToNumber(Argument);
/* Check pitch value */
if(Pitch > 0)
{
/* Emit the beep tone */
BpEnableToneBeep(Pitch);
}
else
{
/* Stop emitting beep tone */
BpDisableToneBeep();
}
/* Wait for duration time */
XtLdrProto->Util.SleepExecution(60000 * Duration / Tempo);
/* Reset pitch and duration */
Pitch = -1;
Duration = -1;
}
/* Get next argument */
Argument = RtlTokenizeWideString(NULL, L" ", &LastArgument);
}
/* Stop emitting beep tone */
BpDisableToneBeep();
}
/**
* Converts a wide string into a number.
*
* @param String
* Supplies an input wide string.
*
* @return This routine returns the number that was converted from the wide string.
*
* @since XT 1.0
*/
XTCDECL
UINT
BpWideStringToNumber(IN PWCHAR String)
{
ULONG Number = 0;
/* Iterate over all characters until '\0' found */
do
{
/* Check if this is a digit */
if(*String - '0' < 10)
{
/* Add another digit to the number */
Number *= 10;
Number += *String - '0';
}
}
while(*++String != L'\0');
/* Return number */
return Number;
}
/**
* This routine is the entry point of the XT EFI boot loader module.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProto);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Play the tune set in the configuration */
BpPlayTune(XtLdrProto->Config.GetValue(L"TUNE"));
return STATUS_EFI_SUCCESS;
}

View File

@@ -0,0 +1,13 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/globals.c
* DESCRIPTION: Dummy XTLDR module global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtblapi.h>
/* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProto;

View File

@@ -0,0 +1,38 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/includes/beep.h
* DESCRIPTION: XTLDR Beep Module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_BEEP_BEEP_H
#define __XTLDR_BEEP_BEEP_H
#include <xtblapi.h>
#include <globals.h>
/* Beep module routines forward references */
XTCDECL
VOID
BpDisableToneBeep();
XTCDECL
VOID
BpEnableToneBeep(IN UINT Pitch);
XTCDECL
VOID
BpPlayTune(IN PWCHAR Arguments);
XTCDECL
UINT
BpWideStringToNumber(IN PWCHAR String);
XTCDECL
EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif/* __XTLDR_BEEP_BEEP_H */

View File

@@ -0,0 +1,18 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/beep/includes/globals.h
* DESCRIPTION: XTLDR Beep Module global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_BEEP_GLOBALS_H
#define __XTLDR_BEEP_GLOBALS_H
#include <beep.h>
/* XTLDR protocol handler */
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProto;
#endif/* __XTLDR_BEEP_GLOBALS_H */

View File

@@ -0,0 +1,27 @@
# XT Boot Loader Dummy Module
PROJECT(XTLDR_DUMMY)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_DUMMY_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_DUMMY_SOURCE
${XTLDR_DUMMY_SOURCE_DIR}/dummy.c
${XTLDR_DUMMY_SOURCE_DIR}/globals.c)
# Link bootloader executable
add_executable(dummy ${XTLDR_DUMMY_SOURCE})
# Add linker libraries
target_link_libraries(dummy libxtldr)
# Set proper binary name and install target
set_target_properties(dummy PROPERTIES SUFFIX .efi)
set_install_target(dummy efi/boot/xtldr/modules)
# Set module entrypoint and subsystem
set_entrypoint(dummy "XtLdrModuleMain")
set_linker_map(dummy TRUE)
set_subsystem(dummy efi_boot_service_driver)

View File

@@ -0,0 +1,69 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/dummy.c
* DESCRIPTION: XTLDR Dummy Module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <dummy.h>
/* Dummy module information */
XTBL_MODINFO = L"XTLDR Dummy Module";
/**
* Stub boot routine.
*
* @param Parameters
* Supplies all parameters associated with the chosen boot menu entry.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters)
{
return STATUS_EFI_SUCCESS;
}
/**
* This routine is the entry point of the XT EFI boot loader module.
*
* @param ImageHandle
* Firmware-allocated handle that identifies the image.
*
* @param SystemTable
* Provides the EFI system table.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID DummyGuid = XT_XTOS_BOOT_PROTOCOL_GUID;
EFI_STATUS Status;
/* Open the XTLDR protocol */
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProto);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open the protocol, return error */
return STATUS_EFI_PROTOCOL_ERROR;
}
/* Set boot protocol routines */
BlpDummyProtocol.BootSystem = BlBootDummyOS;
/* Register XTOS boot protocol */
XtLdrProto->Boot.RegisterProtocol(L"XTOS", &DummyGuid);
/* Register DUMMY protocol as XTOS boot protocol */
return XtLdrProto->Protocol.Install(&BlpDummyProtocol, &DummyGuid);
}

View File

@@ -0,0 +1,16 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/globals.c
* DESCRIPTION: Dummy XTLDR module global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <dummy.h>
/* XTLDR protocol handler */
PXTBL_LOADER_PROTOCOL XtLdrProto;
/* Dummy Boot Protocol handler */
XTBL_BOOT_PROTOCOL BlpDummyProtocol;

View File

@@ -0,0 +1,26 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/includes/dummy.h
* DESCRIPTION: XTLDR Dummy Module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_DUMMY_DUMMY_H
#define __XTLDR_DUMMY_DUMMY_H
#include <xtblapi.h>
#include <globals.h>
/* Dummy module routines forward references */
XTCDECL
EFI_STATUS
BlBootDummyOS(IN PXTBL_BOOT_PARAMETERS Parameters);
XTCDECL
EFI_STATUS
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif/* __XTLDR_DUMMY_DUMMY_H */

View File

@@ -0,0 +1,21 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/dummy/includes/globals.h
* DESCRIPTION: XTLDR Dummy Module global variables
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_DUMMY_GLOBALS_H
#define __XTLDR_DUMMY_GLOBALS_H
#include <dummy.h>
/* XTLDR protocol handler */
EXTERN PXTBL_LOADER_PROTOCOL XtLdrProto;
/* Dummy Boot Protocol handler */
EXTERN XTBL_BOOT_PROTOCOL BlpDummyProtocol;
#endif/* __XTLDR_DUMMY_GLOBALS_H */

View File

@@ -0,0 +1,27 @@
# XT Boot Loader
PROJECT(XTLDR_FB_O)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_FB_O_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_FB_O_SOURCE
${XTLDR_FB_O_SOURCE_DIR}/framebuf.c
${XTLDR_FB_O_SOURCE_DIR}/gop.c)
# Link bootloader executable
add_executable(fb_o ${XTLDR_FB_O_SOURCE})
# Add linker libraries
target_link_libraries(fb_o libxtos libxtldr)
# Set proper binary name and install target
set_target_properties(fb_o PROPERTIES SUFFIX .efi)
set_install_target(fb_o efi/boot/xtldr/modules)
# Set module entrypoint and subsystem
set_entrypoint(fb_o "XtLdrModuleMain")
set_linker_map(fb_o TRUE)
set_subsystem(fb_o efi_boot_service_driver)

View File

@@ -9,14 +9,11 @@
#include <framebuf.h>
/* EFI Image Handle */
EFI_HANDLE EfiImageHandle;
/* EFI System Table */
PEFI_SYSTEM_TABLE EfiSystemTable;
/* PE/COFF_O module information */
XTBL_MODINFO = L"EFI FB (FrameBuffer) support";
/* EFI XT Loader Protocol */
PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol;
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XT FrameBuffer Information */
XT_FRAMEBUFFER_INFORMATION FrameBufferInfo;
@@ -36,18 +33,18 @@ XT_FRAMEBUFFER_PROTOCOL XtFramebufferProtocol;
*/
XTCDECL
VOID
FbGetDisplayDriver(OUT PWCHAR *DriverName)
FbGetDisplayDriver(OUT PWCHAR DriverName)
{
switch(FrameBufferInfo.Protocol)
{
case GOP:
*DriverName = L"GOP";
DriverName = L"GOP";
break;
case UGA:
*DriverName = L"UGA";
DriverName = L"UGA";
break;
default:
*DriverName = L"NONE";
DriverName = L"NONE";
break;
}
}
@@ -91,30 +88,25 @@ FbInitializeDisplay()
EFI_GUID GopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID UgaGuid = EFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL_GUID;
UINT32 Parameter1, Parameter2;
EFI_HANDLE Handle;
EFI_STATUS Status;
/* Check if framebuffer already initialized */
if(!FrameBufferInfo.Initialized)
{
/* Initialize framebuffer */
XtLdrProtocol->DbgPrint(L"Initializing framebuffer device\n");
XtLdrProtocol->Debug.Print(L"Initializing framebuffer device\n");
FrameBufferInfo.Protocol = NONE;
FrameBufferInfo.Initialized = FALSE;
/* Check if GOP already in use */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiSystemTable->ConsoleOutHandle, &GopGuid,
(PVOID*)&FrameBufferInfo.Adapter.GOP);
if(Status != STATUS_EFI_SUCCESS)
{
/* Locate GOP protocol */
Status = EfiSystemTable->BootServices->LocateProtocol(&GopGuid, NULL, (PVOID *)&FrameBufferInfo.Adapter.GOP);
}
/* Attempt to open GOP protocol */
Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FrameBufferInfo.Adapter.GOP, &GopGuid);
/* Check if Graphics Output Protocol is available */
if(Status == STATUS_EFI_SUCCESS)
{
/* Found GOP */
XtLdrProtocol->DbgPrint(L"Found GOP compatible display adapter\n");
XtLdrProtocol->Debug.Print(L"Found GOP compatible display adapter\n");
/* Set framebuffer parameters */
FrameBufferInfo.HorizontalResolution = FrameBufferInfo.Adapter.GOP->Mode->Info->HorizontalResolution;
@@ -128,27 +120,23 @@ FbInitializeDisplay()
FrameBufferInfo.FrameBufferSize = FrameBufferInfo.Adapter.GOP->Mode->FrameBufferSize;
FrameBufferInfo.Protocol = GOP;
FrameBufferInfo.Initialized = TRUE;
/* Close GOP protocol */
Status = XtLdrProtocol->Protocol.Close(Handle, &GopGuid);
}
else
{
/* GOP is unavailable */
FrameBufferInfo.Adapter.GOP = NULL;
/* Check if UGA already in use */
Status = EfiSystemTable->BootServices->HandleProtocol(EfiSystemTable->ConsoleOutHandle, &UgaGuid,
(PVOID*)&FrameBufferInfo.Adapter.UGA);
if(Status != STATUS_EFI_SUCCESS)
{
/* Locate UGA protocol */
Status = EfiSystemTable->BootServices->LocateProtocol(&UgaGuid, NULL,
(PVOID*)&FrameBufferInfo.Adapter.UGA);
}
/* Attempt to open UGA protocol */
Status = XtLdrProtocol->Protocol.Open(&Handle, (PVOID*)&FrameBufferInfo.Adapter.UGA, &UgaGuid);
/* Check if Universal Graphics Adapter is available */
if(Status == STATUS_EFI_SUCCESS)
{
/* Found UGA */
XtLdrProtocol->DbgPrint(L"Found UGA compatible display adapter\n");
XtLdrProtocol->Debug.Print(L"Found UGA compatible display adapter\n");
/* Get current mode */
Status = FrameBufferInfo.Adapter.UGA->GetMode(FrameBufferInfo.Adapter.UGA,
@@ -158,7 +146,7 @@ FbInitializeDisplay()
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get current UGA mode */
XtLdrProtocol->DbgPrint(L"Failed to get current UGA mode (Status code: %lx)\n", Status);
XtLdrProtocol->Debug.Print(L"Failed to get current UGA mode (Status code: %lx)\n", Status);
FrameBufferInfo.Adapter.UGA = NULL;
}
else
@@ -178,6 +166,9 @@ FbInitializeDisplay()
/* Temporarily set this to FALSE, as we don't set FB base and we cannot use it anyway */
FrameBufferInfo.Initialized = FALSE;
}
/* Close UGA protocol */
XtLdrProtocol->Protocol.Close(Handle, &UgaGuid);
}
}
@@ -185,7 +176,7 @@ FbInitializeDisplay()
if(!FrameBufferInfo.Initialized)
{
/* GOP and UGA unavailable */
XtLdrProtocol->DbgPrint(L"No display adapter found\n");
XtLdrProtocol->Debug.Print(L"No display adapter found\n");
return STATUS_EFI_NOT_FOUND;
}
}
@@ -205,31 +196,31 @@ XTCDECL
VOID
FbPrintDisplayInformation()
{
PWCHAR DriverName;
PWCHAR DriverName = NULL;
/* Make sure frame buffer is initialized */
if(!FrameBufferInfo.Initialized)
{
/* No FrameBuffer */
XtLdrProtocol->DbgPrint(L"No display adapters initialized, unable to print video information\n");
XtLdrProtocol->Debug.Print(L"No display adapters initialized, unable to print video information\n");
return;
}
/* Get display driver name */
FbGetDisplayDriver(&DriverName);
FbGetDisplayDriver(DriverName);
/* Print video information */
XtLdrProtocol->DbgPrint(L"XTLDR Framebuffer information:\n"
L" FrameBuffer Address: 0x%lx\n"
L" FrameBuffer Size: %lu\n"
L" FrameBuffer Driver: %S\n"
L" Current Resolution: %ux%ux%u\n"
L" Pixel Format: %u\n"
L" Pixels Per ScanLine: %u\n",
FrameBufferInfo.FrameBufferBase, FrameBufferInfo.FrameBufferSize, DriverName,
FrameBufferInfo.HorizontalResolution, FrameBufferInfo.VerticalResolution,
FrameBufferInfo.BitsPerPixel, FrameBufferInfo.PixelFormat,
FrameBufferInfo.PixelsPerScanLine);
XtLdrProtocol->Debug.Print(L"XTLDR Framebuffer information:\n"
L" FrameBuffer Address: 0x%lx\n"
L" FrameBuffer Size: %lu\n"
L" FrameBuffer Driver: %S\n",
FrameBufferInfo.FrameBufferBase, FrameBufferInfo.FrameBufferSize, DriverName);
XtLdrProtocol->Debug.Print(L" Current Resolution: %dx%dx%d\n"
L" Pixel Format: %u\n"
L" Pixels Per ScanLine: %u\n",
FrameBufferInfo.HorizontalResolution, FrameBufferInfo.VerticalResolution,
FrameBufferInfo.BitsPerPixel, FrameBufferInfo.PixelFormat,
FrameBufferInfo.PixelsPerScanLine);
}
/**
@@ -247,19 +238,14 @@ FbPrintDisplayInformation()
*/
XTCDECL
EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_FRAMEBUFFER_PROTOCOL_GUID;
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
/* Set the system table and image handle */
EfiImageHandle = ImageHandle;
EfiSystemTable = SystemTable;
/* Open the XTLDR protocol */
Status = BlGetXtLoaderProtocol(&XtLdrProtocol);
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
@@ -272,6 +258,5 @@ BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
XtFramebufferProtocol.PrintDisplayInformation = FbPrintDisplayInformation;
/* Register XTOS boot protocol */
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE,
&XtFramebufferProtocol);
return XtLdrProtocol->Protocol.Install(&XtFramebufferProtocol, &Guid);
}

View File

@@ -1,7 +1,7 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/framebuf/gop.c
* FILE: xtldr/modules/fb_o/gop.c
* DESCRIPTION: Graphical Output Protocol (GOP) support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/

View File

@@ -0,0 +1,79 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/fb_o/includes/framebuf.h
* DESCRIPTION: Framebuffer support module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_MODULES_FRAMEBUF_H
#define __XTLDR_MODULES_FRAMEBUF_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;
/* XT framebuffer information structure definition */
typedef struct _XT_FRAMEBUFFER_INFORMATION
{
BOOLEAN Initialized;
EFI_GRAPHICS_PROTOCOL Protocol;
union
{
PEFI_GRAPHICS_OUTPUT_PROTOCOL GOP;
PEFI_UNIVERSAL_GRAPHICS_ADAPTER_PROTOCOL UGA;
} Adapter;
UINT HorizontalResolution;
UINT VerticalResolution;
UINT BitsPerPixel;
UINT BytesPerPixel;
UINT PixelsPerScanLine;
UINT Pitch;
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
EFI_PHYSICAL_ADDRESS FrameBufferBase;
ULONG_PTR FrameBufferSize;
} XT_FRAMEBUFFER_INFORMATION, *PXT_FRAMEBUFFER_INFORMATION;
/* XT FrameBuffer Information */
EXTERN XT_FRAMEBUFFER_INFORMATION FrameBufferInfo;
/* FrameBuffer support protocol related routines forward references */
XTCDECL
VOID
FbGetDisplayDriver(OUT PWCHAR DriverName);
XTCDECL
VOID
FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock);
XTCDECL
EFI_STATUS
FbInitializeDisplay();
XTCDECL
VOID
FbPrintDisplayInformation();
XTCDECL
UINT32
GoppGetBitsPerPixel();
XTCDECL
EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif /* __XTLDR_MODULES_FRAMEBUF_H */

View File

@@ -1,28 +0,0 @@
# XT Boot Loader
PROJECT(XTLDR_FRAMEBUF)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_SOURCE_DIR}/includes
${XTLDR_FRAMEBUF_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_FRAMEBUF_SOURCE
${XTLDR_SOURCE_DIR}/blproto.c
${XTLDR_FRAMEBUF_SOURCE_DIR}/framebuf.c
${XTLDR_FRAMEBUF_SOURCE_DIR}/gop.c)
# Link bootloader executable
add_executable(framebuf ${XTLDR_FRAMEBUF_SOURCE})
# Add linker libraries
target_link_libraries(framebuf libxtos)
# Set proper binary name and install target
set_target_properties(framebuf PROPERTIES SUFFIX .efi)
set_install_target(framebuf efi/boot/xtldr)
# Set module entrypoint and subsystem
set_entrypoint(framebuf "BlXtLdrModuleMain")
set_subsystem(framebuf efi_boot_service_driver)

View File

@@ -1,44 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/framebuf/includes/framebuf.h
* DESCRIPTION: Framebuffer support module header file
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_MODULES_FRAMEBUF_H
#define __XTLDR_MODULES_FRAMEBUF_H
#include <blmod.h>
/* XT FrameBuffer Information */
EXTERN XT_FRAMEBUFFER_INFORMATION FrameBufferInfo;
/* FrameBuffer support protocol related routines forward references */
XTCDECL
VOID
FbGetDisplayDriver(OUT PWCHAR *DriverName);
XTCDECL
VOID
FbGetDisplayInformation(OUT PLOADER_GRAPHICS_INFORMATION_BLOCK InformationBlock);
XTCDECL
EFI_STATUS
FbInitializeDisplay();
XTCDECL
VOID
FbPrintDisplayInformation();
XTCDECL
UINT32
GoppGetBitsPerPixel();
XTCDECL
EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif /* __XTLDR_MODULES_FRAMEBUF_H */

View File

@@ -1,27 +0,0 @@
# XT Boot Loader
PROJECT(XTLDR_PECOFF)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_SOURCE_DIR}/includes
${XTLDR_PECOFF_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_PECOFF_SOURCE
${XTLDR_SOURCE_DIR}/blproto.c
${XTLDR_PECOFF_SOURCE_DIR}/pecoff.c)
# Link bootloader executable
add_executable(pecoff ${XTLDR_PECOFF_SOURCE})
# Add linker libraries
target_link_libraries(pecoff libxtos)
# Set proper binary name and install target
set_target_properties(pecoff PROPERTIES SUFFIX .efi)
set_install_target(pecoff efi/boot/xtldr)
# Set module entrypoint and subsystem
set_entrypoint(pecoff "BlXtLdrModuleMain")
set_subsystem(pecoff efi_boot_service_driver)

View File

@@ -0,0 +1,26 @@
# XT Boot Loader
PROJECT(XTLDR_PECOFF_O)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_PECOFF_O_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_PECOFF_O_SOURCE
${XTLDR_PECOFF_O_SOURCE_DIR}/pecoff.c)
# Link bootloader executable
add_executable(pecoff_o ${XTLDR_PECOFF_O_SOURCE})
# Add linker libraries
target_link_libraries(pecoff_o libxtos libxtldr)
# Set proper binary name and install target
set_target_properties(pecoff_o PROPERTIES SUFFIX .efi)
set_install_target(pecoff_o efi/boot/xtldr/modules)
# Set module entrypoint and subsystem
set_entrypoint(pecoff_o "XtLdrModuleMain")
set_linker_map(pecoff_o TRUE)
set_subsystem(pecoff_o efi_boot_service_driver)

View File

@@ -1,31 +1,31 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/pecoff/includes/pecoff.h
* FILE: xtldr/modules/pecoff_o/includes/pecoff.h
* DESCRIPTION: PE/COFF executable file format support header
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTLDR_MODULES_PECOFF_H
#define __XTLDR_MODULES_PECOFF_H
#ifndef __XTLDR_MODULES_PECOFF_O_H
#define __XTLDR_MODULES_PECOFF_O_H
#include <blmod.h>
#include <xtblapi.h>
/* PE/COFF image protocol related routines forward references */
XTCDECL
EFI_STATUS
PeGetEntryPoint(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetEntryPoint(IN PVOID ImagePointer,
OUT PVOID *EntryPoint);
XTCDECL
EFI_STATUS
PeGetMachineType(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetMachineType(IN PVOID ImagePointer,
OUT PUSHORT MachineType);
XTCDECL
EFI_STATUS
PeGetSubSystem(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetSubSystem(IN PVOID ImagePointer,
OUT PUSHORT SubSystem);
XTCDECL
@@ -33,11 +33,11 @@ EFI_STATUS
PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
IN LOADER_MEMORY_TYPE MemoryType,
IN PVOID VirtualAddress,
OUT PPECOFF_IMAGE_CONTEXT *Image);
OUT PVOID *ImagePointer);
XTCDECL
EFI_STATUS
PeRelocateImage(IN PPECOFF_IMAGE_CONTEXT Image,
PeRelocateImage(IN PVOID ImagePointer,
IN EFI_VIRTUAL_ADDRESS Address);
XTCDECL
@@ -55,4 +55,4 @@ EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif /* __XTLDR_MODULES_PECOFF_H */
#endif /* __XTLDR_MODULES_PECOFF_O_H */

View File

@@ -1,25 +1,22 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/modules/pecoff/pecoff.c
* DESCRIPTION: PE/COFF executable file format support
* FILE: xtldr/modules/pecoff_o/pecoff.c
* DESCRIPTION: OLD and deprecated PE/COFF executable file format support module
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <pecoff.h>
/* EFI Image Handle */
EFI_HANDLE EfiImageHandle;
/* EFI System Table */
PEFI_SYSTEM_TABLE EfiSystemTable;
/* PE/COFF_O module information */
XTBL_MODINFO = L"PE/COFF executable file format support";
/* EFI XT Loader Protocol */
PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol;
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS PE/COFF Image Protocol */
XT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol;
XTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol;
/**
* Returns the address of the entry point.
@@ -36,9 +33,11 @@ XT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol;
*/
XTCDECL
EFI_STATUS
PeGetEntryPoint(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetEntryPoint(IN PVOID ImagePointer,
OUT PVOID *EntryPoint)
{
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
/* Validate input data */
if(!Image || !Image->PeHeader)
{
@@ -66,9 +65,11 @@ PeGetEntryPoint(IN PPECOFF_IMAGE_CONTEXT Image,
*/
XTCDECL
EFI_STATUS
PeGetMachineType(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetMachineType(IN PVOID ImagePointer,
OUT PUSHORT MachineType)
{
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
/* Validate input data */
if(!Image || !Image->PeHeader)
{
@@ -96,9 +97,11 @@ PeGetMachineType(IN PPECOFF_IMAGE_CONTEXT Image,
*/
XTCDECL
EFI_STATUS
PeGetSubSystem(IN PPECOFF_IMAGE_CONTEXT Image,
PeGetSubSystem(IN PVOID ImagePointer,
OUT PUSHORT SubSystem)
{
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
/* Validate input data */
if(!Image || !Image->PeHeader)
{
@@ -135,7 +138,7 @@ EFI_STATUS
PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
IN LOADER_MEMORY_TYPE MemoryType,
IN PVOID VirtualAddress,
OUT PPECOFF_IMAGE_CONTEXT *Image)
OUT PVOID *ImagePointer)
{
EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
@@ -153,11 +156,11 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
ReadSize = sizeof(EFI_FILE_INFO) + 32;
/* Allocate necessary amount of memory */
Status = XtLdrProtocol->AllocatePool(ReadSize, (PVOID *)&FileInfo);
Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n");
XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n");
return Status;
}
@@ -166,12 +169,12 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
{
/* Buffer it too small, but EFI tells the required size, let's reallocate */
XtLdrProtocol->FreePool(&FileInfo);
Status = XtLdrProtocol->AllocatePool(ReadSize, (PVOID *)&FileInfo);
XtLdrProtocol->Memory.FreePool(&FileInfo);
Status = XtLdrProtocol->Memory.AllocatePool(ReadSize, (PVOID *)&FileInfo);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n");
XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n");
return Status;
}
@@ -181,16 +184,16 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get file information */
XtLdrProtocol->DbgPrint(L"ERROR: Failed to get file information\n");
XtLdrProtocol->Debug.Print(L"ERROR: Failed to get file information\n");
return Status;
}
/* Allocate memory for storing image data */
Status = XtLdrProtocol->AllocatePool(sizeof(PECOFF_IMAGE_CONTEXT), (PVOID *)&ImageData);
Status = XtLdrProtocol->Memory.AllocatePool(sizeof(PECOFF_IMAGE_CONTEXT), (PVOID *)&ImageData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
XtLdrProtocol->DbgPrint(L"ERROR: Memory pool allocation failure\n");
XtLdrProtocol->Debug.Print(L"ERROR: Memory pool allocation failure\n");
return Status;
}
@@ -198,18 +201,18 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
ImageData->Data = NULL;
ImageData->FileSize = FileInfo->FileSize;
ImageData->MemoryType = MemoryType;
XtLdrProtocol->FreePool(FileInfo);
XtLdrProtocol->Memory.FreePool(FileInfo);
/* Calculate number of pages */
Pages = EFI_SIZE_TO_PAGES(ImageData->FileSize);
/* Allocate pages */
Status = XtLdrProtocol->AllocatePages(Pages, &Address);
Status = XtLdrProtocol->Memory.AllocatePages(Pages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Pages allocation failure */
XtLdrProtocol->DbgPrint(L"ERROR: Pages allocation failure\n");
XtLdrProtocol->FreePool(ImageData);
XtLdrProtocol->Debug.Print(L"ERROR: Pages allocation failure\n");
XtLdrProtocol->Memory.FreePool(ImageData);
return Status;
}
@@ -220,9 +223,9 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to read data */
XtLdrProtocol->DbgPrint(L"ERROR: Unable to read PE/COFF image file\n");
XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->FreePool(ImageData);
XtLdrProtocol->Debug.Print(L"ERROR: Unable to read PE/COFF image file\n");
XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->Memory.FreePool(ImageData);
return Status;
}
@@ -235,9 +238,9 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if(Status != STATUS_EFI_SUCCESS)
{
/* Header validation failed, probably broken or invalid PE/COFF image */
XtLdrProtocol->DbgPrint(L"ERROR: Invalid PE/COFF image headers\n");
XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->FreePool(ImageData);
XtLdrProtocol->Debug.Print(L"ERROR: Invalid PE/COFF image headers\n");
XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->Memory.FreePool(ImageData);
return Status;
}
@@ -245,9 +248,9 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
if (!(ImageData->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_EXECUTABLE_IMAGE))
{
/* Loaded image is not executable */
XtLdrProtocol->DbgPrint(L"ERROR: Non-executable PE/COFF image loaded\n");
XtLdrProtocol->FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->FreePool(ImageData);
XtLdrProtocol->Debug.Print(L"ERROR: Non-executable PE/COFF image loaded\n");
XtLdrProtocol->Memory.FreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data);
XtLdrProtocol->Memory.FreePool(ImageData);
return STATUS_EFI_LOAD_ERROR;
}
@@ -256,12 +259,12 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
ImageData->ImagePages = EFI_SIZE_TO_PAGES(ImageData->ImageSize);
/* Allocate image pages */
Status = XtLdrProtocol->AllocatePages(ImageData->ImagePages, &Address);
Status = XtLdrProtocol->Memory.AllocatePages(ImageData->ImagePages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Pages reallocation failure */
XtLdrProtocol->DbgPrint(L"ERROR: Pages reallocation failure\n");
XtLdrProtocol->FreePool(ImageData);
XtLdrProtocol->Debug.Print(L"ERROR: Pages reallocation failure\n");
XtLdrProtocol->Memory.FreePool(ImageData);
return Status;
}
@@ -319,19 +322,19 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
}
/* Free pages */
XtLdrProtocol->FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages);
XtLdrProtocol->Memory.FreePages((EFI_PHYSICAL_ADDRESS)(UINT_PTR)Data, Pages);
/* Perform relocation fixups */
Status = PepRelocateLoadedImage(ImageData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to relocate image */
XtLdrProtocol->DbgPrint(L"ERROR: PE/COFF image relocation failed\n");
XtLdrProtocol->Debug.Print(L"ERROR: PE/COFF image relocation failed\n");
return Status;
}
/* Store image data */
*Image = ImageData;
*ImagePointer = ImageData;
/* Return SUCCESS */
return STATUS_EFI_SUCCESS;
@@ -352,9 +355,11 @@ PeLoadImage(IN PEFI_FILE_HANDLE FileHandle,
*/
XTCDECL
EFI_STATUS
PeRelocateImage(IN PPECOFF_IMAGE_CONTEXT Image,
PeRelocateImage(IN PVOID ImagePointer,
IN EFI_VIRTUAL_ADDRESS Address)
{
PPECOFF_IMAGE_CONTEXT Image = ImagePointer;
UINT64 ImageBase, OldVirtualAddress;
EFI_STATUS Status;
@@ -416,7 +421,7 @@ PepRelocateLoadedImage(IN PPECOFF_IMAGE_CONTEXT Image)
if(Image->PeHeader->FileHeader.Characteristics & PECOFF_IMAGE_FILE_RELOCS_STRIPPED)
{
/* No relocation information found */
XtLdrProtocol->DbgPrint(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n");
XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image is stripped and contains no information about relocations\n");
return STATUS_EFI_SUCCESS;
}
@@ -531,21 +536,21 @@ PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader,
/* Validate file size */
if(FileSize < sizeof(PECOFF_IMAGE_DOS_HEADER))
{
XtLdrProtocol->DbgPrint(L"WARNING: PE/COFF image shorter than DOS header\n");
XtLdrProtocol->Debug.Print(L"WARNING: PE/COFF image shorter than DOS header\n");
return STATUS_EFI_END_OF_FILE;
}
/* Validate DOS header */
if(DosHeader->e_magic != PECOFF_IMAGE_DOS_SIGNATURE)
{
XtLdrProtocol->DbgPrint(L"WARNING: Invalid DOS signature found\n");
XtLdrProtocol->Debug.Print(L"WARNING: Invalid DOS signature found\n");
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
/* Validate PE header */
if(PeHeader->Signature != PECOFF_IMAGE_NT_SIGNATURE && PeHeader->Signature != PECOFF_IMAGE_XT_SIGNATURE)
{
XtLdrProtocol->DbgPrint(L"WARNING: Invalid NT/XT signature found\n");
XtLdrProtocol->Debug.Print(L"WARNING: Invalid NT/XT signature found\n");
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
@@ -553,7 +558,7 @@ PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader,
if(PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR32_MAGIC &&
PeHeader->OptionalHeader.Magic != PECOFF_IMAGE_PE_OPTIONAL_HDR64_MAGIC)
{
XtLdrProtocol->DbgPrint(L"WARNING: Invalid optional header signature found\n");
XtLdrProtocol->Debug.Print(L"WARNING: Invalid optional header signature found\n");
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
@@ -576,19 +581,14 @@ PepValidateImageHeaders(IN PPECOFF_IMAGE_DOS_HEADER DosHeader,
*/
XTCDECL
EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
/* Set the system table and image handle */
EfiImageHandle = ImageHandle;
EfiSystemTable = SystemTable;
/* Open the XTLDR protocol */
Status = BlGetXtLoaderProtocol(&XtLdrProtocol);
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
@@ -599,10 +599,9 @@ BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
XtPeCoffProtocol.GetEntryPoint = PeGetEntryPoint;
XtPeCoffProtocol.GetMachineType = PeGetMachineType;
XtPeCoffProtocol.GetSubSystem = PeGetSubSystem;
XtPeCoffProtocol.Load = PeLoadImage;
XtPeCoffProtocol.Relocate = PeRelocateImage;
XtPeCoffProtocol.LoadImage = PeLoadImage;
XtPeCoffProtocol.RelocateImage = PeRelocateImage;
/* Register PE/COFF protocol */
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE,
&XtPeCoffProtocol);
return XtLdrProtocol->Protocol.Install(&XtPeCoffProtocol, &Guid);
}

View File

@@ -1,27 +0,0 @@
# XT Boot Loader
PROJECT(XTLDR_XTOS)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_SOURCE_DIR}/includes
${XTLDR_XTOS_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_XTOS_SOURCE
${XTLDR_SOURCE_DIR}/blproto.c
${XTLDR_XTOS_SOURCE_DIR}/xtos.c)
# Link bootloader executable
add_executable(xtos ${XTLDR_XTOS_SOURCE})
# Add linker libraries
target_link_libraries(xtos libxtos)
# Set proper binary name and install target
set_target_properties(xtos PROPERTIES SUFFIX .efi)
set_install_target(xtos efi/boot/xtldr)
# Set module entrypoint and subsystem
set_entrypoint(xtos "BlXtLdrModuleMain")
set_subsystem(xtos efi_boot_service_driver)

View File

@@ -1,54 +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 <blmod.h>
/* EFI XT Loader Protocol */
EXTERN PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* XTOS boot protocol related routines forward references */
XTCDECL
EFI_STATUS
XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters);
XTCDECL
EFI_STATUS
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters);
XTCDECL
EFI_STATUS
XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings);
XTCDECL
EFI_STATUS
XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
IN PVOID *VirtualAddress);
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
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif /* __XTLDR_MODULES_XTOS_H */

View File

@@ -0,0 +1,28 @@
# XT Boot Loader
PROJECT(XTLDR_XTOS_O)
# Specify include directories
include_directories(
${EXECTOS_SOURCE_DIR}/sdk/xtdk
${XTLDR_XTOS_O_SOURCE_DIR}/includes)
# Specify list of source code files
list(APPEND XTLDR_XTOS_O_SOURCE
${XTLDR_XTOS_O_SOURCE_DIR}/${ARCH}/memory.c
${XTLDR_XTOS_O_SOURCE_DIR}/memory.c
${XTLDR_XTOS_O_SOURCE_DIR}/xtos.c)
# Link bootloader executable
add_executable(xtos_o ${XTLDR_XTOS_O_SOURCE})
# Add linker libraries
target_link_libraries(xtos_o libxtos libxtldr)
# Set proper binary name and install target
set_target_properties(xtos_o PROPERTIES SUFFIX .efi)
set_install_target(xtos_o efi/boot/xtldr/modules)
# Set module entrypoint and subsystem
set_entrypoint(xtos_o "XtLdrModuleMain")
set_linker_map(xtos_o TRUE)
set_subsystem(xtos_o efi_boot_service_driver)

View File

@@ -0,0 +1,336 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/amd64/memory.c
* DESCRIPTION: EFI memory management for AMD64 target
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param VirtualAddress
* Supplies a pointer to the next valid, free and available virtual address.
*
* @param ImageProtocol
* A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed.
*
* @param PtePointer
* Supplies a pointer to memory area containing a Page Table Entries (PTE).
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
IN PVOID *PtePointer)
{
PLOADER_MEMORY_MAPPING Mapping;
EFI_PHYSICAL_ADDRESS Address;
PEFI_MEMORY_MAP MemoryMap;
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
EFI_STATUS Status;
/* Allocate pages for PML4 */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Assign and zero-fill memory used by page mappings */
*PtePointer = (PVOID)(UINT_PTR)Address;
RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE);
/* Get list of XTLDR modules */
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
Status = XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Map XTLDR code */
XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
/* Add page mapping itself to memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping PML4 failed */
return Status;
}
/* Iterate through and map all the mappings*/
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
ListEntry = MemoryMappings->Flink;
while(ListEntry != MemoryMappings)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Map zero page as well */
XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
/* Allocate and zero-fill buffer for EFI memory map */
XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map and prepare for exiting boot services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
return Status;
}
/* Exit EFI Boot Services */
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
/* Check if exitted boot services successfully */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
return Status;
}
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
}
/* Check if exitted boot services successfully */
if(Status != STATUS_EFI_SUCCESS)
{
XtLdrProtocol->Console.Print(L"Failed to exit boot services (Status code: %lx)\n", Status);
return STATUS_EFI_ABORTED;
}
/* Write PML4 to CR3 */
ArWriteControlRegister(3, (UINT_PTR)*PtePointer);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine does the actual virtual memory mapping.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @param PaeExtension
* Specifies whether Physical Address Extension (PAE) is supported by the hardware. Not used on AMD64.
*
* @param PtePointer
* Supplies a pointer to an array of pointers to page table entries.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
IN UINT_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress,
IN UINT NumberOfPages,
IN OUT PVOID *PtePointer)
{
PHARDWARE_PTE PageDirectoryPointTable, PageDirectory, PageTable;
UINT Pml4Index, PdpIndex, PdIndex, PtIndex;
EFI_PHYSICAL_ADDRESS Address;
UINT_PTR PageFrameNumber;
EFI_STATUS Status;
UINT64 Pointer;
/* Set the PFN */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Calculate indices from a virtual address */
Pml4Index = (VirtualAddress >> 39) & 0x1FF;
PdpIndex = (VirtualAddress >> 30) & 0x1FF;
PdIndex = (VirtualAddress >> 21) & 0x1FF;
PtIndex = (VirtualAddress >> 12) & 0x1FF;
/* Validate Page Map Level 4 (PML4) */
if(!((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid)
{
/* Allocate pages for the PDPT */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid = 1;
((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Write = 1;
PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Directory Point Table (PDPT) */
Pointer = ((PHARDWARE_PTE)(*PtePointer))[Pml4Index].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageDirectoryPointTable = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Validate Page Directory Point Table (PDPT)*/
if(!PageDirectoryPointTable[PdpIndex].Valid)
{
/* Allocate pages for the PD */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageDirectoryPointTable[PdpIndex].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageDirectoryPointTable[PdpIndex].Valid = 1;
PageDirectoryPointTable[PdpIndex].Write = 1;
PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Directory (PD) */
Pointer = PageDirectoryPointTable[PdpIndex].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageDirectory = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Validate Page Directory (PD)*/
if(!PageDirectory[PdIndex].Valid)
{
/* Allocate pages for the PT */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Add new memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
if (Status != STATUS_EFI_SUCCESS) {
/* Memory mapping failed */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageDirectory[PdIndex].Valid = 1;
PageDirectory[PdIndex].Write = 1;
PageTable = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Find Page Table (PT) */
Pointer = PageDirectory[PdIndex].PageFrameNumber;
Pointer <<= EFI_PAGE_SHIFT;
PageTable = (PHARDWARE_PTE)(UINT_PTR)Pointer;
}
/* Set paging entry settings */
PageTable[PtIndex].PageFrameNumber = PageFrameNumber;
PageTable[PtIndex].Valid = 1;
PageTable[PtIndex].Write = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -0,0 +1,361 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/i686/memory.c
* DESCRIPTION: EFI memory management for i686 target
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Builds the actual memory mapping page table and enables paging. This routine exits EFI boot services as well.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param VirtualAddress
* Supplies a pointer to the next valid, free and available virtual address.
*
* @param ImageProtocol
* A pointer to the EFI loaded image protocol with information about where in memory the loader code was placed.
*
* @param PtePointer
* Supplies a pointer to memory area containing a Page Table Entries (PTE).
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
IN PVOID *PtePointer)
{
UINT_PTR PhysicalAddress, DescriptorCount;
EFI_PHYSICAL_ADDRESS Address, PDPTAddress = 0;
PCPUID_REGISTERS CpuRegisters = NULL;
PEFI_MEMORY_DESCRIPTOR Descriptor;
PLOADER_MEMORY_MAPPING Mapping;
PEFI_MEMORY_MAP MemoryMap;
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
PXTBL_MODULE_INFO ModuleInfo;
EFI_STATUS Status;
UINT Index;
/* Prepare CPUID registers */
CpuRegisters->Leaf = CPUID_GET_CPU_FEATURES;
CpuRegisters->SubLeaf = 0;
CpuRegisters->Eax = 0;
CpuRegisters->Ebx = 0;
CpuRegisters->Ecx = 0;
CpuRegisters->Edx = 0;
/* Get CPUID */
ArCpuId(CpuRegisters);
/* Store PAE status from the CPUID results */
if(!(CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE))
{
/* No PAE support */
XtLdrProtocol->Debug.Print(L"ERROR: PAE extension not supported by the CPU\n");
return STATUS_EFI_UNSUPPORTED;
}
/* Allocate and zero-fill buffer for EFI memory map */
XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map */
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
return Status;
}
/* Calculate descriptors count and get first one */
Descriptor = MemoryMap->Map;
DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize;
/* Calculate physical address based on KSEG0 base */
PhysicalAddress = (UINT_PTR)VirtualAddress - KSEG0_BASE;
/* Iterate over all descriptors from memory map to find satisfying address for PDPT */
for(Index = 0; Index < DescriptorCount; Index++)
{
/* Check descriptor if it can be used to store PDPT */
if((Descriptor->PhysicalStart + ((Descriptor->NumberOfPages - 1) * EFI_PAGE_SIZE) >= PhysicalAddress) &&
(Descriptor->Type == EfiConventionalMemory))
{
/* Use highest address possible */
if(PhysicalAddress >= Descriptor->PhysicalStart)
{
/* Use physical address */
PDPTAddress = PhysicalAddress;
}
else
{
/* Use descriptor physical start as PDPT address */
PDPTAddress = Descriptor->PhysicalStart;
}
/* Allocate pages for the PDPT address */
Status = XtLdrProtocol->Memory.AllocatePages(1, &PDPTAddress);
if(Status != STATUS_EFI_SUCCESS) {
return Status;
}
break;
}
/* Get next descriptor */
Descriptor = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)Descriptor + MemoryMap->DescriptorSize);
}
/* Make sure PDPT address found */
if(PDPTAddress == 0)
{
/* No suitable area for PDPT found in EFI memory map */
return STATUS_EFI_NOT_FOUND;
}
/* Set virtual address based on new PDPT address mapped to KSEG0 base */
VirtualAddress = (PVOID)(UINT_PTR)(PDPTAddress + EFI_PAGE_SIZE + KSEG0_BASE);
/* Set base page frame number */
Address = 0x100000;
/* Allocate pages for the PFN */
Status = XtLdrProtocol->Memory.AllocatePages(4, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Set and zero memory used by page mappings and CR3 */
*PtePointer = (PVOID)(UINT_PTR)PDPTAddress;
RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE);
RtlZeroMemory((PVOID)Address, EFI_PAGE_SIZE * 4);
/* Set the page directory into the PDPT and mark it present */
for(Index = 0; Index < 4; Index++)
{
/* Set paging entry settings */
((PHARDWARE_PTE)*PtePointer)[Index].PageFrameNumber = Address / EFI_PAGE_SIZE;
((PHARDWARE_PTE)*PtePointer)[Index].Valid = 1;
/* Next valid PFN address */
Address += EFI_PAGE_SIZE;
}
/* Get list of XTLDR modules */
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
ModulesListEntry = ModulesList->Flink;
while(ModulesListEntry != ModulesList)
{
/* Get module info */
ModuleInfo = CONTAIN_RECORD(ModulesListEntry, XTBL_MODULE_INFO, Flink);
/* Map module code */
XtAddVirtualMemoryMapping(MemoryMappings, ModuleInfo->ModuleBase, ModuleInfo->ModuleBase,
EFI_SIZE_TO_PAGES(ModuleInfo->ModuleSize), LoaderFirmwareTemporary);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping module code failed */
return Status;
}
/* Get next module */
ModulesListEntry = ModulesListEntry->Flink;
}
/* Map XTLDR code */
XtAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
/* Add page mapping itself to memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping PD failed */
return Status;
}
/* Iterate through and map all the mappings */
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
ListEntry = MemoryMappings->Flink;
while(ListEntry != MemoryMappings)
{
/* Take mapping from the list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Check if virtual address is set */
if(Mapping->VirtualAddress)
{
/* Dump memory mapping */
XtLdrProtocol->Debug.Print(L" Type=%02lu, PhysicalBase=0x%08lx, VirtualBase=0x%08lx, Pages=%lu\n", Mapping->MemoryType,
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
/* Map memory */
Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory mapping failed */
return Status;
}
}
/* Take next element */
ListEntry = ListEntry->Flink;
}
/* Map zero page as well */
XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
/* Zero-fill buffer for EFI memory map */
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map and prepare for exiting boot services */
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
return Status;
}
/* Exit EFI Boot Services */
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
/* Check if exitted boot services successfully */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to get memory map */
return Status;
}
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
}
/* Check if exitted boot services successfully */
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to exit boot services */
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %lx)\n", Status);
return STATUS_EFI_ABORTED;
}
/* Enable Physical Address Extension (PAE) */
ArWriteControlRegister(4, ArReadControlRegister(4) | CR4_PAE);
/* Write page mappings to CR3 */
ArWriteControlRegister(3, (UINT_PTR)*PtePointer);
/* Enable paging */
ArWriteControlRegister(0, ArReadControlRegister(0) | CR0_PG);
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine does the actual virtual memory mapping.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param VirtualAddress
* Supplies a virtual address of the mapping.
*
* @param PhysicalAddress
* Supplies a physical address of the mapping.
*
* @param NumberOfPages
* Supplies a number of the pages of the mapping.
*
* @param PaeExtension
* Specifies whether Physical Address Extension (PAE) is supported by the hardware.
*
* @param PtePointer
* Supplies a pointer to an array of pointers to page table entries.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
IN UINT_PTR VirtualAddress,
IN UINT_PTR PhysicalAddress,
IN UINT NumberOfPages,
IN OUT PVOID *PtePointer)
{
EFI_PHYSICAL_ADDRESS Address;
UINT_PTR PageFrameNumber;
PHARDWARE_PTE PageTable, PageDirectory;
EFI_STATUS Status;
unsigned int PdIndex, PtIndex;
/* Set the PFN */
PageFrameNumber = PhysicalAddress >> EFI_PAGE_SHIFT;
/* Do the recursive mapping */
while(NumberOfPages > 0)
{
/* Find Page Directory and calculate indices from a virtual address */
PageDirectory = (PHARDWARE_PTE)(UINT_PTR)(((PHARDWARE_PTE)(*PtePointer))[VirtualAddress >> 30].PageFrameNumber * EFI_PAGE_SIZE);
PdIndex = (VirtualAddress >> 21) & 0x1FF;
PtIndex = (VirtualAddress & 0x1FF000) >> 12;
/* Validate Page Directory */
if(!PageDirectory[PdIndex].Valid) {
/* Allocate pages for new page table */
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
if(Status != STATUS_EFI_SUCCESS) {
/* Memory allocation failure */
return Status;
}
/* Fill allocated memory with zeros */
RtlZeroMemory((PVOID)(UINT_PTR)Address, EFI_PAGE_SIZE);
/* Set paging entry settings */
PageDirectory[PdIndex].PageFrameNumber = Address / EFI_PAGE_SIZE;
PageDirectory[PdIndex].Valid = 1;
PageDirectory[PdIndex].Write = 1;
/* Set page table */
PageTable = (PHARDWARE_PTE)(UINT_PTR)Address;
}
else
{
/* Set page table */
PageTable = (PHARDWARE_PTE)(UINT_PTR)(PageDirectory[PdIndex].PageFrameNumber * EFI_PAGE_SIZE);
}
/* Set page table settings */
PageTable[PtIndex].PageFrameNumber = PageFrameNumber;
PageTable[PtIndex].Valid = 1;
PageTable[PtIndex].Write = 1;
/* Take next virtual address and PFN */
VirtualAddress += EFI_PAGE_SIZE;
PageFrameNumber++;
/* Decrease number of pages left */
NumberOfPages--;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}

View File

@@ -0,0 +1,107 @@
/**
* 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 kernel entry point */
typedef VOID (XTAPI *PXT_ENTRY_POINT)(IN PKERNEL_INITIALIZATION_BLOCK BootParameters);
/* 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
EFI_STATUS
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
IN PVOID VirtualAddress,
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
IN PVOID *PtePointer);
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 PLIST_ENTRY MemoryMappings);
XTCDECL
EFI_STATUS
XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
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
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
#endif /* __XTLDR_MODULES_XTOS_H */

View File

@@ -0,0 +1,385 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/memory.c
* DESCRIPTION: EFI memory management
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.h>
/**
* Adds a physical to virtual address mapping to the linked list for future processing.
*
* @param MemoryMapping
* Supplies the head of the memory mapping list.
*
* @param VirtualAddress
* Supplies a virtual address where the physical address should be mapped.
*
* @param PhysicalAddress
* Supplies a physical address which will be mapped.
*
* @param NumberOfPages
* Supplies a number of pages which will be mapped.
*
* @param MemoryType
* Supplies the type of memory that will be assigned to the memory descriptor.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
IN PVOID VirtualAddress,
IN PVOID PhysicalAddress,
IN UINT NumberOfPages,
IN LOADER_MEMORY_TYPE MemoryType)
{
PLOADER_MEMORY_MAPPING Mapping1, Mapping2, Mapping3;
PVOID PhysicalAddressEnd, PhysicalAddress2End;
PLIST_ENTRY ListEntry, MappingListEntry;
SIZE_T NumberOfMappedPages;
EFI_STATUS Status;
/* Allocate memory for new mapping */
Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID *)&Mapping1);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Set mapping fields */
Mapping1->PhysicalAddress = PhysicalAddress;
Mapping1->VirtualAddress = VirtualAddress;
Mapping1->NumberOfPages = NumberOfPages;
Mapping1->MemoryType = MemoryType;
/* Calculate the end of the physical address */
PhysicalAddressEnd = (PUINT8)PhysicalAddress + (NumberOfPages * EFI_PAGE_SIZE) - 1;
/* Iterate through all the mappings already set to insert new mapping at the correct place */
ListEntry = MemoryMappings->Flink;
while(ListEntry != MemoryMappings)
{
/* Take a mapping from the list and calculate its end of physical address */
Mapping2 = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1 ;
/* Check if they overlap */
if(PhysicalAddressEnd > Mapping2->PhysicalAddress && PhysicalAddressEnd <= PhysicalAddress2End)
{
/* Make sure it's memory type is LoaderFree */
if(Mapping2->MemoryType != LoaderFree)
{
/* LoaderFree memory type is strictly expected */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Calculate number of pages for this mapping */
NumberOfMappedPages = ((PUINT8)PhysicalAddress2End - (PUINT8)PhysicalAddressEnd) / EFI_PAGE_SIZE;
if(NumberOfMappedPages > 0)
{
/* Pages associated to the mapping, allocate memory for it */
Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = (PUINT8)PhysicalAddressEnd + 1;
Mapping3->VirtualAddress = NULL;
Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType;
RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
}
/* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUINT8)PhysicalAddressEnd + 1 -
(PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
}
/* Check if they overlap */
if(Mapping1->PhysicalAddress > Mapping2->PhysicalAddress && Mapping1->PhysicalAddress < PhysicalAddress2End)
{
/* Make sure it's memory type is LoaderFree */
if(Mapping2->MemoryType != LoaderFree)
{
/* LoaderFree memory type is strictly expected */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Calculate number of pages for this mapping */
NumberOfMappedPages = ((PUINT8)PhysicalAddress2End + 1 - (PUINT8)Mapping1->PhysicalAddress) / EFI_PAGE_SIZE;
if(NumberOfMappedPages > 0)
{
/* Pages associated to the mapping, allocate memory for it */
Status = XtLdrProtocol->Memory.AllocatePool(sizeof(LOADER_MEMORY_MAPPING), (PVOID*)&Mapping3);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
return Status;
}
/* Set mapping fields and insert it on the top */
Mapping3->PhysicalAddress = Mapping1->PhysicalAddress;
Mapping3->VirtualAddress = NULL;
Mapping3->NumberOfPages = NumberOfMappedPages;
Mapping3->MemoryType = Mapping2->MemoryType;
RtlInsertHeadList(&Mapping2->ListEntry, &Mapping3->ListEntry);
}
/* Calculate number of pages and the end of the physical address */
Mapping2->NumberOfPages = ((PUINT8)Mapping1->PhysicalAddress -
(PUINT8)Mapping2->PhysicalAddress) / EFI_PAGE_SIZE;
PhysicalAddress2End = (PUINT8)Mapping2->PhysicalAddress + (Mapping2->NumberOfPages * EFI_PAGE_SIZE) - 1;
}
/* Check if mapping is really needed */
if((Mapping2->PhysicalAddress >= Mapping1->PhysicalAddress && PhysicalAddress2End <= PhysicalAddressEnd) ||
(Mapping2->NumberOfPages == 0))
{
/* Make sure it's memory type is LoaderFree */
if(Mapping2->MemoryType != LoaderFree)
{
/* LoaderFree memory type is strictly expected */
return STATUS_EFI_INVALID_PARAMETER;
}
/* Store address of the next mapping */
MappingListEntry = ListEntry->Flink;
/* Remove mapping from the list and free up it's memory */
RtlRemoveEntryList(&Mapping2->ListEntry);
Status = XtLdrProtocol->Memory.FreePool(Mapping2);
ListEntry = MappingListEntry;
/* Go to the next mapping */
continue;
}
/* Determine phsical address order */
if(Mapping2->PhysicalAddress > Mapping1->PhysicalAddress)
{
/* Insert new mapping in front */
RtlInsertHeadList(Mapping2->ListEntry.Blink, &Mapping1->ListEntry);
return STATUS_EFI_SUCCESS;
}
/* Get next mapping from the list */
ListEntry = ListEntry->Flink;
}
/* Insert new mapping to the end of the list and return success */
RtlInsertTailList(MemoryMappings, &Mapping1->ListEntry);
return STATUS_EFI_SUCCESS;
}
/**
* Converts an EFI memory type into an XTOS memory type.
*
* @param EfiMemoryType
* Supplies the EFI memory type.
*
* @return Returns a conversion of the memory type.
*
* @since XT 1.0
*/
XTCDECL
LOADER_MEMORY_TYPE
XtConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType)
{
LOADER_MEMORY_TYPE MemoryType;
/* Check EFI memory type and convert to XTOS memory type */
switch(EfiMemoryType)
{
case EfiACPIMemoryNVS:
case EfiACPIReclaimMemory:
case EfiPalCode:
MemoryType = LoaderSpecialMemory;
break;
case EfiRuntimeServicesCode:
case EfiRuntimeServicesData:
case EfiMemoryMappedIO:
case EfiMemoryMappedIOPortSpace:
MemoryType = LoaderFirmwarePermanent;
break;
case EfiBootServicesData:
case EfiLoaderCode:
case EfiLoaderData:
MemoryType = LoaderFirmwareTemporary;
break;
case EfiUnusableMemory:
MemoryType = LoaderBad;
break;
default:
MemoryType = LoaderFree;
break;
}
/* Return XTOS memory type */
return MemoryType;
}
/**
* Attempts to find a virtual address of the specified physical address in memory mappings.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param PhysicalAddress
* Supplies a physical address to search for in the mappings.
*
* @param VirtualAddress
* Supplies a buffer, where mapped virtual address of the found mapping will be stored.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtGetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
IN PVOID PhysicalAddress,
OUT PVOID *VirtualAddress)
{
PLOADER_MEMORY_MAPPING Mapping;
PLIST_ENTRY ListEntry;
/* NULLify virtual address */
*VirtualAddress = NULL;
/* Iterate over memory mappings in order to find descriptor containing a physical address */
ListEntry = MemoryMappings->Flink;
while(ListEntry != MemoryMappings)
{
/* Get mapping from linked list */
Mapping = CONTAIN_RECORD(ListEntry, LOADER_MEMORY_MAPPING, ListEntry);
/* Make sure any virtual address is set */
if(Mapping->VirtualAddress)
{
/* Check if provided physical address is in range of this mapping */
if((PhysicalAddress >= Mapping->PhysicalAddress) &&
(PhysicalAddress < Mapping->PhysicalAddress + (Mapping->NumberOfPages * EFI_PAGE_SIZE)))
{
/* Calculate virtual address based on the mapping */
*VirtualAddress = PhysicalAddress - Mapping->PhysicalAddress + Mapping->VirtualAddress;
}
}
/* Get next element from the list */
ListEntry = ListEntry->Flink;
}
/* If virtual address is still NULL, then mapping was not found */
if(*VirtualAddress == NULL)
{
/* Mapping not found */
return STATUS_EFI_NOT_FOUND;
}
/* Mapping found, return success */
return STATUS_EFI_SUCCESS;
}
/**
* Initializes virtual memory by adding known and general mappings.
*
* @param MemoryMappings
* Supplies a pointer to linked list containing all memory mappings.
*
* @param MemoryMapAddress
* Supplies an address of the mapped virtual memory area.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
XtInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
IN OUT PVOID *MemoryMapAddress)
{
PEFI_MEMORY_DESCRIPTOR Descriptor;
LOADER_MEMORY_TYPE MemoryType;
PEFI_MEMORY_MAP MemoryMap;
SIZE_T DescriptorCount;
PUCHAR VirtualAddress;
EFI_STATUS Status;
SIZE_T Index;
/* Set initial virtual address */
VirtualAddress = *MemoryMapAddress;
/* Allocate and zero-fill buffer for EFI memory map */
XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
/* Get EFI memory map */
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
if(Status != STATUS_EFI_SUCCESS)
{
return Status;
}
/* Calculate descriptors count and get first one */
Descriptor = MemoryMap->Map;
DescriptorCount = MemoryMap->MapSize / MemoryMap->DescriptorSize;
/* Iterate through all descriptors from the memory map */
for(Index = 0; Index < DescriptorCount; Index++)
{
/* Make sure descriptor does not go beyond lowest physical page */
if((Descriptor->PhysicalStart + (Descriptor->NumberOfPages * EFI_PAGE_SIZE)) <= (UINT_PTR)-1)
{
/* Convert EFI memory type into XTOS memory type */
MemoryType = XtConvertEfiMemoryType(Descriptor->Type);
/* Do memory mappings depending on memory type */
if(MemoryType == LoaderFirmwareTemporary)
{
/* Map EFI firmware code */
Status = XtAddVirtualMemoryMapping(MemoryMappings, (PVOID)Descriptor->PhysicalStart,
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
}
else if(MemoryType != LoaderFree)
{
/* Add any non-free memory mapping */
Status = XtAddVirtualMemoryMapping(MemoryMappings, VirtualAddress, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, MemoryType);
/* Calculate next valid virtual address */
VirtualAddress += Descriptor->NumberOfPages * EFI_PAGE_SIZE;
}
else
{
/* Map all other memory as loader free */
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)Descriptor->PhysicalStart,
Descriptor->NumberOfPages, LoaderFree);
}
/* Make sure memory mapping succeeded */
if(Status != STATUS_EFI_SUCCESS)
{
/* Mapping failed */
return Status;
}
/* Grab next descriptor */
Descriptor = (PEFI_MEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryMap->DescriptorSize);
}
}
/* Store next valid virtual address and return success */
*MemoryMapAddress = VirtualAddress;
return STATUS_EFI_SUCCESS;
}

View File

@@ -9,20 +9,18 @@
#include <xtos.h>
/* EFI Image Handle */
EFI_HANDLE EfiImageHandle;
/* EFI System Table */
PEFI_SYSTEM_TABLE EfiSystemTable;
/* XTOS module information */
XTBL_MODINFO = L"XTOS boot protocol support";
XTBL_MODDEPS = {L"fb_o", L"pecoff_o"};
/* EFI XT Loader Protocol */
PXT_BOOT_LOADER_PROTOCOL XtLdrProtocol;
PXTBL_LOADER_PROTOCOL XtLdrProtocol;
/* XTOS PE/COFF Image Protocol */
PXT_PECOFF_IMAGE_PROTOCOL XtPeCoffProtocol;
PXTBL_EXECUTABLE_IMAGE_PROTOCOL XtPeCoffProtocol;
/* XTOS Boot Protocol */
XT_BOOT_PROTOCOL XtBootProtocol;
XTBL_BOOT_PROTOCOL XtBootProtocol;
/* XTOS Page Map */
PVOID XtPageMap;
@@ -39,23 +37,23 @@ PVOID XtPageMap;
*/
XTCDECL
EFI_STATUS
XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
XtBootSystem(IN PXTBL_BOOT_PARAMETERS Parameters)
{
EFI_GUID PeCoffProtocolGuid = XT_PECOFF_IMAGE_PROTOCOL_GUID;
EFI_HANDLE DiskHandle;
EFI_HANDLE DiskHandle, ProtocolHandle;
PEFI_FILE_HANDLE FsHandle, BootDir;
PWCHAR SystemPath;
EFI_STATUS Status;
/* Print debug message */
XtLdrProtocol->DbgPrint(L"XTOS boot protocol activated\n");
XtLdrProtocol->Debug.Print(L"XTOS boot protocol activated\n");
/* Open the XT PE/COFF protocol */
Status = BlLoadXtProtocol((PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid);
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID *)&XtPeCoffProtocol, &PeCoffProtocolGuid);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
XtLdrProtocol->DbgPrint(L"ERROR: Unable to load PE/COFF image protocol\n");
XtLdrProtocol->Debug.Print(L"ERROR: Unable to load PE/COFF image protocol\n");
return STATUS_EFI_PROTOCOL_ERROR;
}
@@ -63,7 +61,7 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
if(Parameters->DevicePath == NULL)
{
/* No device path set */
XtLdrProtocol->DbgPrint(L"ERROR: No device path provided, unable to boot system\n");
XtLdrProtocol->Debug.Print(L"ERROR: No device path provided, unable to boot system\n");
return STATUS_EFI_INVALID_PARAMETER;
}
@@ -85,7 +83,7 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
if(((*SystemPath | 32) - 'a' >= 26) && ((*SystemPath - '0') >= 10))
{
/* Invalid path specified */
XtLdrProtocol->DbgPrint(L"ERROR: System path does not point to the valid XTOS installation\n");
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 */
@@ -95,7 +93,7 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
else
{
/* Fallback to '/ExectOS' by default */
XtLdrProtocol->DbgPrint(L"WARNING: No system path set, falling back to defaults\n");
XtLdrProtocol->Debug.Print(L"WARNING: No system path set, falling back to defaults\n");
Parameters->SystemPath = L"\\ExectOS";
}
@@ -103,31 +101,31 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
if(Parameters->KernelFile == NULL)
{
/* No kernel filename set, fallback to default */
XtLdrProtocol->DbgPrint(L"WARNING: No kernel file specified, falling back to defaults\n");
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->Arguments == NULL)
if(Parameters->Parameters == NULL)
{
/* No argument supplied */
Parameters->Arguments = L"";
Parameters->Parameters = L"";
}
/* Print a debug message */
XtLdrProtocol->DbgPrint(L"[XTOS] ARC Path: %S\n"
L"[XTOS] System Path: %S\n"
L"[XTOS] Kernel File: %S\n"
L"[XTOS] Boot Arguments: %S\n",
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->Arguments);
Parameters->KernelFile, Parameters->Parameters);
/* Open EFI volume */
Status = XtLdrProtocol->OpenVolume(NULL, &DiskHandle, &FsHandle);
Status = XtLdrProtocol->Disk.OpenVolume(NULL, &DiskHandle, &FsHandle);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open a volume */
XtLdrProtocol->DbgPrint(L"ERROR: Unable to open boot volume\n");
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open boot volume\n");
return Status;
}
@@ -142,17 +140,17 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
if(Status == STATUS_EFI_NOT_FOUND)
{
/* Directory not found, nothing to load */
XtLdrProtocol->DbgPrint(L"ERROR: System boot directory not found\n");
XtLdrProtocol->Debug.Print(L"ERROR: System boot directory not found\n");
/* Close volume */
XtLdrProtocol->CloseVolume(DiskHandle);
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
return Status;
}
else if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open directory */
XtLdrProtocol->DbgPrint(L"ERROR: Unable to open system boot directory\n");
XtLdrProtocol->CloseVolume(DiskHandle);
XtLdrProtocol->Debug.Print(L"ERROR: Unable to open system boot directory\n");
XtLdrProtocol->Disk.CloseVolume(DiskHandle);
return Status;
}
@@ -176,7 +174,7 @@ XtBootSystem(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
XTCDECL
EFI_STATUS
XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters)
IN PXTBL_BOOT_PARAMETERS Parameters)
{
EFI_GUID LoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
PKERNEL_INITIALIZATION_BLOCK KernelParameters;
@@ -185,10 +183,11 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
PVOID VirtualAddress, VirtualMemoryArea;
PXT_ENTRY_POINT KernelEntryPoint;
LIST_ENTRY MemoryMappings;
EFI_HANDLE ProtocolHandle;
EFI_STATUS Status;
/* Initialize XTOS startup sequence */
XtLdrProtocol->DbgPrint(L"Initializing XTOS startup sequence\n");
XtLdrProtocol->Debug.Print(L"Initializing XTOS startup sequence\n");
/* Set base virtual memory area for the kernel mappings */
VirtualMemoryArea = (PVOID)KSEG0_BASE;
@@ -198,7 +197,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
RtlInitializeListHead(&MemoryMappings);
/* Initialize virtual memory mappings */
Status = XtLdrProtocol->InitializeVirtualMemory(&MemoryMappings, &VirtualMemoryArea);
Status = XtInitializeVirtualMemory(&MemoryMappings, &VirtualMemoryArea);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to initialize virtual memory */
@@ -214,7 +213,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
}
/* Add kernel image memory mapping */
Status = XtLdrProtocol->AddVirtualMemoryMapping(&MemoryMappings, ImageContext->VirtualAddress,
Status = XtAddVirtualMemoryMapping(&MemoryMappings, ImageContext->VirtualAddress,
ImageContext->PhysicalAddress, ImageContext->ImagePages, 0);
if(Status != STATUS_EFI_SUCCESS)
{
@@ -228,11 +227,11 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
KernelParameters = (PKERNEL_INITIALIZATION_BLOCK)VirtualAddress;
/* Setup and map kernel initialization block */
Status = XtpInitializeLoaderBlock(&MemoryMappings, &VirtualAddress);
Status = XtpInitializeLoaderBlock(&MemoryMappings, &VirtualAddress, Parameters);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->DbgPrint(L"Failed to setup kernel initialization block (Status Code: %lx)\n", Status);
XtLdrProtocol->Debug.Print(L"Failed to setup kernel initialization block (Status Code: %lx)\n", Status);
return Status;
}
@@ -241,7 +240,7 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to setup kernel initialization block */
XtLdrProtocol->DbgPrint(L"Failed to initialize APIC (Status Code: %lx)\n", Status);
XtLdrProtocol->Debug.Print(L"Failed to initialize APIC (Status Code: %lx)\n", Status);
return Status;
}
@@ -252,17 +251,17 @@ XtpBootSequence(IN PEFI_FILE_HANDLE BootDir,
BootDir->Close(BootDir);
/* Enable paging */
EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LoadedImageGuid, (PVOID*)&ImageProtocol);
Status = XtLdrProtocol->EnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap);
XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&ImageProtocol, &LoadedImageGuid);
Status = XtEnablePaging(&MemoryMappings, VirtualAddress, ImageProtocol, &XtPageMap);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to enable paging */
XtLdrProtocol->DbgPrint(L"Failed to enable paging (Status Code: %lx)\n", Status);
XtLdrProtocol->Debug.Print(L"Failed to enable paging (Status Code: %lx)\n", Status);
return Status;
}
/* Call XTOS kernel */
XtLdrProtocol->DbgPrint(L"Booting the XTOS kernel\n");
XtLdrProtocol->Debug.Print(L"Booting the XTOS kernel\n");
KernelEntryPoint(KernelParameters);
/* Return success */
@@ -306,7 +305,7 @@ XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings)
ApicBaseAddress = (PVOID)((UINT_PTR)ArReadModelSpecificRegister(0x1B) & 0xFFFFF000);
/* Map APIC base address */
XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent);
XtAddVirtualMemoryMapping(MemoryMappings, (PVOID)APIC_BASE, ApicBaseAddress, 1, LoaderFirmwarePermanent);
return STATUS_EFI_SUCCESS;
}
@@ -326,21 +325,23 @@ XtpInitializeApicBase(IN PLIST_ENTRY MemoryMappings)
XTCDECL
EFI_STATUS
XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
IN PVOID *VirtualAddress)
IN PVOID *VirtualAddress,
IN PXTBL_BOOT_PARAMETERS Parameters)
{
EFI_GUID FrameBufGuid = XT_FRAMEBUFFER_PROTOCOL_GUID;
PXT_FRAMEBUFFER_PROTOCOL FrameBufProtocol;
PKERNEL_INITIALIZATION_BLOCK LoaderBlock;
EFI_PHYSICAL_ADDRESS Address;
PVOID RuntimeServices;
// PVOID RuntimeServices;
EFI_STATUS Status;
EFI_HANDLE ProtocolHandle;
UINT BlockPages, FrameBufferPages;
/* Calculate number of pages needed for initialization block */
BlockPages = EFI_SIZE_TO_PAGES(sizeof(KERNEL_INITIALIZATION_BLOCK));
/* Allocate memory for kernel initialization block */
Status = XtLdrProtocol->AllocatePages(BlockPages, &Address);
Status = XtLdrProtocol->Memory.AllocatePages(BlockPages, &Address);
if(Status != STATUS_EFI_SUCCESS)
{
/* Memory allocation failure */
@@ -357,15 +358,14 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
LoaderBlock->ProtocolVersion = BOOT_PROTOCOL_VERSION;
/* Set LoaderInformation block properties */
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->DbgPrint;
LoaderBlock->LoaderInformation.DbgPrint = XtLdrProtocol->Debug.Print;
/* Load FrameBuffer protocol */
Status = BlLoadXtProtocol((PVOID *)&FrameBufProtocol, &FrameBufGuid);
Status = XtLdrProtocol->Protocol.Open(&ProtocolHandle, (PVOID*)&FrameBufProtocol, &FrameBufGuid);
if(Status == STATUS_EFI_SUCCESS)
{
/* Make sure FrameBuffer is initialized */
FrameBufProtocol->Initialize();
FrameBufProtocol->PrintDisplayInformation();
/* Store information about FrameBuffer device */
FrameBufProtocol->GetDisplayInformation(&LoaderBlock->LoaderInformation.FrameBuffer);
@@ -377,23 +377,29 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
LoaderBlock->LoaderInformation.FrameBuffer.Protocol = NONE;
}
/* Close FrameBuffer protocol */
XtLdrProtocol->Protocol.Close(ProtocolHandle, &FrameBufGuid);
/* Attempt to find virtual address of the EFI Runtime Services */
Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
if(Status == STATUS_EFI_SUCCESS)
{
// Status = XtLdrProtocol->GetVirtualAddress(MemoryMappings, &EfiSystemTable->RuntimeServices->Hdr, &RuntimeServices);
// if(Status == STATUS_EFI_SUCCESS)
// {
/* Set FirmwareInformation block properties */
LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareEfi;
LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = EfiSystemTable->Hdr.Revision;
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = RuntimeServices;
}
else
{
/* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */
LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid;
}
LoaderBlock->FirmwareInformation.EfiFirmware.EfiVersion = 0; //EfiSystemTable->Hdr.Revision;
LoaderBlock->FirmwareInformation.EfiFirmware.EfiRuntimeServices = NULL;
// }
// else
// {
// /* Set invalid firmware type to indicate that kernel cannot rely on FirmwareInformation block */
// LoaderBlock->FirmwareInformation.FirmwareType = SystemFirmwareInvalid;
// }
/* Copy parameters to kernel initialization block */
RtlCopyMemory(&LoaderBlock->KernelParameters, Parameters->Parameters, RtlWideStringLength(Parameters->Parameters, 0));
/* Map kernel initialization block */
XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock,
XtAddVirtualMemoryMapping(MemoryMappings, *VirtualAddress, (PVOID)LoaderBlock,
BlockPages, LoaderSystemBlock);
/* Calculate next valid virtual address */
@@ -406,7 +412,7 @@ XtpInitializeLoaderBlock(IN PLIST_ENTRY MemoryMappings,
FrameBufferPages = EFI_SIZE_TO_PAGES(LoaderBlock->LoaderInformation.FrameBuffer.BufferSize);
/* Map frame buffer memory */
XtLdrProtocol->AddVirtualMemoryMapping(MemoryMappings, *VirtualAddress,
XtAddVirtualMemoryMapping(MemoryMappings, *VirtualAddress,
LoaderBlock->LoaderInformation.FrameBuffer.Address,
FrameBufferPages, LoaderFirmwarePermanent);
@@ -456,23 +462,23 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
EFI_STATUS Status;
/* Print debug message */
XtLdrProtocol->DbgPrint(L"Loading %S ... \n", FileName);
XtLdrProtocol->Debug.Print(L"Loading %S ... \n", FileName);
/* Open module file */
Status = SystemDir->Open(SystemDir, &ModuleHandle, FileName, EFI_FILE_MODE_READ, 0);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to open the file */
XtLdrProtocol->DbgPrint(L"ERROR: Failed to open '%S'\n", FileName);
XtLdrProtocol->Debug.Print(L"ERROR: Failed to open '%S'\n", FileName);
return Status;
}
/* Load the PE/COFF image file */
Status = XtPeCoffProtocol->Load(ModuleHandle, MemoryType, VirtualAddress, ImageContext);
Status = XtPeCoffProtocol->LoadImage(ModuleHandle, MemoryType, VirtualAddress, (PVOID)ImageContext);
if(Status != STATUS_EFI_SUCCESS)
{
/* Unable to load the file */
XtLdrProtocol->DbgPrint(L"ERROR: Failed to load '%S'\n", FileName);
XtLdrProtocol->Debug.Print(L"ERROR: Failed to load '%S'\n", FileName);
return Status;
}
@@ -484,7 +490,7 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
if(MachineType != _ARCH_IMAGE_MACHINE_TYPE)
{
/* Machine type mismatch */
XtLdrProtocol->DbgPrint(L"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\n");
XtLdrProtocol->Debug.Print(L"ERROR: Loaded incompatible PE/COFF image (machine type mismatch)\n");
return STATUS_EFI_INCOMPATIBLE_VERSION;
}
@@ -494,12 +500,12 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_APPLICATION &&
SubSystem != PECOFF_IMAGE_SUBSYSTEM_XT_NATIVE_DRIVER)
{
XtLdrProtocol->DbgPrint(L"WARNING: Loaded PE/COFF image with non-XT subsystem set\n");
XtLdrProtocol->Debug.Print(L"WARNING: Loaded PE/COFF image with non-XT subsystem set\n");
}
/* Print debug message */
XtLdrProtocol->DbgPrint(L"Loaded %S at PA: 0x%lx, VA: 0x%lx\n", FileName,
(*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress);
XtLdrProtocol->Debug.Print(L"Loaded %S at PA: 0x%lx, VA: 0x%lx\n", FileName,
(*ImageContext)->PhysicalAddress, (*ImageContext)->VirtualAddress);
/* Return success */
return STATUS_EFI_SUCCESS;
@@ -520,19 +526,14 @@ XtpLoadModule(IN PEFI_FILE_HANDLE SystemDir,
*/
XTCDECL
EFI_STATUS
BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
XtLdrModuleMain(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable)
{
EFI_GUID Guid = XT_XTOS_BOOT_PROTOCOL_GUID;
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
/* Set the system table and image handle */
EfiImageHandle = ImageHandle;
EfiSystemTable = SystemTable;
/* Open the XTLDR protocol */
Status = BlGetXtLoaderProtocol(&XtLdrProtocol);
Status = BlGetXtLdrProtocol(SystemTable, ImageHandle, &XtLdrProtocol);
if(Status != STATUS_EFI_SUCCESS)
{
/* Failed to open loader protocol */
@@ -543,6 +544,8 @@ BlXtLdrModuleMain(IN EFI_HANDLE ImageHandle,
XtBootProtocol.BootSystem = XtBootSystem;
/* Register XTOS boot protocol */
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE,
&XtBootProtocol);
XtLdrProtocol->Boot.RegisterProtocol(L"XTOS", &Guid);
/* Install XTOS protocol */
return XtLdrProtocol->Protocol.Install(&XtBootProtocol, &Guid);
}