forked from xt-sys/exectos
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:
committed by
CodingWorkshop Signing Team
parent
44905bb71d
commit
4412d4fc98
@@ -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)
|
||||
|
27
xtldr/modules/beep/CMakeLists.txt
Normal file
27
xtldr/modules/beep/CMakeLists.txt
Normal 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
209
xtldr/modules/beep/beep.c
Normal 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;
|
||||
}
|
13
xtldr/modules/beep/globals.c
Normal file
13
xtldr/modules/beep/globals.c
Normal 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;
|
38
xtldr/modules/beep/includes/beep.h
Normal file
38
xtldr/modules/beep/includes/beep.h
Normal 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 */
|
18
xtldr/modules/beep/includes/globals.h
Normal file
18
xtldr/modules/beep/includes/globals.h
Normal 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 */
|
27
xtldr/modules/dummy/CMakeLists.txt
Normal file
27
xtldr/modules/dummy/CMakeLists.txt
Normal 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)
|
69
xtldr/modules/dummy/dummy.c
Normal file
69
xtldr/modules/dummy/dummy.c
Normal 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);
|
||||
}
|
16
xtldr/modules/dummy/globals.c
Normal file
16
xtldr/modules/dummy/globals.c
Normal 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;
|
26
xtldr/modules/dummy/includes/dummy.h
Normal file
26
xtldr/modules/dummy/includes/dummy.h
Normal 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 */
|
21
xtldr/modules/dummy/includes/globals.h
Normal file
21
xtldr/modules/dummy/includes/globals.h
Normal 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 */
|
27
xtldr/modules/fb_o/CMakeLists.txt
Normal file
27
xtldr/modules/fb_o/CMakeLists.txt
Normal 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)
|
@@ -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);
|
||||
}
|
@@ -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>
|
||||
*/
|
79
xtldr/modules/fb_o/includes/framebuf.h
Normal file
79
xtldr/modules/fb_o/includes/framebuf.h
Normal 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 */
|
@@ -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)
|
@@ -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 */
|
@@ -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)
|
26
xtldr/modules/pecoff_o/CMakeLists.txt
Normal file
26
xtldr/modules/pecoff_o/CMakeLists.txt
Normal 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)
|
@@ -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 */
|
@@ -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);
|
||||
}
|
@@ -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)
|
@@ -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 */
|
28
xtldr/modules/xtos_o/CMakeLists.txt
Normal file
28
xtldr/modules/xtos_o/CMakeLists.txt
Normal 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)
|
336
xtldr/modules/xtos_o/amd64/memory.c
Normal file
336
xtldr/modules/xtos_o/amd64/memory.c
Normal 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;
|
||||
}
|
361
xtldr/modules/xtos_o/i686/memory.c
Normal file
361
xtldr/modules/xtos_o/i686/memory.c
Normal 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;
|
||||
}
|
107
xtldr/modules/xtos_o/includes/xtos.h
Normal file
107
xtldr/modules/xtos_o/includes/xtos.h
Normal 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 */
|
385
xtldr/modules/xtos_o/memory.c
Normal file
385
xtldr/modules/xtos_o/memory.c
Normal 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;
|
||||
}
|
@@ -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);
|
||||
}
|
Reference in New Issue
Block a user