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:
parent
44905bb71d
commit
4412d4fc98
@ -2,8 +2,5 @@
|
||||
This is a list of well known bugs that exists in all master branch builds.
|
||||
|
||||
### XTLDR
|
||||
- [ ] In some specific scenarios (most probably EFI by Insyde) XTLDR cannot load modules. Calling the EFI's
|
||||
BootServices->LoadImage() fails with STATUS_EFI_NOT_FOUND (0x800000000000000E) status code. Possibly this is
|
||||
a bug in BlFindVolumeDevicePath() routine.
|
||||
- [ ] EFI Runtime Services are not mapped properly into higher half. They are mapped itself, but all pointers inside
|
||||
that structure point to some physical address that is unavailable after paging is enabled.
|
||||
|
@ -1 +1 @@
|
||||
set_install_file(xtldr.ini efi/boot)
|
||||
set_install_file(xtldr.ini efi/boot/xtldr)
|
||||
|
@ -6,13 +6,14 @@
|
||||
# Debug - enables the debugging port and consists of two comma-separated parameters: com port and baud rate;
|
||||
# it is also possible to specify custom port address with: COM0:[address],[baud_rate]
|
||||
# Default - specifies which operating system listen in config file will be started if no choice is made
|
||||
# Theme - allows to set a custom theme to personalize XTLDR's look'n'feel
|
||||
# Modules - supplies a list of modules that will be loaded in orded to extend XTLDR functionality
|
||||
# Timeout - sets the countdown timer (in seconds) before the default OS get started automatically
|
||||
# Tune - plays a tune on the pcspeaker right before the XTLDR loads
|
||||
# Tune - plays a tune on the pcspeaker right before the XTLDR boot menu shows up
|
||||
#
|
||||
# Another type of section is [OS-Section] which adds a new position (operating system) to the boot menu. Each type
|
||||
# of the operating system provides a set of available parameters. If unsupported option is added, it is being ignored
|
||||
# by the XT Boot Loader. The available options are:
|
||||
# BootModules - supplies a list of additional modules that will be loaded just before invoking the boot protocol
|
||||
# SystemName - sets a long operating system name that will be shown on the boot menu
|
||||
# SystemType - specifies an OS type from a predefined list of supported boot protocols
|
||||
# SystemPath - the ARC path, eg. multi(0)disk(0)rdisk(0)partition(1)
|
||||
@ -22,22 +23,24 @@
|
||||
# Parameters - specifies extra boot options for the kernel
|
||||
|
||||
[XTLDR]
|
||||
Tune=400 880 2 988 2 783 2 392 2 587 3
|
||||
Debug=COM1,115200
|
||||
Timeout=30
|
||||
Theme=Fancy
|
||||
Default=ExectOS
|
||||
Modules=beep
|
||||
Timeout=30
|
||||
Tune=400 880 2 988 2 783 2 392 2 587 3
|
||||
|
||||
[ExectOS]
|
||||
SystemName="ExectOS Operating System"
|
||||
SystemType=XTOS
|
||||
BootModules=xtos_o
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(1)/ExectOS
|
||||
KernelFile=xtoskrnl.exe
|
||||
Parameters=DEBUG DEBUGPORT=COM1,115200
|
||||
Parameters=DEBUG=COM1,115200
|
||||
|
||||
[Windows]
|
||||
SystemName="Microsoft Windows 2000"
|
||||
SystemType=NT50
|
||||
BootModules=ntos
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(2)/Windows
|
||||
KernelFile=ntoskrnl.exe
|
||||
HalFile=hal.dll
|
||||
@ -46,6 +49,7 @@ Parameters=/NOGUIBOOT /MININT
|
||||
[Linux]
|
||||
SystemName="GNU/Linux"
|
||||
SystemType=LINUX
|
||||
BootModules=linux
|
||||
SystemPath=multi(0)disk(0)rdisk(0)partition(3)/boot
|
||||
KernelFile=vmlinuz
|
||||
InitrdFile=initramfs.cpio.gz
|
||||
|
@ -9,6 +9,10 @@ set(XTOS_COMPATIBLE_MINOR "3")
|
||||
set(XTOS_COMPATIBLE_VERSION "0x0603")
|
||||
set(XTOS_COMPATIBLE_BUILD "9600")
|
||||
|
||||
# Set XTLDR version
|
||||
set(XTLDR_VERSION_MAJOR "0")
|
||||
set(XTLDR_VERSION_MINOR "1")
|
||||
|
||||
# Set common XTOS version variables
|
||||
string(TIMESTAMP XTOS_VERSION_YEAR %Y)
|
||||
string(TIMESTAMP XTOS_VERSION_DATE "%Y%m%d")
|
||||
|
@ -29,4 +29,7 @@
|
||||
#define XTOS_COMPILER_NAME "@CMAKE_C_COMPILER_ID@"
|
||||
#define XTOS_COMPILER_VERSION "@CMAKE_C_COMPILER_VERSION@"
|
||||
|
||||
#define XTLDR_VERSION_MAJOR @XTLDR_VERSION_MAJOR@
|
||||
#define XTLDR_VERSION_MINOR @XTLDR_VERSION_MINOR@
|
||||
|
||||
#endif /* __XTGEN_XTVER_H */
|
||||
|
23
sdk/xtdk/blfuncs.h
Normal file
23
sdk/xtdk/blfuncs.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/blfuncs.h
|
||||
* DESCRIPTION: XT Boot Manager routines
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_BLFUNCS_H
|
||||
#define __XTDK_BLFUNCS_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <xtuefi.h>
|
||||
|
||||
|
||||
/* XT BootLoader routines forward references */
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler);
|
||||
|
||||
#endif /* __XTDK_BLFUNCS_H */
|
289
sdk/xtdk/bltypes.h
Normal file
289
sdk/xtdk/bltypes.h
Normal file
@ -0,0 +1,289 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/bltypes.h
|
||||
* DESCRIPTION: XT Boot Manager structures definitions
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTDK_BLTYPES_H
|
||||
#define __XTDK_BLTYPES_H
|
||||
|
||||
#include <xttypes.h>
|
||||
#include <xtuefi.h>
|
||||
#include <hltypes.h>
|
||||
|
||||
|
||||
/* Architecture specific definitions */
|
||||
#if defined(__i386__) || defined(__i686__)
|
||||
#define XTBL_ARCH_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\"
|
||||
#define XTBL_ARCH_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\MODULES\\"
|
||||
#define XTBL_ARCH_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR32\\THEMES\\"
|
||||
#elif defined(__amd64__) || defined(__x86_64__)
|
||||
#define XTBL_ARCH_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\"
|
||||
#define XTBL_ARCH_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\MODULES\\"
|
||||
#define XTBL_ARCH_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR64\\THEMES\\"
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
/* XTLDR directories */
|
||||
#define XTBL_LOADER_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\"
|
||||
#define XTBL_MODULES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\MODULES\\"
|
||||
#define XTBL_THEMES_DIRECTORY_PATH L"\\EFI\\BOOT\\XTLDR\\THEMES\\"
|
||||
|
||||
/* XTLDR module segment macros */
|
||||
#define XTBL_MODDEPS SEGMENT(".moddeps") CONST WCHAR XtBlpDeps[][8]
|
||||
#define XTBL_MODINFO SEGMENT(".modinfo") CONST WCHAR XtBlpInfo[]
|
||||
|
||||
/* EFI XT boot devices */
|
||||
#define XTBL_BOOT_DEVICE_UNKNOWN 0x00
|
||||
#define XTBL_BOOT_DEVICE_CDROM 0x01
|
||||
#define XTBL_BOOT_DEVICE_FLOPPY 0x02
|
||||
#define XTBL_BOOT_DEVICE_HARDDISK 0x03
|
||||
#define XTBL_BOOT_DEVICE_RAMDISK 0x04
|
||||
|
||||
/* XTLDR Debug Port type definitions */
|
||||
#define XTBL_DEBUGPORT_SCREEN 1
|
||||
#define XTBL_DEBUGPORT_SERIAL 2
|
||||
|
||||
/* TUI dialog box attributes */
|
||||
#define XTBL_TUI_DIALOG_GENERIC_BOX 1
|
||||
#define XTBL_TUI_DIALOG_ERROR_BOX 2
|
||||
#define XTBL_TUI_DIALOG_ACTIVE_BUTTON 4
|
||||
#define XTBL_TUI_DIALOG_INACTIVE_BUTTON 8
|
||||
#define XTBL_TUI_DIALOG_ACTIVE_INPUT 16
|
||||
#define XTBL_TUI_DIALOG_INACTIVE_INPUT 32
|
||||
#define XTBL_TUI_DIALOG_PROGRESS_BAR 64
|
||||
|
||||
/* TUI dialog box maximum width */
|
||||
#define XTBL_TUI_MAX_DIALOG_WIDTH 100
|
||||
|
||||
/* Boot Loader protocol routine pointers */
|
||||
typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory);
|
||||
typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
|
||||
typedef VOID (*PBL_BOOTMENU_INITIALIZE_OS_LIST)(OUT PXTBL_BOOTMENU_ITEM MenuEntries, OUT PULONG EntriesCount, OUT PULONG DefaultId);
|
||||
typedef EFI_STATUS (*PBL_BOOTPROTO_BOOT_SYSTEM)(IN PXTBL_BOOT_PARAMETERS Parameters);
|
||||
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||
typedef VOID (*PBL_CLEAR_CONSOLE_LINE)(IN ULONGLONG LineNo);
|
||||
typedef EFI_STATUS (*PBL_CLOSE_XT_PROTOCOL)(IN PEFI_HANDLE Handle, IN PEFI_GUID ProtocolGuid);
|
||||
typedef PWCHAR (*PBL_CONFIG_GET_VALUE)(IN CONST PWCHAR ConfigName);
|
||||
typedef VOID (*PBL_CONSOLE_CLEAR_SCREEN)();
|
||||
typedef VOID (*PBL_CONSOLE_DISABLE_CURSOR)();
|
||||
typedef VOID (*PBL_CONSOLE_ENABLE_CURSOR)();
|
||||
typedef VOID (*PBL_CONSOLE_PRINT)(IN PUINT16 Format, IN ...);
|
||||
typedef VOID (*PBL_CONSOLE_QUERY_MODE)(OUT PUINT_PTR ResX, OUT PUINT_PTR ResY);
|
||||
typedef VOID (*PBL_CONSOLE_READ_KEY_STROKE)(OUT PEFI_INPUT_KEY Key);
|
||||
typedef VOID (*PBL_CONSOLE_RESET_INPUT_BUFFER)();
|
||||
typedef VOID (*PBL_CONSOLE_SET_ATTRIBUTES)(IN ULONGLONG Attributes);
|
||||
typedef VOID (*PBL_CONSOLE_SET_CURSOR_POSITION)(IN ULONGLONG PosX, IN ULONGLONG PosY);
|
||||
typedef VOID (*PBL_CONSOLE_WRITE)(IN PUSHORT String);
|
||||
typedef VOID (*PBL_DEBUG_PRINT)(IN PUINT16 Format, IN ...);
|
||||
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_ENTRY_POINT)(IN PVOID ImagePointer, OUT PVOID *EntryPoint);
|
||||
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_MACHINE_TYPE)(IN PVOID ImagePointer, OUT PUSHORT MachineType);
|
||||
typedef EFI_STATUS (*PBL_EXECIMAGE_GET_SUBSYSTEM)(IN PVOID ImagePointer, OUT PUSHORT SubSystem);
|
||||
typedef EFI_STATUS (*PBL_EXECIMAGE_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType, IN PVOID VirtualAddress, OUT PVOID *ImagePointer);
|
||||
typedef EFI_STATUS (*PBL_EXECIMAGE_RELOCATE_IMAGE)(IN PVOID ImagePointer, IN EFI_VIRTUAL_ADDRESS Address);
|
||||
typedef EFI_STATUS (*PBL_EXIT_BOOT_SERVICES)(IN UINT_PTR MapKey);
|
||||
typedef EFI_STATUS (*PBL_FIND_BOOT_PROTOCOL)(IN PWCHAR SystemType, OUT PEFI_GUID BootProtocolGuid);
|
||||
typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory);
|
||||
typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap);
|
||||
typedef PLIST_ENTRY (*PBL_GET_MODULES_LIST)();
|
||||
typedef INT_PTR (*PBL_GET_SECURE_BOOT_STATUS)();
|
||||
typedef EFI_STATUS (*PBL_INSTALL_XT_PROTOCOL)(IN PVOID Interface, IN PEFI_GUID Guid);
|
||||
typedef EFI_STATUS (*PBL_INVOKE_BOOT_PROTOCOL)(IN PLIST_ENTRY OptionsList);
|
||||
typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
||||
typedef EFI_STATUS (*PBL_OPEN_XT_PROTOCOL)(OUT PEFI_HANDLE Handle, OUT PVOID *ProtocolHandler, IN PEFI_GUID ProtocolGuid);
|
||||
typedef EFI_STATUS (*PBL_READ_FILE)(IN PEFI_FILE_HANDLE DirHandle, IN CONST PWCHAR FileName, OUT PVOID *FileData, OUT PSIZE_T FileSize);
|
||||
typedef EFI_STATUS (*PBL_REGISTER_BOOT_PROTOCOL)(IN PWCHAR SystemType, IN PEFI_GUID BootProtocolGuid);
|
||||
typedef VOID (*PBL_REGISTER_XT_BOOT_MENU)(PVOID BootMenuRoutine);
|
||||
typedef VOID (*PBL_SLEEP_EXECUTION)(IN ULONG_PTR Milliseconds);
|
||||
typedef VOID (*PBL_TUI_DISPLAY_ERROR_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message);
|
||||
typedef VOID (*PBL_TUI_DISPLAY_INFO_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message);
|
||||
typedef VOID (*PBL_TUI_DISPLAY_INPUT_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN PWCHAR *InputFieldText);
|
||||
typedef XTBL_DIALOG_HANDLE (*PBL_TUI_DISPLAY_PROGRESS_DIALOG)(IN PWCHAR Caption, IN PWCHAR Message, IN UCHAR Percentage);
|
||||
typedef VOID (*PBL_TUI_UPDATE_PROGRESS_BAR)(IN PXTBL_DIALOG_HANDLE Handle, IN PWCHAR Message, IN UCHAR Percentage);
|
||||
typedef EFI_STATUS (*PBL_WAIT_FOR_EFI_EVENT)(IN UINT_PTR NumberOfEvents, IN PEFI_EVENT Event, OUT PUINT_PTR Index);
|
||||
typedef VOID (*PBL_XT_BOOT_MENU)();
|
||||
|
||||
/* Boot parameters structure */
|
||||
typedef struct _XTBL_BOOT_PARAMETERS
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||||
PWCHAR ArcName;
|
||||
PWCHAR SystemPath;
|
||||
PWCHAR SystemType;
|
||||
PWCHAR KernelFile;
|
||||
PWCHAR InitrdFile;
|
||||
PWCHAR HalFile;
|
||||
PWCHAR Parameters;
|
||||
} XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS;
|
||||
|
||||
/* Boot menu list structure */
|
||||
typedef struct _XTBL_BOOTMENU_ITEM
|
||||
{
|
||||
PWCHAR EntryName;
|
||||
PLIST_ENTRY Options;
|
||||
} XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;
|
||||
|
||||
/* XTLDR Configuration data */
|
||||
typedef struct _XTBL_CONFIG_ENTRY
|
||||
{
|
||||
LIST_ENTRY Flink;
|
||||
PWCHAR Name;
|
||||
PWCHAR Value;
|
||||
} XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY;
|
||||
|
||||
/* XTLDR Configuration section */
|
||||
typedef struct _XTBL_CONFIG_SECTION
|
||||
{
|
||||
LIST_ENTRY Flink;
|
||||
LIST_ENTRY Options;
|
||||
PWCHAR SectionName;
|
||||
} XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION;
|
||||
|
||||
/* XTLDR Dialog handle data */
|
||||
typedef struct _XTBL_DIALOG_HANDLE
|
||||
{
|
||||
UCHAR Attributes;
|
||||
UCHAR DialogColor;
|
||||
UCHAR TextColor;
|
||||
UINT_PTR ResX;
|
||||
UINT_PTR ResY;
|
||||
UINT_PTR PosX;
|
||||
UINT_PTR PosY;
|
||||
UINT_PTR Width;
|
||||
UINT_PTR Height;
|
||||
} XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE;
|
||||
|
||||
/* Registered boot protocol structure */
|
||||
typedef struct _XTBL_KNOWN_BOOT_PROTOCOL
|
||||
{
|
||||
LIST_ENTRY Flink;
|
||||
PWCHAR SystemType;
|
||||
EFI_GUID Guid;
|
||||
} XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
||||
|
||||
/* XTLDR Module dependencies data */
|
||||
typedef struct _XTBL_MODULE_DEPS
|
||||
{
|
||||
LIST_ENTRY Flink;
|
||||
PWCHAR ModuleName;
|
||||
} XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;
|
||||
|
||||
/* XTLDR Module information data */
|
||||
typedef struct _XTBL_MODULE_INFO
|
||||
{
|
||||
LIST_ENTRY Flink;
|
||||
PWCHAR ModuleName;
|
||||
PWCHAR ModuleDescription;
|
||||
LIST_ENTRY Dependencies;
|
||||
PVOID ModuleBase;
|
||||
UINT64 ModuleSize;
|
||||
UINT32 Revision;
|
||||
PEFI_IMAGE_UNLOAD UnloadModule;
|
||||
} XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
||||
|
||||
/* XTLDR Status data */
|
||||
typedef struct _XTBL_STATUS
|
||||
{
|
||||
PBL_XT_BOOT_MENU BootMenu;
|
||||
BOOLEAN BootServices;
|
||||
ULONG DebugPort;
|
||||
INT_PTR SecureBoot;
|
||||
CPPORT SerialPort;
|
||||
} XTBL_STATUS, *PXTBL_STATUS;
|
||||
|
||||
/* XTLDR Boot protocol structure */
|
||||
typedef struct _XTBL_BOOT_PROTOCOL
|
||||
{
|
||||
PBL_BOOTPROTO_BOOT_SYSTEM BootSystem;
|
||||
} XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL;
|
||||
|
||||
/* XTLDR Executable image protocol structure */
|
||||
typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL
|
||||
{
|
||||
PBL_EXECIMAGE_GET_ENTRY_POINT GetEntryPoint;
|
||||
PBL_EXECIMAGE_GET_MACHINE_TYPE GetMachineType;
|
||||
// PBL_EXECIMAGE_GET_SECTION GetSection;
|
||||
PBL_EXECIMAGE_GET_SUBSYSTEM GetSubSystem;
|
||||
// PBL_EXECIMAGE_GET_VERSION GetVersion;
|
||||
PBL_EXECIMAGE_LOAD_IMAGE LoadImage;
|
||||
// PBL_EXECIMAGE_PRINT_INFO PrintDebugInfo;
|
||||
PBL_EXECIMAGE_RELOCATE_IMAGE RelocateImage;
|
||||
// PBL_EXECUTABLE_VERIFY_IMAGE VerifyImage;
|
||||
} XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL;
|
||||
|
||||
/* XTLDR Loader protocol */
|
||||
typedef struct _XTBL_LOADER_PROTOCOL
|
||||
{
|
||||
struct
|
||||
{
|
||||
PBL_FIND_BOOT_PROTOCOL FindProtocol;
|
||||
PBL_BOOTMENU_INITIALIZE_OS_LIST InitializeMenuList;
|
||||
PBL_INVOKE_BOOT_PROTOCOL InvokeProtocol;
|
||||
PBL_REGISTER_XT_BOOT_MENU RegisterMenu;
|
||||
PBL_REGISTER_BOOT_PROTOCOL RegisterProtocol;
|
||||
} Boot;
|
||||
struct
|
||||
{
|
||||
PBL_CONFIG_GET_VALUE GetValue;
|
||||
} Config;
|
||||
struct
|
||||
{
|
||||
PBL_CLEAR_CONSOLE_LINE ClearLine;
|
||||
PBL_CONSOLE_CLEAR_SCREEN ClearScreen;
|
||||
PBL_CONSOLE_DISABLE_CURSOR DisableCursor;
|
||||
PBL_CONSOLE_ENABLE_CURSOR EnableCursor;
|
||||
PBL_CONSOLE_PRINT Print;
|
||||
PBL_CONSOLE_QUERY_MODE QueryMode;
|
||||
PBL_CONSOLE_READ_KEY_STROKE ReadKeyStroke;
|
||||
PBL_CONSOLE_RESET_INPUT_BUFFER ResetInputBuffer;
|
||||
PBL_CONSOLE_SET_ATTRIBUTES SetAttributes;
|
||||
PBL_CONSOLE_SET_CURSOR_POSITION SetCursorPosition;
|
||||
PBL_CONSOLE_WRITE Write;
|
||||
} Console;
|
||||
struct
|
||||
{
|
||||
PBL_DEBUG_PRINT Print;
|
||||
} Debug;
|
||||
struct
|
||||
{
|
||||
PBL_CLOSE_VOLUME CloseVolume;
|
||||
PBL_OPEN_VOLUME OpenVolume;
|
||||
PBL_READ_FILE ReadFile;
|
||||
} Disk;
|
||||
struct
|
||||
{
|
||||
PBL_ALLOCATE_PAGES AllocatePages;
|
||||
PBL_ALLOCATE_POOL AllocatePool;
|
||||
PBL_FREE_PAGES FreePages;
|
||||
PBL_FREE_POOL FreePool;
|
||||
PBL_GET_MEMORY_MAP GetMemoryMap;
|
||||
} Memory;
|
||||
struct
|
||||
{
|
||||
PBL_CLOSE_XT_PROTOCOL Close;
|
||||
PBL_GET_MODULES_LIST GetModulesList;
|
||||
PBL_INSTALL_XT_PROTOCOL Install;
|
||||
PBL_OPEN_XT_PROTOCOL Open;
|
||||
} Protocol;
|
||||
struct
|
||||
{
|
||||
PBL_TUI_DISPLAY_ERROR_DIALOG DisplayErrorDialog;
|
||||
PBL_TUI_DISPLAY_INFO_DIALOG DisplayInfoDialog;
|
||||
PBL_TUI_DISPLAY_INPUT_DIALOG DisplayInputDialog;
|
||||
PBL_TUI_DISPLAY_PROGRESS_DIALOG DisplayProgressDialog;
|
||||
PBL_TUI_UPDATE_PROGRESS_BAR UpdateProgressBar;
|
||||
} Tui;
|
||||
struct
|
||||
{
|
||||
PBL_EXIT_BOOT_SERVICES ExitBootServices;
|
||||
PBL_GET_SECURE_BOOT_STATUS GetSecureBootStatus;
|
||||
PBL_SLEEP_EXECUTION SleepExecution;
|
||||
PBL_WAIT_FOR_EFI_EVENT WaitForEfiEvent;
|
||||
} Util;
|
||||
} XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||
|
||||
#endif /* __XTDK_BLTYPES_H */
|
50
sdk/xtdk/xtblapi.h
Normal file
50
sdk/xtdk/xtblapi.h
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: sdk/xtdk/xtblapi.h
|
||||
* DESCRIPTION: Top level header for the XT Boot Loader API
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
/* Base XT headers */
|
||||
#include <xtdefs.h>
|
||||
#include <xtstatus.h>
|
||||
#include <xttarget.h>
|
||||
#include <xttypes.h>
|
||||
|
||||
/* XT forward references */
|
||||
#include <xtstruct.h>
|
||||
|
||||
/* Architecture-specific XT forward references */
|
||||
#include ARCH_HEADER(xtstruct.h)
|
||||
|
||||
/* Architecture-independent XT API */
|
||||
#include <xtbase.h>
|
||||
#include <xtfw.h>
|
||||
#include <xtimage.h>
|
||||
#include <xtuefi.h>
|
||||
#include <xtdebug.h>
|
||||
#include <xtguid.h>
|
||||
|
||||
/* Architecture independent XT kernel data types */
|
||||
#include <hltypes.h>
|
||||
#include <iotypes.h>
|
||||
#include <rtltypes.h>
|
||||
|
||||
/* Architecture dependent XT kernel data types */
|
||||
#include ARCH_HEADER(artypes.h)
|
||||
#include ARCH_HEADER(hltypes.h)
|
||||
#include ARCH_HEADER(ketypes.h)
|
||||
#include ARCH_HEADER(mmtypes.h)
|
||||
|
||||
/* XT Kernel runtime routines */
|
||||
#include <hlfuncs.h>
|
||||
#include <rtlfuncs.h>
|
||||
|
||||
/* Architecture specific XT kernel routines */
|
||||
#include ARCH_HEADER(arfuncs.h)
|
||||
#include ARCH_HEADER(hlfuncs.h)
|
||||
|
||||
/* Boot Manager specific structures */
|
||||
#include <bltypes.h>
|
||||
#include <blfuncs.h>
|
@ -264,6 +264,18 @@ typedef struct _UEFI_FIRMWARE_INFORMATION UEFI_FIRMWARE_INFORMATION, *PUEFI_FIRM
|
||||
typedef struct _UNICODE_STRING UNICODE_STRING, *PUNICODE_STRING;
|
||||
typedef struct _UNICODE_STRING32 UNICODE_STRING32, *PUNICODE_STRING32;
|
||||
typedef struct _UNICODE_STRING64 UNICODE_STRING64, *PUNICODE_STRING64;
|
||||
typedef struct _XTBL_BOOT_PARAMETERS XTBL_BOOT_PARAMETERS, *PXTBL_BOOT_PARAMETERS;
|
||||
typedef struct _XTBL_BOOT_PROTOCOL XTBL_BOOT_PROTOCOL, *PXTBL_BOOT_PROTOCOL;
|
||||
typedef struct _XTBL_BOOTMENU_ITEM XTBL_BOOTMENU_ITEM, *PXTBL_BOOTMENU_ITEM;
|
||||
typedef struct _XTBL_CONFIG_ENTRY XTBL_CONFIG_ENTRY, *PXTBL_CONFIG_ENTRY;
|
||||
typedef struct _XTBL_CONFIG_SECTION XTBL_CONFIG_SECTION, *PXTBL_CONFIG_SECTION;
|
||||
typedef struct _XTBL_DIALOG_HANDLE XTBL_DIALOG_HANDLE, *PXTBL_DIALOG_HANDLE;
|
||||
typedef struct _XTBL_EXECUTABLE_IMAGE_PROTOCOL XTBL_EXECUTABLE_IMAGE_PROTOCOL, *PXTBL_EXECUTABLE_IMAGE_PROTOCOL;
|
||||
typedef struct _XTBL_KNOWN_BOOT_PROTOCOL XTBL_KNOWN_BOOT_PROTOCOL, *PXTBL_KNOWN_BOOT_PROTOCOL;
|
||||
typedef struct _XTBL_LOADER_PROTOCOL XTBL_LOADER_PROTOCOL, *PXTBL_LOADER_PROTOCOL;
|
||||
typedef struct _XTBL_MODULE_DEPS XTBL_MODULE_DEPS, *PXTBL_MODULE_DEPS;
|
||||
typedef struct _XTBL_MODULE_INFO XTBL_MODULE_INFO, *PXTBL_MODULE_INFO;
|
||||
typedef struct _XTBL_STATUS XTBL_STATUS, *PXTBL_STATUS;
|
||||
|
||||
/* Unions forward references */
|
||||
typedef union _EFI_DEV_PATH EFI_DEV_PATH, *PEFI_DEV_PATH;
|
||||
|
@ -9,19 +9,29 @@ include_directories(
|
||||
${EXECTOS_SOURCE_DIR}/sdk/xtdk
|
||||
${XTLDR_SOURCE_DIR}/includes)
|
||||
|
||||
# Specify list of library source code files
|
||||
list(APPEND LIBXTLDR_SOURCE
|
||||
${XTLDR_SOURCE_DIR}/library/modproto.c)
|
||||
|
||||
# Specify list of source code files
|
||||
list(APPEND XTLDR_SOURCE
|
||||
${XTLDR_SOURCE_DIR}/${ARCH}/memory.c
|
||||
${XTLDR_SOURCE_DIR}/blproto.c
|
||||
${XTLDR_SOURCE_DIR}/config.c
|
||||
${XTLDR_SOURCE_DIR}/console.c
|
||||
${XTLDR_SOURCE_DIR}/efiutil.c
|
||||
${XTLDR_SOURCE_DIR}/debug.c
|
||||
${XTLDR_SOURCE_DIR}/efiutils.c
|
||||
${XTLDR_SOURCE_DIR}/globals.c
|
||||
${XTLDR_SOURCE_DIR}/hardware.c
|
||||
${XTLDR_SOURCE_DIR}/memory.c
|
||||
${XTLDR_SOURCE_DIR}/protocol.c
|
||||
${XTLDR_SOURCE_DIR}/shell.c
|
||||
${XTLDR_SOURCE_DIR}/string.c
|
||||
${XTLDR_SOURCE_DIR}/system.c
|
||||
${XTLDR_SOURCE_DIR}/textui.c
|
||||
${XTLDR_SOURCE_DIR}/volume.c
|
||||
${XTLDR_SOURCE_DIR}/xtldr.c)
|
||||
|
||||
# Link static XTLDR library
|
||||
add_library(libxtldr ${LIBXTLDR_SOURCE})
|
||||
|
||||
# Link bootloader executable
|
||||
add_executable(xtldr ${XTLDR_SOURCE})
|
||||
|
||||
@ -38,6 +48,7 @@ set_target_properties(xtldr PROPERTIES OUTPUT_NAME ${BINARY_NAME} SUFFIX .efi)
|
||||
set_install_target(xtldr efi/boot)
|
||||
|
||||
# Set loader entrypoint and subsystem
|
||||
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
|
||||
set_entrypoint(xtldr "BlStartXtLoader")
|
||||
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
|
||||
set_linker_map(xtldr TRUE)
|
||||
set_subsystem(xtldr efi_application)
|
||||
|
@ -1,4 +1,4 @@
|
||||
## XT Loader (XTLDR)
|
||||
## XT Boot Loader (XTLDR)
|
||||
The XTLDR, or XTOS Boot Loader, is an EFI (Extensible Firmware Interface) boot loader specifically designed for XTOS.
|
||||
As an EFI boot loader, XTLDR operates exclusively with EFI-based hardware and is not compatible with non-EFI systems,
|
||||
like old and deprecated BIOS.
|
||||
|
@ -1,96 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/blproto.c
|
||||
* DESCRIPTION: EFI XTLDR protocol API
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <blproto.h>
|
||||
|
||||
|
||||
/**
|
||||
* This routine locates and opens the XT boot loader protocol.
|
||||
*
|
||||
* @param LdrProtocol
|
||||
* Supplies the address where a pointer to the loader protocol is returned.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetXtLoaderProtocol(OUT PXT_BOOT_LOADER_PROTOCOL *LdrProtocol)
|
||||
{
|
||||
EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;
|
||||
|
||||
/* Load XTLDR protocol */
|
||||
return BlLoadXtProtocol((PVOID *)LdrProtocol, &Guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine locates and opens the requested XT protocol.
|
||||
*
|
||||
* @param ProtocolHandler
|
||||
* Supplies the address where a pointer to the opened protocol is returned.
|
||||
*
|
||||
* @param ProtocolGuid
|
||||
* Supplies a pointer to the unique protocol GUID.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadXtProtocol(OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid)
|
||||
{
|
||||
PEFI_HANDLE Handles = NULL;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR Count;
|
||||
UINT Index;
|
||||
|
||||
/* Try to locate the handles */
|
||||
Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULL, &Count, &Handles);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get handles */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if any handles returned */
|
||||
if(Count > 0)
|
||||
{
|
||||
/* Iterate through all given handles */
|
||||
for(Index = 0; Index < Count; Index++)
|
||||
{
|
||||
/* Try to open protocol */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], ProtocolGuid,
|
||||
ProtocolHandler, EfiImageHandle, NULL,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
|
||||
/* Check if successfully opened the loader protocol */
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Protocol found and successfully opened */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free handles */
|
||||
EfiSystemTable->BootServices->FreePool(Handles);
|
||||
|
||||
/* Make sure the loaded protocol has been found */
|
||||
if(*ProtocolHandler == NULL)
|
||||
{
|
||||
/* Protocol not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
595
xtldr/config.c
Normal file
595
xtldr/config.c
Normal file
@ -0,0 +1,595 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/config.c
|
||||
* DESCRIPTION: XT Boot Loader Configuration
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Returns a value of the specified configuration key.
|
||||
*
|
||||
* @param ConfigName
|
||||
* Specifies the configuration key to return its value.
|
||||
*
|
||||
* @return This routine returns a pointer to the configuration value, or NULL if key was not found.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
PWCHAR
|
||||
BlGetConfigValue(IN CONST PWCHAR ConfigName)
|
||||
{
|
||||
PXTBL_CONFIG_ENTRY ConfigEntry;
|
||||
PLIST_ENTRY ConfigListEntry;
|
||||
SIZE_T KeyLength, ValueLength;
|
||||
EFI_STATUS Status;
|
||||
PWCHAR Value;
|
||||
|
||||
/* Get config entry name length */
|
||||
KeyLength = RtlWideStringLength(ConfigName, 0);
|
||||
|
||||
/* Iterate through config entries */
|
||||
ConfigListEntry = BlpConfig.Flink;
|
||||
while(ConfigListEntry != &BlpConfig)
|
||||
{
|
||||
/* Get config entry */
|
||||
ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);
|
||||
|
||||
/* Check if requested configuration found */
|
||||
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, KeyLength) == 0)
|
||||
{
|
||||
/* Get value length */
|
||||
ValueLength = RtlWideStringLength(ConfigEntry->Value, 0);
|
||||
|
||||
/* Allocate memory for value */
|
||||
Status = BlMemoryAllocatePool(ValueLength * sizeof(WCHAR), (PVOID *)&Value);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure, return NULL */
|
||||
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Copy value and return it */
|
||||
RtlCopyMemory(Value, ConfigEntry->Value, ValueLength * sizeof(WCHAR));
|
||||
Value[ValueLength] = 0;
|
||||
return Value;
|
||||
}
|
||||
|
||||
/* Move to the next config entry */
|
||||
ConfigListEntry = ConfigListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Config entry not found, return NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates existing configuration value.
|
||||
*
|
||||
* @param ConfigName
|
||||
* Specifies the configuration key to update.
|
||||
*
|
||||
* @param ConfigValue
|
||||
* Specifies the new configuration value.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetConfigValue(IN CONST PWCHAR ConfigName,
|
||||
IN CONST PWCHAR ConfigValue)
|
||||
{
|
||||
PXTBL_CONFIG_ENTRY ConfigEntry;
|
||||
PLIST_ENTRY ConfigListEntry;
|
||||
SIZE_T Length;
|
||||
|
||||
/* Get config entry name length */
|
||||
Length = RtlWideStringLength(ConfigName, 0);
|
||||
|
||||
/* Iterate through config entries */
|
||||
ConfigListEntry = BlpConfig.Flink;
|
||||
while(ConfigListEntry != &BlpConfig)
|
||||
{
|
||||
/* Get config entry */
|
||||
ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);
|
||||
|
||||
/* Check if requested configuration found */
|
||||
if(RtlCompareWideStringInsensitive(ConfigEntry->Name, ConfigName, Length) == 0)
|
||||
{
|
||||
/* Update config value */
|
||||
ConfigEntry->Value = ConfigValue;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Move to the next config entry */
|
||||
ConfigListEntry = ConfigListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Config entry not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and parses XTLDR configuration file.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpLoadConfiguration()
|
||||
{
|
||||
PLIST_ENTRY SectionListEntry;
|
||||
EFI_STATUS Status;
|
||||
PCHAR ConfigData;
|
||||
|
||||
/* Initialize configuration pointer */
|
||||
RtlInitializeListHead(&BlpConfigSections);
|
||||
|
||||
/* Read data from configuration file */
|
||||
Status = BlpReadConfigFile(XTBL_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to read config file, try with architecture specific directory */
|
||||
Status = BlpReadConfigFile(XTBL_ARCH_LOADER_DIRECTORY_PATH, L"XTLDR.INI", &ConfigData);
|
||||
}
|
||||
|
||||
/* Check if configuration was read successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load configuration */
|
||||
BlDebugPrint(L"Failed to load FS0:/EFI/BOOT/XTLDR.INI configuration file (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Parse configuration data */
|
||||
Status = BlpParseConfigFile(ConfigData, &BlpConfigSections);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse configuration */
|
||||
BlDebugPrint(L"Failed to parse FS0:/EFI/BOOT/XTLDR.INI configuration file (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Iterate through config sections */
|
||||
SectionListEntry = BlpConfigSections.Flink;
|
||||
while(SectionListEntry != &BlpConfigSections)
|
||||
{
|
||||
/* Get config section */
|
||||
PXTBL_CONFIG_SECTION Section = CONTAIN_RECORD(SectionListEntry, XTBL_CONFIG_SECTION, Flink);
|
||||
|
||||
/* Look for global XTLDR configuration section */
|
||||
if(RtlCompareWideStringInsensitive(Section->SectionName, L"XTLDR", 5) == 0)
|
||||
{
|
||||
/* Update global configuration */
|
||||
BlpUpdateConfiguration(&Section->Options);
|
||||
|
||||
/* Remove XTLDR section from the list */
|
||||
RtlRemoveEntryList(SectionListEntry);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to the next section */
|
||||
SectionListEntry = SectionListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Update boot menu OS list */
|
||||
BlpMenuList = &BlpConfigSections;
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses command line arguments and updates global configuration.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpParseCommandLine(VOID)
|
||||
{
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
PWCHAR Argument, Key, LastArg, Value;
|
||||
PXTBL_CONFIG_ENTRY Option;
|
||||
EFI_STATUS Status;
|
||||
SIZE_T KeyLength, ValueLength;
|
||||
LIST_ENTRY Config;
|
||||
|
||||
/* Initialize configuration list */
|
||||
RtlInitializeListHead(&Config);
|
||||
|
||||
/* Handle loaded image protocol */
|
||||
Status = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Check if launched from UEFI shell */
|
||||
if(LoadedImage && LoadedImage->LoadOptions)
|
||||
{
|
||||
/* Tokenize provided options */
|
||||
Argument = RtlTokenizeWideString(LoadedImage->LoadOptions, L" ", &LastArg);
|
||||
|
||||
/* Iterate over all arguments passed to boot loader */
|
||||
while(Argument != NULL)
|
||||
{
|
||||
/* Store key name */
|
||||
Key = Argument;
|
||||
|
||||
/* Find end of the key */
|
||||
while(*Argument != '=' && *Argument != 0 && *Argument != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
Argument++;
|
||||
}
|
||||
|
||||
/* Mark end of the key and advance to the next character */
|
||||
*Argument = 0;
|
||||
Argument++;
|
||||
|
||||
/* Store value */
|
||||
Value = Argument;
|
||||
|
||||
/* Find end of the value */
|
||||
while(*Argument != 0 && *Argument != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
Argument++;
|
||||
}
|
||||
|
||||
/* Mark end of the value and advance to the next character */
|
||||
*Argument = 0;
|
||||
Argument++;
|
||||
|
||||
/* Get length of the key and its value */
|
||||
KeyLength = RtlWideStringLength(Key, 0);
|
||||
ValueLength = RtlWideStringLength(Value, 0);
|
||||
|
||||
/* Check if argument is valid */
|
||||
if(KeyLength == 0 || ValueLength == 0)
|
||||
{
|
||||
/* Invalid argument, skip to the next one */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate memory for new option */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Allocate more memory for option name */
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Allocate even more memory for option value */
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);
|
||||
}
|
||||
}
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Some memory allocation failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set entry name and value */
|
||||
RtlCopyMemory(Option->Name, Key, (KeyLength * sizeof(WCHAR)));
|
||||
RtlCopyMemory(Option->Value, Value, (ValueLength * sizeof(WCHAR)));
|
||||
Option->Name[KeyLength] = 0;
|
||||
Option->Value[ValueLength] = 0;
|
||||
|
||||
/* Add entry to the list */
|
||||
RtlInsertTailList(&Config, &Option->Flink);
|
||||
|
||||
/* Take next argument */
|
||||
Argument = RtlTokenizeWideString(NULL, L" ", &LastArg);
|
||||
}
|
||||
|
||||
/* Update global configuration */
|
||||
BlpUpdateConfiguration(&Config);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses configuration INI file.
|
||||
*
|
||||
* @param RawConfig
|
||||
* Suplies a pointer to configuration INI file to be parsed.
|
||||
*
|
||||
* @param Configuration
|
||||
* Supplies a pointer to memory region where parsed configuration will be stored.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpParseConfigFile(IN CONST PCHAR RawConfig,
|
||||
OUT PLIST_ENTRY Configuration)
|
||||
{
|
||||
SIZE_T SectionLength, KeyLength, ValueLength;
|
||||
PCHAR InputData, Key, SectionName, Value;
|
||||
PXTBL_CONFIG_SECTION Section;
|
||||
PXTBL_CONFIG_ENTRY Option;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Initialize pointers */
|
||||
InputData = RawConfig;
|
||||
Section = NULL;
|
||||
Option = NULL;
|
||||
SectionName = NULL;
|
||||
Key = NULL;
|
||||
Value = NULL;
|
||||
|
||||
/* Analyze configuration data until end of file is reached */
|
||||
while(*InputData != 0)
|
||||
{
|
||||
if(*InputData == ';' || *InputData == '#')
|
||||
{
|
||||
/* Skip comment until end of the line */
|
||||
while(*InputData != 0 && *InputData != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
InputData++;
|
||||
}
|
||||
}
|
||||
else if(*InputData == ' ' || *InputData == '\t' || *InputData == '\r' || *InputData == '\n')
|
||||
{
|
||||
/* Skip whitespaces */
|
||||
InputData++;
|
||||
}
|
||||
else if(*InputData == '[')
|
||||
{
|
||||
/* Skip leading bracket */
|
||||
InputData++;
|
||||
|
||||
/* Store section name */
|
||||
SectionName = InputData;
|
||||
|
||||
/* Find end of the section name */
|
||||
while(*InputData != ']' && *InputData != 0 && *InputData != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
InputData++;
|
||||
}
|
||||
|
||||
/* Check if end of the section name is reached */
|
||||
if(*InputData != ']')
|
||||
{
|
||||
/* Section name does not end */
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Mark end of the section name and advance to the next character */
|
||||
*InputData = 0;
|
||||
InputData++;
|
||||
|
||||
/* Remove leading and trailing spaces from section name */
|
||||
SectionName = RtlTrimString(SectionName);
|
||||
|
||||
/* Find length of the section name */
|
||||
SectionLength = RtlStringLength(SectionName, 0);
|
||||
|
||||
/* Allocate memory for new section */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_SECTION), (PVOID*)&Section);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Allocate more memory for section name */
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (SectionLength + 1), (PVOID*)&Section->SectionName);
|
||||
}
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Some memory allocation failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Initialize new section and add it to the list */
|
||||
RtlInitializeListHead(&Section->Options);
|
||||
RtlStringToWideString(Section->SectionName, &SectionName, SectionLength + 1);
|
||||
RtlInsertTailList(Configuration, &Section->Flink);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store key */
|
||||
Key = InputData;
|
||||
|
||||
/* Find end of the key */
|
||||
while(*InputData != '=' && *InputData != 0 && *InputData != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
InputData++;
|
||||
}
|
||||
|
||||
/* Check if end of the key is reached */
|
||||
if(*InputData != '=')
|
||||
{
|
||||
/* Key name does not end */
|
||||
return STATUS_EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Mark end of the key and advance to the next character */
|
||||
*InputData = 0;
|
||||
InputData++;
|
||||
|
||||
/* Skip all leading spaces in the value */
|
||||
while(*InputData == ' ')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
InputData++;
|
||||
}
|
||||
|
||||
/* Store value */
|
||||
Value = InputData;
|
||||
|
||||
/* Find end of the value */
|
||||
while(*InputData != 0 && *InputData != '\n')
|
||||
{
|
||||
/* Advance to the next character */
|
||||
InputData++;
|
||||
}
|
||||
|
||||
/* Mark end of the value and advance to the next character */
|
||||
*InputData = 0;
|
||||
InputData++;
|
||||
|
||||
/* Remove leading and trailing spaces from key and value */
|
||||
Key = RtlTrimString(Key);
|
||||
Value = RtlTrimString(Value);
|
||||
|
||||
/* Find length of the key and its value */
|
||||
KeyLength = RtlStringLength(Key, 0);
|
||||
ValueLength = RtlStringLength(Value, 0);
|
||||
|
||||
/* Allocate memory for new option */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_CONFIG_ENTRY), (PVOID*)&Option);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Allocate more memory for option name */
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (KeyLength + 1), (PVOID*)&Option->Name);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Allocate even more memory for option value */
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * (ValueLength + 1), (PVOID*)&Option->Value);
|
||||
}
|
||||
}
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Some memory allocation failed */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Remove leading quotes from the value */
|
||||
if(*Value == '"' || *Value == '\'')
|
||||
{
|
||||
Value++;
|
||||
}
|
||||
|
||||
/* Remove trailing quotes from the value */
|
||||
if(Value[ValueLength - 2] == '"' || Value[ValueLength - 2] == '\'')
|
||||
{
|
||||
Value[ValueLength - 2] = 0;
|
||||
}
|
||||
|
||||
/* Initialize new option and add it to the list */
|
||||
RtlStringToWideString(Option->Name, &Key, RtlStringLength(Key, 0) + 1);
|
||||
RtlStringToWideString(Option->Value, &Value, RtlStringLength(Value, 0) + 1);
|
||||
RtlInsertTailList(&Section->Options, &Option->Flink);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads configuration file from the specified directory on the FS0:/ drive.
|
||||
*
|
||||
* @param ConfigDirectory
|
||||
* Specifies a path to the directory containing the configuration file.
|
||||
*
|
||||
* @param ConfigFile
|
||||
* Specifies the name of the configuration file.
|
||||
*
|
||||
* @param ConfigData
|
||||
* Provides a buffer to store the data read from the configuration file.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory,
|
||||
IN CONST PWCHAR ConfigFile,
|
||||
OUT PCHAR *ConfigData)
|
||||
{
|
||||
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||
EFI_HANDLE DiskHandle;
|
||||
EFI_STATUS Status;
|
||||
SIZE_T FileSize;
|
||||
|
||||
/* Open EFI volume */
|
||||
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open a volume */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Open specified directory, containing the configuration file and close the FS immediately */
|
||||
Status = FsHandle->Open(FsHandle, &DirHandle, ConfigDirectory, EFI_FILE_MODE_READ, 0);
|
||||
FsHandle->Close(FsHandle);
|
||||
|
||||
/* Check if directory opened successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open directory */
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read configuration file and close directory */
|
||||
Status = BlReadFile(DirHandle, ConfigFile, (PVOID *)ConfigData, &FileSize);
|
||||
DirHandle->Close(DirHandle);
|
||||
|
||||
/* Close EFI volume */
|
||||
BlCloseVolume(DiskHandle);
|
||||
|
||||
/* Return read status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new XTLDR configuration entries to the global configuration list. Existing entries are not overwritten.
|
||||
*
|
||||
* @param NewConfig
|
||||
* Supplies a pointer to a linked list containing new configuration entries.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig)
|
||||
{
|
||||
PXTBL_CONFIG_ENTRY ConfigEntry;
|
||||
PLIST_ENTRY ConfigListEntry, NextListEntry;
|
||||
|
||||
/* Iterate through new config entries */
|
||||
ConfigListEntry = NewConfig->Flink;
|
||||
while(ConfigListEntry != NewConfig)
|
||||
{
|
||||
/* Get new config entry */
|
||||
ConfigEntry = CONTAIN_RECORD(ConfigListEntry, XTBL_CONFIG_ENTRY, Flink);
|
||||
|
||||
/* Get next config entry */
|
||||
NextListEntry = ConfigListEntry->Flink;
|
||||
|
||||
/* Make sure config entry does not exist yet */
|
||||
if(BlGetConfigValue(ConfigEntry->Name) == NULL)
|
||||
{
|
||||
/* Remove new config entry from input list and put it into global config list */
|
||||
RtlRemoveEntryList(&ConfigEntry->Flink);
|
||||
RtlInsertTailList(&BlpConfig, &ConfigEntry->Flink);
|
||||
}
|
||||
|
||||
/* Move to the next new config entry */
|
||||
ConfigListEntry = NextListEntry;
|
||||
}
|
||||
}
|
253
xtldr/console.c
253
xtldr/console.c
@ -6,9 +6,37 @@
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Clears a specified line on the UEFI text console.
|
||||
*
|
||||
* @param LineNo
|
||||
* Supplies a line number to clear.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlClearConsoleLine(IN ULONGLONG LineNo)
|
||||
{
|
||||
UINT_PTR Index, ResX, ResY;
|
||||
|
||||
/* Query console mode */
|
||||
BlQueryConsoleMode(&ResX, &ResY);
|
||||
|
||||
/* Set cursor position and clear line */
|
||||
BlSetCursorPosition(0, LineNo);
|
||||
for(Index = 0; Index < ResX; Index++)
|
||||
{
|
||||
/* Clear line */
|
||||
BlConsoleWrite(L" ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine clears the UEFI console screen.
|
||||
*
|
||||
@ -18,32 +46,233 @@
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleClearScreen()
|
||||
BlClearConsoleScreen()
|
||||
{
|
||||
/* Clear screen */
|
||||
EfiSystemTable->ConOut->ClearScreen(EfiSystemTable->ConOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the EFI console.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* Disables the cursor on the UEFI console.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleInitialize()
|
||||
BlDisableConsoleCursor()
|
||||
{
|
||||
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the cursor on the UEFI console.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlEnableConsoleCursor()
|
||||
{
|
||||
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it out to the stdout and serial console.
|
||||
*
|
||||
* @param Format
|
||||
* The formatted string that is to be written to the output.
|
||||
*
|
||||
* @param ...
|
||||
* Depending on the format string, this routine might expect a sequence of additional arguments.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsolePrint(IN PUINT16 Format,
|
||||
IN ...)
|
||||
{
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Format and print the string to the stdout */
|
||||
BlpStringPrint(BlpConsolePrintChar, Format, Arguments);
|
||||
|
||||
/* Print to serial console only if not running under OVMF */
|
||||
if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0)
|
||||
{
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
{
|
||||
/* Format and print the string to the serial console */
|
||||
BlpStringPrint(BlpDebugPutChar, Format, Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the string on the device at the current cursor location.
|
||||
*
|
||||
* @param String
|
||||
* The string to be displayed.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleWrite(IN PUSHORT String)
|
||||
{
|
||||
EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, String);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the EFI console.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeConsole()
|
||||
{
|
||||
/* Clear console buffers */
|
||||
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
|
||||
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
|
||||
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
|
||||
|
||||
/* Clear screen */
|
||||
BlConsoleClearScreen();
|
||||
/* Make sure that current console mode is 80x25 characters, as some broken EFI implementations might
|
||||
* set different mode that do not fit on the screen, causing a text to be displayed offscreen */
|
||||
if(EfiSystemTable->ConOut->Mode->Mode != 0)
|
||||
{
|
||||
/* Set console mode to 0, which is standard, 80x25 text mode */
|
||||
BlSetConsoleMode(0);
|
||||
}
|
||||
|
||||
/* Enable cursor */
|
||||
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE);
|
||||
/* Clear screen and enable cursor */
|
||||
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
BlClearConsoleScreen();
|
||||
BlEnableConsoleCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries information concerning the output device’s supported text mode.
|
||||
*
|
||||
* @param ResX
|
||||
* Supplies a buffer to receive the horizontal resolution.
|
||||
*
|
||||
* @param ResY
|
||||
* Supplies a buffer to receive the vertical resolution.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlQueryConsoleMode(OUT PUINT_PTR ResX,
|
||||
OUT PUINT_PTR ResY)
|
||||
{
|
||||
EfiSystemTable->ConOut->QueryMode(EfiSystemTable->ConOut, EfiSystemTable->ConOut->Mode->Mode, ResX, ResY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a keystroke from the input device.
|
||||
*
|
||||
* @param Key
|
||||
* Supplies a pointer to the EFI_INPUT_KEY structure that will receive the keystroke.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key)
|
||||
{
|
||||
EfiSystemTable->ConIn->ReadKeyStroke(EfiSystemTable->ConIn, Key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the console input device and clears its input buffer.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlResetConsoleInputBuffer()
|
||||
{
|
||||
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the foreground and background colors.
|
||||
*
|
||||
* @param Attribute
|
||||
* Specifies the foreground and background colors (bits 0..3 are fg, and bits 4..6 are bg color).
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetConsoleAttributes(IN ULONGLONG Attributes)
|
||||
{
|
||||
EfiSystemTable->ConOut->SetAttribute(EfiSystemTable->ConOut, Attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output console device to the requested mode.
|
||||
*
|
||||
* @param Mode
|
||||
* Supplies a text mode number to set.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetConsoleMode(IN ULONGLONG Mode)
|
||||
{
|
||||
return EfiSystemTable->ConOut->SetMode(EfiSystemTable->ConOut, Mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets new coordinates of the console cursor position.
|
||||
*
|
||||
* @param PosX
|
||||
* Specifies the new X coordinate of the cursor.
|
||||
*
|
||||
* @param PosY
|
||||
* Specifies the new Y coordinate of the cursor.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetCursorPosition(IN ULONGLONG PosX,
|
||||
IN ULONGLONG PosY)
|
||||
{
|
||||
EfiSystemTable->ConOut->SetCursorPosition(EfiSystemTable->ConOut, PosX, PosY);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,7 +287,7 @@ BlConsoleInitialize()
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsolePutChar(IN USHORT Character)
|
||||
BlpConsolePrintChar(IN USHORT Character)
|
||||
{
|
||||
USHORT Buffer[2];
|
||||
|
||||
|
263
xtldr/debug.c
Normal file
263
xtldr/debug.c
Normal file
@ -0,0 +1,263 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/debug.c
|
||||
* DESCRIPTION: XT Boot Loader debugging support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it out to the debug ports.
|
||||
*
|
||||
* @param Format
|
||||
* The formatted string that is to be written to the output.
|
||||
*
|
||||
* @param ...
|
||||
* Depending on the format string, this routine might expect a sequence of additional arguments.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDebugPrint(IN PUINT16 Format,
|
||||
IN ...)
|
||||
{
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Check if serial debug port is enabled */
|
||||
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
{
|
||||
/* Format and print the string to the serial console */
|
||||
BlpStringPrint(BlpDebugPutChar, Format, Arguments);
|
||||
}
|
||||
|
||||
/* Check if screen debug port is enabled and Boot Services are still available */
|
||||
if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE))
|
||||
{
|
||||
/* Format and print the string to the screen */
|
||||
BlpStringPrint(BlpConsolePrintChar, Format, Arguments);
|
||||
}
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the XTLDR debug console.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInitializeDebugConsole()
|
||||
{
|
||||
ULONG PortAddress, PortNumber, BaudRate;
|
||||
PWCHAR DebugConfiguration, DebugPort, LastPort;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Set default serial port options */
|
||||
PortAddress = 0;
|
||||
PortNumber = 0;
|
||||
BaudRate = 0;
|
||||
|
||||
/* Get debug configuration */
|
||||
DebugConfiguration = BlGetConfigValue(L"DEBUG");
|
||||
|
||||
/* Make sure any debug options are provided and debug console is not initialized yet */
|
||||
if(DebugConfiguration && BlpStatus.DebugPort == 0)
|
||||
{
|
||||
/* Find all debug ports */
|
||||
DebugPort = RtlTokenizeWideString(DebugConfiguration, L";", &LastPort);
|
||||
|
||||
/* Iterate over all debug ports */
|
||||
while(DebugPort != NULL)
|
||||
{
|
||||
/* Check what port is set for debugging */
|
||||
if(RtlCompareWideStringInsensitive(DebugPort, L"COM", 3) == 0)
|
||||
{
|
||||
/* Read COM port number */
|
||||
DebugPort += 3;
|
||||
while(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
/* Get port number */
|
||||
PortNumber *= 10;
|
||||
PortNumber += *DebugPort - '0';
|
||||
DebugPort++;
|
||||
}
|
||||
|
||||
/* Check if custom COM port address supplied */
|
||||
if(PortNumber == 0 && RtlCompareWideStringInsensitive(DebugPort, L":0x", 3) == 0)
|
||||
{
|
||||
/* COM port address provided */
|
||||
DebugPort += 3;
|
||||
while((*DebugPort >= '0' && *DebugPort <= '9') ||
|
||||
(*DebugPort >= 'A' && *DebugPort <= 'F') ||
|
||||
(*DebugPort >= 'a' && *DebugPort <= 'f'))
|
||||
{
|
||||
/* Get port address */
|
||||
PortAddress *= 16;
|
||||
if(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
PortAddress += *DebugPort - '0';
|
||||
}
|
||||
else if(*DebugPort >= 'A' && *DebugPort <= 'F')
|
||||
{
|
||||
PortAddress += *DebugPort - 'A' + 10;
|
||||
}
|
||||
else if(*DebugPort >= 'a' && *DebugPort <= 'f')
|
||||
{
|
||||
PortAddress += *DebugPort - 'a' + 10;
|
||||
}
|
||||
DebugPort++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for additional COM port parameters */
|
||||
if(*DebugPort == ',')
|
||||
{
|
||||
/* Baud rate provided */
|
||||
DebugPort++;
|
||||
while(*DebugPort >= '0' && *DebugPort <= '9')
|
||||
{
|
||||
/* Get baud rate */
|
||||
BaudRate *= 10;
|
||||
BaudRate += *DebugPort - '0';
|
||||
DebugPort++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable debug port */
|
||||
BlpStatus.DebugPort |= XTBL_DEBUGPORT_SERIAL;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(DebugPort, L"SCREEN", 5) == 0)
|
||||
{
|
||||
/* Enable debug port */
|
||||
BlpStatus.DebugPort |= XTBL_DEBUGPORT_SCREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unsupported debug port specified */
|
||||
BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
|
||||
BlSleepExecution(3000);
|
||||
}
|
||||
|
||||
/* Take next debug port */
|
||||
DebugPort = RtlTokenizeWideString(NULL, L";", &LastPort);
|
||||
}
|
||||
|
||||
/* Check if serial debug port is enabled */
|
||||
if(BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL)
|
||||
{
|
||||
/* Try to initialize COM port */
|
||||
Status = BlpInitializeSerialPort(PortNumber, PortAddress, BaudRate);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Remove serial debug port, as COM port initialization failed and return */
|
||||
BlpStatus.DebugPort &= ~XTBL_DEBUGPORT_SERIAL;
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the serial debug console.
|
||||
*
|
||||
* @param PortNumber
|
||||
* Supplies a port number.
|
||||
*
|
||||
* @param PortAddress
|
||||
* Supplies an address of the COM port.
|
||||
*
|
||||
* @param BaudRate
|
||||
* Supplies an optional port baud rate.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInitializeSerialPort(IN ULONG PortNumber,
|
||||
IN ULONG PortAddress,
|
||||
IN ULONG BaudRate)
|
||||
{
|
||||
EFI_STATUS EfiStatus;
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Print debug message depending on port settings */
|
||||
if(PortAddress)
|
||||
{
|
||||
BlConsolePrint(L"Initializing serial console at COM port address: 0x%lx\n", PortAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber);
|
||||
}
|
||||
|
||||
/* Initialize COM port */
|
||||
Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
|
||||
|
||||
/* Port not found under supplied address */
|
||||
if(Status == STATUS_NOT_FOUND && PortAddress)
|
||||
{
|
||||
/* This might be PCI(E) serial controller, try to activate I/O space access first */
|
||||
EfiStatus = BlpActivateSerialIOController();
|
||||
if(EfiStatus == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Try to reinitialize COM port */
|
||||
BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
|
||||
Status = HlInitializeComPort(&BlpStatus.SerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check COM port initialization status code */
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Serial port initialization failed, mark as not ready */
|
||||
return STATUS_EFI_NOT_READY;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a character to the serial console.
|
||||
*
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDebugPutChar(IN USHORT Character)
|
||||
{
|
||||
USHORT Buffer[2];
|
||||
|
||||
/* Write character to the serial console */
|
||||
Buffer[0] = Character;
|
||||
Buffer[1] = 0;
|
||||
|
||||
HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]);
|
||||
}
|
364
xtldr/efiutil.c
364
xtldr/efiutil.c
@ -1,364 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/efiutil.c
|
||||
* DESCRIPTION: EFI utilities
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
|
||||
|
||||
/**
|
||||
* Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlActivateSerialControllerIO()
|
||||
{
|
||||
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
|
||||
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
|
||||
USHORT Bus, Device, Function, Command;
|
||||
UINT_PTR Index, PciHandleSize;
|
||||
PEFI_HANDLE PciHandle = NULL;
|
||||
PCI_COMMON_HEADER PciHeader;
|
||||
EFI_STATUS Status;
|
||||
UINT64 Address;
|
||||
|
||||
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
|
||||
PciHandleSize = sizeof(EFI_HANDLE);
|
||||
Status = BlEfiMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get all instances of PciRootBridgeIo */
|
||||
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle);
|
||||
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* Reallocate more memory as requested by UEFI */
|
||||
BlEfiMemoryFreePool(PciHandle);
|
||||
Status = BlEfiMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory reallocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Second attempt to get instances of PciRootBridgeIo */
|
||||
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle);
|
||||
}
|
||||
|
||||
/* Make sure successfully obtained PciRootBridgeIo instances */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get PciRootBridgeIo instances */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
|
||||
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
|
||||
{
|
||||
/* Get inferface from the protocol */
|
||||
Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get interface */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate whole PCI bridge */
|
||||
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
|
||||
{
|
||||
/* Enumerate all devices for each bus */
|
||||
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
|
||||
{
|
||||
/* Enumerate all functions for each devices */
|
||||
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
|
||||
{
|
||||
/* Read configuration space */
|
||||
Address = ((UINT64)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
|
||||
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
|
||||
PciDev->Pci.Read(PciDev, 2, Address, sizeof (PciHeader) / sizeof (UINT32), &PciHeader);
|
||||
|
||||
/* Check if device exists */
|
||||
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
|
||||
{
|
||||
/* Skip non-existen device */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if device is serial controller or multiport serial controller */
|
||||
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
|
||||
{
|
||||
/* Enable I/O space access */
|
||||
Address |= 0x4;
|
||||
Command = PCI_ENABLE_IO_SPACE;
|
||||
Status = PciDev->Pci.Write(PciDev, 1, Address, 1, &Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return SUCCESS */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the COM port debug console.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlComPortInitialize()
|
||||
{
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
ULONG PortAddress, PortNumber, BaudRate;
|
||||
PWCHAR Argument, CommandLine, LastArg;
|
||||
EFI_STATUS EfiStatus;
|
||||
XTSTATUS Status;
|
||||
|
||||
/* Set default serial port options */
|
||||
PortAddress = 0;
|
||||
PortNumber = 0;
|
||||
BaudRate = 0;
|
||||
|
||||
/* Handle loaded image protocol */
|
||||
EfiStatus = EfiSystemTable->BootServices->HandleProtocol(EfiImageHandle, &LIPGuid, (PVOID *)&LoadedImage);
|
||||
if(EfiStatus == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
|
||||
/* Check if launched from UEFI shell */
|
||||
if(LoadedImage && LoadedImage->LoadOptions)
|
||||
{
|
||||
/* Store arguments passed from UEFI shell */
|
||||
CommandLine = (PWCHAR)LoadedImage->LoadOptions;
|
||||
|
||||
/* Find command in command line */
|
||||
Argument = RtlTokenizeWideString(CommandLine, L" ", &LastArg);
|
||||
|
||||
/* Iterate over all arguments passed to boot loader */
|
||||
while(Argument != NULL)
|
||||
{
|
||||
/* Check if this is DEBUG parameter */
|
||||
if(RtlCompareWideString(Argument, L"DEBUG=", 6) == 0)
|
||||
{
|
||||
/* Skip to the argument value */
|
||||
Argument += 6;
|
||||
|
||||
/* Make sure COM port is being used */
|
||||
if(RtlCompareWideString(Argument, L"COM", 3))
|
||||
{
|
||||
/* Invalid debug port specified */
|
||||
BlEfiPrint(L"ERROR: Invalid debug port specified, falling back to defaults\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read COM port number */
|
||||
Argument += 3;
|
||||
while(*Argument >= '0' && *Argument <= '9')
|
||||
{
|
||||
/* Get port number */
|
||||
PortNumber *= 10;
|
||||
PortNumber += *Argument - '0';
|
||||
Argument++;
|
||||
}
|
||||
|
||||
/* Check if custom COM port address supplied */
|
||||
if(PortNumber == 0 && RtlCompareWideString(Argument, L":0x", 3) == 0)
|
||||
{
|
||||
/* COM port address provided */
|
||||
Argument += 3;
|
||||
while((*Argument >= '0' && *Argument <= '9') ||
|
||||
(*Argument >= 'A' && *Argument <= 'F') ||
|
||||
(*Argument >= 'a' && *Argument <= 'f'))
|
||||
{
|
||||
/* Get port address */
|
||||
PortAddress *= 16;
|
||||
if(*Argument >= '0' && *Argument <= '9')
|
||||
{
|
||||
PortAddress += *Argument - '0';
|
||||
}
|
||||
else if(*Argument >= 'A' && *Argument <= 'F')
|
||||
{
|
||||
PortAddress += *Argument - 'A' + 10;
|
||||
}
|
||||
else if(*Argument >= 'a' && *Argument <= 'f')
|
||||
{
|
||||
PortAddress += *Argument - 'a' + 10;
|
||||
}
|
||||
Argument++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for additional COM port parameters */
|
||||
if(*Argument == ',')
|
||||
{
|
||||
/* Baud rate provided */
|
||||
Argument++;
|
||||
while(*Argument >= '0' && *Argument <= '9')
|
||||
{
|
||||
/* Get baud rate */
|
||||
BaudRate *= 10;
|
||||
BaudRate += *Argument - '0';
|
||||
Argument++;
|
||||
}
|
||||
}
|
||||
|
||||
/* No need to check next arguments */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Take next argument */
|
||||
Argument = RtlTokenizeWideString(NULL, L" ", &LastArg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Print debug message depending on port settings */
|
||||
if(PortAddress)
|
||||
{
|
||||
BlEfiPrint(L"Initializing serial console at COM port address: 0x%lx\n", PortAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlEfiPrint(L"Initializing serial console at port COM%d\n", PortNumber);
|
||||
}
|
||||
|
||||
/* Initialize COM port */
|
||||
Status = HlInitializeComPort(&EfiSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
|
||||
|
||||
/* Port not found under supplied address */
|
||||
if(Status == STATUS_NOT_FOUND && PortAddress)
|
||||
{
|
||||
/* This might be PCI(E) serial controller, try to activate I/O space access first */
|
||||
EfiStatus = BlActivateSerialControllerIO();
|
||||
if(EfiStatus == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Try to reinitialize COM port */
|
||||
BlEfiPrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
|
||||
Status = HlInitializeComPort(&EfiSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check COM port initialization status code */
|
||||
if(Status != STATUS_SUCCESS)
|
||||
{
|
||||
/* Serial port initialization failed, mark as not ready */
|
||||
return STATUS_EFI_NOT_READY;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a character to the serial console.
|
||||
*
|
||||
* @param Character
|
||||
* The integer promotion of the character to be written.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlComPortPutChar(IN USHORT Character)
|
||||
{
|
||||
USHORT Buffer[2];
|
||||
|
||||
/* Write character to the serial console */
|
||||
Buffer[0] = Character;
|
||||
Buffer[1] = 0;
|
||||
|
||||
HlComPortPutByte(&EfiSerialPort, Buffer[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it out to the serial console.
|
||||
*
|
||||
* @param Format
|
||||
* The formatted string that is to be written to the output.
|
||||
*
|
||||
* @param ...
|
||||
* Depending on the format string, this routine might expect a sequence of additional arguments.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDbgPrint(IN PUINT16 Format,
|
||||
IN ...)
|
||||
{
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG && (EfiSerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
{
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Format and print the string to the serial console */
|
||||
BlStringPrint(BlComPortPutChar, Format, Arguments);
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it out to the stdout and serial console.
|
||||
*
|
||||
* @param Format
|
||||
* The formatted string that is to be written to the output.
|
||||
*
|
||||
* @param ...
|
||||
* Depending on the format string, this routine might expect a sequence of additional arguments.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*
|
||||
* @todo Check if GOP is active and use it instead of default conout protocol
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlEfiPrint(IN PUINT16 Format,
|
||||
IN ...)
|
||||
{
|
||||
VA_LIST Arguments;
|
||||
|
||||
/* Initialise the va_list */
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Format and print the string to the stdout */
|
||||
BlStringPrint(BlConsolePutChar, Format, Arguments);
|
||||
|
||||
/* Print to serial console only if not running under OVMF */
|
||||
if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0)
|
||||
{
|
||||
/* Check if debugging enabled and if EFI serial port is fully initialized */
|
||||
if(DEBUG && (EfiSerialPort.Flags & COMPORT_FLAG_INIT))
|
||||
{
|
||||
/* Format and print the string to the serial console */
|
||||
BlStringPrint(BlComPortPutChar, Format, Arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
}
|
120
xtldr/efiutils.c
Normal file
120
xtldr/efiutils.c
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/efiutils.c
|
||||
* DESCRIPTION: EFI related routines for XT Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Exits EFI boot services.
|
||||
*
|
||||
* @param MapKey
|
||||
* Identifies the current memory map of the system.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlExitBootServices(IN UINT_PTR MapKey)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Attempt to exit boot services */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Retry as UEFI spec says to do it twice */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MapKey);
|
||||
}
|
||||
|
||||
/* Make sure boot services were successfully exited */
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mark EFI Boot Services as no longer available */
|
||||
BlpStatus.BootServices = FALSE;
|
||||
}
|
||||
|
||||
/* Return EFI status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether SecureBoot is enabled or not.
|
||||
*
|
||||
* @return Numeric representation of SecureBoot status (0 = Disabled, >0 = Enabled, <0 SetupMode).
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
BlGetSecureBootStatus()
|
||||
{
|
||||
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
INT_PTR SecureBootStatus = 0;
|
||||
UCHAR VarValue = 0;
|
||||
UINT_PTR Size;
|
||||
|
||||
Size = sizeof(VarValue);
|
||||
if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
SecureBootStatus = (INT_PTR)VarValue;
|
||||
|
||||
if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)
|
||||
{
|
||||
SecureBootStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return SecureBoot status */
|
||||
return SecureBootStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the system to sleep for the specified number of milliseconds.
|
||||
*
|
||||
* @param Milliseconds
|
||||
* Supplies the number of milliseconds to sleep.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSleepExecution(IN ULONG_PTR Milliseconds)
|
||||
{
|
||||
EfiSystemTable->BootServices->Stall(Milliseconds * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for one or more EFI events.
|
||||
*
|
||||
* @param NumberOfEvents
|
||||
* Supplies the number of events to wait for.
|
||||
*
|
||||
* @param Event
|
||||
* Supplies the array of events to wait for.
|
||||
*
|
||||
* @param Index
|
||||
* Receives the index of the event that was signaled.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents,
|
||||
IN PEFI_EVENT Event,
|
||||
OUT PUINT_PTR Index)
|
||||
{
|
||||
return EfiSystemTable->BootServices->WaitForEvent(NumberOfEvents, Event, Index);
|
||||
}
|
@ -6,26 +6,38 @@
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/* XT Boot Loader registered boot protocol list */
|
||||
LIST_ENTRY BlpBootProtocols;
|
||||
|
||||
/* XT Boot Loader configuration list */
|
||||
LIST_ENTRY BlpConfig;
|
||||
|
||||
/* XT Boot Loader loaded configuration */
|
||||
LIST_ENTRY BlpConfigSections;
|
||||
|
||||
/* XT Boot Loader hex table */
|
||||
STATIC PUINT16 BlpHexTable = L"0123456789ABCDEF";
|
||||
|
||||
/* XT Boot Loader protocol */
|
||||
XTBL_LOADER_PROTOCOL BlpLdrProtocol;
|
||||
|
||||
/* XT Boot Loader loaded modules list */
|
||||
LIST_ENTRY BlpLoadedModules;
|
||||
|
||||
/* XT Boot Loader menu list */
|
||||
PLIST_ENTRY BlpMenuList = NULL;
|
||||
|
||||
/* XT Boot Loader status data */
|
||||
XTBL_STATUS BlpStatus = {0};
|
||||
|
||||
/* List of available block devices */
|
||||
LIST_ENTRY EfiBlockDevices;
|
||||
|
||||
/* XT Boot Loader hex table */
|
||||
STATIC PUINT16 EfiHexTable = L"0123456789ABCDEF";
|
||||
|
||||
/* EFI Image Handle */
|
||||
EFI_HANDLE EfiImageHandle;
|
||||
|
||||
/* XT Boot Loader protocol */
|
||||
XT_BOOT_LOADER_PROTOCOL EfiLdrProtocol;
|
||||
|
||||
/* EFI System Table */
|
||||
PEFI_SYSTEM_TABLE EfiSystemTable;
|
||||
|
||||
/* EFI Secure Boot status */
|
||||
INT_PTR EfiSecureBoot;
|
||||
|
||||
/* Serial port configuration */
|
||||
CPPORT EfiSerialPort;
|
||||
|
112
xtldr/hardware.c
Normal file
112
xtldr/hardware.c
Normal file
@ -0,0 +1,112 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/hardware.c
|
||||
* DESCRIPTION: EFI hardware support for XT Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Enables I/O space access to all serial controllers found on the PCI(E) root bridge.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpActivateSerialIOController()
|
||||
{
|
||||
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
|
||||
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;
|
||||
USHORT Bus, Device, Function, Command;
|
||||
UINT_PTR Index, PciHandleSize;
|
||||
PEFI_HANDLE PciHandle = NULL;
|
||||
PCI_COMMON_HEADER PciHeader;
|
||||
EFI_STATUS Status;
|
||||
UINT64 Address;
|
||||
|
||||
/* Allocate memory for single EFI_HANDLE, what should be enough in most cases */
|
||||
PciHandleSize = sizeof(EFI_HANDLE);
|
||||
Status = BlMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get all instances of PciRootBridgeIo */
|
||||
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle);
|
||||
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* Reallocate more memory as requested by UEFI */
|
||||
BlMemoryFreePool(PciHandle);
|
||||
Status = BlMemoryAllocatePool(PciHandleSize, (PVOID*)&PciHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory reallocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Second attempt to get instances of PciRootBridgeIo */
|
||||
Status = EfiSystemTable->BootServices->LocateHandle(ByProtocol, &PciGuid, NULL, &PciHandleSize, PciHandle);
|
||||
}
|
||||
|
||||
/* Make sure successfully obtained PciRootBridgeIo instances */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get PciRootBridgeIo instances */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate all devices for each handle, which decides a segment and a bus number range */
|
||||
for(Index = 0; Index < (PciHandleSize / sizeof(EFI_HANDLE)); Index++)
|
||||
{
|
||||
/* Get inferface from the protocol */
|
||||
Status = EfiSystemTable->BootServices->HandleProtocol(PciHandle[Index], &PciGuid, (PVOID*)&PciDev);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get interface */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Enumerate whole PCI bridge */
|
||||
for(Bus = 0; Bus <= PCI_MAX_BRIDGE_NUMBER; Bus++)
|
||||
{
|
||||
/* Enumerate all devices for each bus */
|
||||
for(Device = 0; Device < PCI_MAX_DEVICES; Device++)
|
||||
{
|
||||
/* Enumerate all functions for each devices */
|
||||
for(Function = 0; Function < PCI_MAX_FUNCTION; Function++)
|
||||
{
|
||||
/* Read configuration space */
|
||||
Address = ((UINT64)((((UINT_PTR) Bus) << 24) + (((UINT_PTR) Device) << 16) +
|
||||
(((UINT_PTR) Function) << 8) + ((UINT_PTR) 0)));
|
||||
PciDev->Pci.Read(PciDev, 2, Address, sizeof (PciHeader) / sizeof (UINT32), &PciHeader);
|
||||
|
||||
/* Check if device exists */
|
||||
if(PciHeader.VendorId == PCI_INVALID_VENDORID)
|
||||
{
|
||||
/* Skip non-existen device */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if device is serial controller or multiport serial controller */
|
||||
if(PciHeader.BaseClass == 0x07 && (PciHeader.SubClass == 0x00 || PciHeader.SubClass == 0x02))
|
||||
{
|
||||
/* Enable I/O space access */
|
||||
Address |= 0x4;
|
||||
Command = PCI_ENABLE_IO_SPACE;
|
||||
Status = PciDev->Pci.Write(PciDev, 1, Address, 1, &Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return SUCCESS */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/bldefs.h
|
||||
* DESCRIPTION: Definitions for the XT boot loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_BLDEFS_H
|
||||
#define __XTLDR_BLDEFS_H
|
||||
|
||||
#include <xtkmapi.h>
|
||||
|
||||
|
||||
/* EFI XT boot devices */
|
||||
#define XT_BOOT_DEVICE_UNKNOWN 0x00
|
||||
#define XT_BOOT_DEVICE_CDROM 0x01
|
||||
#define XT_BOOT_DEVICE_FLOPPY 0x02
|
||||
#define XT_BOOT_DEVICE_HARDDISK 0x03
|
||||
#define XT_BOOT_DEVICE_RAMDISK 0x04
|
||||
|
||||
#endif /* __XTLDR_BLDEFS_H */
|
@ -1,94 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/blmod.h
|
||||
* DESCRIPTION: Top level header for XTLDR modules support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_BLMOD_H
|
||||
#define __XTLDR_BLMOD_H
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <bldefs.h>
|
||||
#include <blproto.h>
|
||||
|
||||
|
||||
/* Structures forward declarations */
|
||||
typedef struct _XT_BOOT_PROTOCOL XT_BOOT_PROTOCOL, *PXT_BOOT_PROTOCOL;
|
||||
typedef struct _XT_BOOT_PROTOCOL_PARAMETERS XT_BOOT_PROTOCOL_PARAMETERS, *PXT_BOOT_PROTOCOL_PARAMETERS;
|
||||
typedef struct _XT_PECOFFF_IMAGE_PROTOCOL XT_PECOFF_IMAGE_PROTOCOL, *PXT_PECOFF_IMAGE_PROTOCOL;
|
||||
|
||||
/* Pointers to the routines provided by the modules */
|
||||
typedef EFI_STATUS (*PXT_BOOTPROTO_BOOT_SYSTEM)(IN PXT_BOOT_PROTOCOL_PARAMETERS Parameters);
|
||||
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)();
|
||||
typedef EFI_STATUS (*PXT_PECOFF_GET_ENTRY_POINT)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PVOID *EntryPoint);
|
||||
typedef EFI_STATUS (*PXT_PECOFF_GET_MACHINE_TYPE)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PUSHORT MachineType);
|
||||
typedef EFI_STATUS (*PXT_PECOFF_GET_SUBSYSTEM)(IN PPECOFF_IMAGE_CONTEXT Image, OUT PUSHORT SubSystem);
|
||||
typedef EFI_STATUS (*PXT_PECOFF_LOAD_IMAGE)(IN PEFI_FILE_HANDLE FileHandle, IN LOADER_MEMORY_TYPE MemoryType,
|
||||
IN PVOID VirtualAddress, OUT PPECOFF_IMAGE_CONTEXT *Image);
|
||||
typedef EFI_STATUS (*PXT_PECOFF_RELOCATE_IMAGE)(IN PPECOFF_IMAGE_CONTEXT Image, IN EFI_VIRTUAL_ADDRESS Address);
|
||||
|
||||
|
||||
/* XT common boot protocols */
|
||||
typedef struct _XT_BOOT_PROTOCOL
|
||||
{
|
||||
PXT_BOOTPROTO_BOOT_SYSTEM BootSystem;
|
||||
} XT_BOOT_PROTOCOL, *PXT_BOOT_PROTOCOL;
|
||||
|
||||
/* XT common boot protocol parameters */
|
||||
typedef struct _XT_BOOT_PROTOCOL_PARAMETERS
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL DevicePath;
|
||||
PWCHAR ArcName;
|
||||
PWCHAR SystemPath;
|
||||
PWCHAR KernelFile;
|
||||
PWCHAR InitrdFile;
|
||||
PWCHAR HalFile;
|
||||
PWCHAR Arguments;
|
||||
} XT_BOOT_PROTOCOL_PARAMETERS, *PXT_BOOT_PROTOCOL_PARAMETERS;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* EFI XT PE/COFF Image Protocol */
|
||||
typedef struct _XT_PECOFFF_IMAGE_PROTOCOL
|
||||
{
|
||||
PXT_PECOFF_GET_ENTRY_POINT GetEntryPoint;
|
||||
PXT_PECOFF_GET_MACHINE_TYPE GetMachineType;
|
||||
PXT_PECOFF_GET_SUBSYSTEM GetSubSystem;
|
||||
PXT_PECOFF_LOAD_IMAGE Load;
|
||||
PXT_PECOFF_RELOCATE_IMAGE Relocate;
|
||||
} XT_PECOFF_IMAGE_PROTOCOL, *PXT_PECOFF_IMAGE_PROTOCOL;
|
||||
|
||||
#endif /* __XTLDR_BLMOD_H */
|
@ -1,62 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/blproto.h
|
||||
* DESCRIPTION: XTLDR boot loader protocol support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_BLPROTO_H
|
||||
#define __XTLDR_BLPROTO_H
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <bldefs.h>
|
||||
|
||||
|
||||
/* Loader protocol routine pointers */
|
||||
typedef EFI_STATUS (*PBL_ADD_VIRTUAL_MEMORY_MAPPING)(IN PLIST_ENTRY MemoryMappings, IN PVOID VirtualAddress, IN PVOID PhysicalAddress, IN UINT NumberOfPages, IN LOADER_MEMORY_TYPE MemoryType);
|
||||
typedef EFI_STATUS (*PBL_ALLOCATE_PAGES)(IN UINT64 Size, OUT PEFI_PHYSICAL_ADDRESS Memory);
|
||||
typedef EFI_STATUS (*PBL_ALLOCATE_POOL)(IN UINT_PTR Size, OUT PVOID *Memory);
|
||||
typedef EFI_STATUS (*PBL_ENABLE_PAGING)(IN PLIST_ENTRY MemoryMappings, IN PVOID VirtualAddress, IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol, IN PVOID *PtePointer);
|
||||
typedef EFI_STATUS (*PBL_FREE_PAGES)(IN UINT64 Size, IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
typedef EFI_STATUS (*PBL_FREE_POOL)(IN PVOID Memory);
|
||||
typedef EFI_STATUS (*PBL_GET_MEMORY_MAP)(OUT PEFI_MEMORY_MAP MemoryMap);
|
||||
typedef EFI_STATUS (*PBL_GET_VIRTUAL_ADDRESS)(IN PLIST_ENTRY MemoryMappings, IN PVOID PhysicalAddress, OUT PVOID *VirtualAddress);
|
||||
typedef EFI_STATUS (*PBL_INIT_VIRTUAL_MEMORY)(IN OUT PLIST_ENTRY MemoryMappings, IN OUT PVOID *MemoryMapAddress);
|
||||
typedef EFI_STATUS (*PBL_MAP_VIRTUAL_MEMORY)(IN PLIST_ENTRY MemoryMappings, IN UINT_PTR VirtualAddress, IN UINT_PTR PhysicalAddress, IN UINT NumberOfPages, IN OUT PVOID *PtePointer);
|
||||
typedef VOID (*PBL_GET_STACK)(OUT PVOID *Stack);
|
||||
typedef VOID (*PBL_DBG_PRINT)(IN PUINT16 Format, IN ...);
|
||||
typedef VOID (*PBL_EFI_PRINT)(IN PUINT16 Format, IN ...);
|
||||
typedef EFI_STATUS (*PBL_CLOSE_VOLUME)(IN PEFI_HANDLE VolumeHandle);
|
||||
typedef EFI_STATUS (*PBL_OPEN_VOLUME)(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath, OUT PEFI_HANDLE DiskHandle, OUT PEFI_FILE_HANDLE *FsHandle);
|
||||
|
||||
/* EFI XT Boot Loader Protocol */
|
||||
typedef struct _XT_BOOT_LOADER_PROTOCOL
|
||||
{
|
||||
PBL_ADD_VIRTUAL_MEMORY_MAPPING AddVirtualMemoryMapping;
|
||||
PBL_ALLOCATE_PAGES AllocatePages;
|
||||
PBL_ALLOCATE_POOL AllocatePool;
|
||||
PBL_FREE_PAGES FreePages;
|
||||
PBL_FREE_POOL FreePool;
|
||||
PBL_ENABLE_PAGING EnablePaging;
|
||||
PBL_GET_MEMORY_MAP GetMemoryMap;
|
||||
PBL_GET_VIRTUAL_ADDRESS GetVirtualAddress;
|
||||
PBL_INIT_VIRTUAL_MEMORY InitializeVirtualMemory;
|
||||
PBL_MAP_VIRTUAL_MEMORY MapVirtualMemory;
|
||||
PBL_DBG_PRINT DbgPrint;
|
||||
PBL_EFI_PRINT EfiPrint;
|
||||
PBL_CLOSE_VOLUME CloseVolume;
|
||||
PBL_OPEN_VOLUME OpenVolume;
|
||||
} XT_BOOT_LOADER_PROTOCOL, *PXT_BOOT_LOADER_PROTOCOL;
|
||||
|
||||
/* Loader protocol related routines forward references */
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetXtLoaderProtocol(OUT PXT_BOOT_LOADER_PROTOCOL *LdrProtocol);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadXtProtocol(OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
|
||||
#endif /* __XTLDR_BLPROTO_H */
|
48
xtldr/includes/globals.h
Normal file
48
xtldr/includes/globals.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/globals.h
|
||||
* DESCRIPTION: XTLDR global variables
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_GLOBALS_H
|
||||
#define __XTLDR_GLOBALS_H
|
||||
|
||||
#include <xtblapi.h>
|
||||
|
||||
|
||||
/* XT Boot Loader registered boot protocol list */
|
||||
EXTERN LIST_ENTRY BlpBootProtocols;
|
||||
|
||||
/* XT Boot Loader configuration list */
|
||||
EXTERN LIST_ENTRY BlpConfig;
|
||||
|
||||
/* XT Boot Loader loaded configuration */
|
||||
EXTERN LIST_ENTRY BlpConfigSections;
|
||||
|
||||
/* XT Boot Loader hex table */
|
||||
EXTERN PUINT16 BlpHexTable;
|
||||
|
||||
/* XT Boot Loader protocol */
|
||||
EXTERN XTBL_LOADER_PROTOCOL BlpLdrProtocol;
|
||||
|
||||
/* XT Boot Loader loaded modules list */
|
||||
EXTERN LIST_ENTRY BlpLoadedModules;
|
||||
|
||||
/* XT Boot Loader menu list */
|
||||
EXTERN PLIST_ENTRY BlpMenuList;
|
||||
|
||||
/* XT Boot Loader status data */
|
||||
EXTERN XTBL_STATUS BlpStatus;
|
||||
|
||||
/* List of available block devices */
|
||||
EXTERN LIST_ENTRY EfiBlockDevices;
|
||||
|
||||
/* EFI Image Handle */
|
||||
EXTERN EFI_HANDLE EfiImageHandle;
|
||||
|
||||
/* EFI System Table */
|
||||
EXTERN PEFI_SYSTEM_TABLE EfiSystemTable;
|
||||
|
||||
#endif /* __XTLDR_GLOBALS_H */
|
@ -1,264 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/xtbl.h
|
||||
* DESCRIPTION: Top level header for XTLDR
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_XTBL_H
|
||||
#define __XTLDR_XTBL_H
|
||||
|
||||
#include <xtkmapi.h>
|
||||
#include <xtver.h>
|
||||
#include <blmod.h>
|
||||
|
||||
|
||||
/* List of available block devices */
|
||||
EXTERN LIST_ENTRY EfiBlockDevices;
|
||||
|
||||
/* XT Boot Loader hex table */
|
||||
EXTERN PUINT16 EfiHexTable;
|
||||
|
||||
/* EFI Image Handle */
|
||||
EXTERN EFI_HANDLE EfiImageHandle;
|
||||
|
||||
/* XT Boot Loader protocol */
|
||||
EXTERN XT_BOOT_LOADER_PROTOCOL EfiLdrProtocol;
|
||||
|
||||
/* EFI System Table */
|
||||
EXTERN PEFI_SYSTEM_TABLE EfiSystemTable;
|
||||
|
||||
/* EFI Secure Boot status */
|
||||
EXTERN INT_PTR EfiSecureBoot;
|
||||
|
||||
/* New bootloader stack */
|
||||
EXTERN PVOID EfiLoaderStack;
|
||||
|
||||
/* Serial port configuration */
|
||||
EXTERN CPPORT EfiSerialPort;
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlActivateSerialControllerIO();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlAddVirtualMemoryMapping(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PVOID PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN LOADER_MEMORY_TYPE MemoryType);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlCloseVolume(IN PEFI_HANDLE VolumeHandle);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlComPortInitialize();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlComPortPutChar(IN USHORT Character);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleClearScreen();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleInitialize();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsolePutChar(IN USHORT Character);
|
||||
|
||||
XTCDECL
|
||||
LOADER_MEMORY_TYPE
|
||||
BlConvertEfiMemoryType(IN EFI_MEMORY_TYPE EfiMemoryType);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDbgPrint(IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
BlEfiGetSecureBootStatus();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiGetSystemConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
OUT PVOID *Table);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryAllocatePages(IN UINT64 Size,
|
||||
OUT PEFI_PHYSICAL_ADDRESS Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryAllocatePool(IN UINT_PTR Size,
|
||||
OUT PVOID *Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryFreePages(IN UINT64 Size,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryFreePool(IN PVOID Memory);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlEfiPrint(IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
|
||||
IN PVOID *PtePointer);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnumerateEfiBlockDevices();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
IN CONST PWCHAR FileSystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVolumeDevicePath(IN PUCHAR SystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
OUT PUCHAR *ArcName,
|
||||
OUT PUCHAR *Path);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
|
||||
IN OUT PVOID *MemoryMapAddress);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadEfiModules();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadXtSystem();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
IN UINT_PTR VirtualAddress,
|
||||
IN UINT_PTR PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
IN OUT PVOID *PtePointer);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_HANDLE DiskHandle,
|
||||
OUT PEFI_FILE_HANDLE *FsHandle);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlRegisterXtLoaderProtocol();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
|
||||
XTCDECL
|
||||
INT
|
||||
BlStringCompareInsensitive(IN PUCHAR String1,
|
||||
IN PUCHAR String2);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
IN PUINT16 Format,
|
||||
IN VA_LIST Arguments);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
OUT PUCHAR *ArcName,
|
||||
OUT PUCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber);
|
||||
|
||||
XTCDECL
|
||||
PEFI_DEVICE_PATH_PROTOCOL
|
||||
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);
|
||||
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
BlpFindParentEfiBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA ParentNode);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringFormat(IN VOID PutChar(IN USHORT Character),
|
||||
IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character),
|
||||
IN INT32 Number,
|
||||
IN UINT32 Base);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character),
|
||||
IN INT_PTR Number,
|
||||
IN UINT_PTR Base);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character),
|
||||
IN UINT32 Number,
|
||||
IN UINT32 Base,
|
||||
IN UINT32 Padding);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character),
|
||||
IN UINT_PTR Number,
|
||||
IN UINT_PTR Base,
|
||||
IN UINT_PTR Padding);
|
||||
|
||||
XTCDECL
|
||||
UINT64
|
||||
BlpStringReadPadding(IN PUINT16 *Format);
|
||||
|
||||
#endif /* __XTLDR_XTBL_H */
|
422
xtldr/includes/xtldr.h
Normal file
422
xtldr/includes/xtldr.h
Normal file
@ -0,0 +1,422 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/includes/xtldr.h
|
||||
* DESCRIPTION: Top level header for XTLDR
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#ifndef __XTLDR_XTLDR_H
|
||||
#define __XTLDR_XTLDR_H
|
||||
|
||||
#include <xtblapi.h>
|
||||
#include <xtver.h>
|
||||
|
||||
#include <globals.h>
|
||||
|
||||
|
||||
/* XTLDR routine callbacks */
|
||||
typedef VOID (BLPRINTCHAR)(IN USHORT Character);
|
||||
|
||||
/* XTLDR routines forward references */
|
||||
XTCDECL
|
||||
VOID
|
||||
BlClearConsoleLine(IN ULONGLONG LineNo);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlClearConsoleScreen();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlCloseVolume(IN PEFI_HANDLE VolumeHandle);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsolePrint(IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlConsoleWrite(IN PUSHORT String);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDebugPrint(IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisableConsoleCursor();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayBootMenu();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayErrorDialog(IN PWCHAR Caption,
|
||||
IN PWCHAR Message);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayInfoDialog(IN PWCHAR Caption,
|
||||
IN PWCHAR Message);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlDisplayInputDialog(IN PWCHAR Caption,
|
||||
IN PWCHAR Message,
|
||||
IN OUT PWCHAR *InputFieldText);
|
||||
|
||||
XTCDECL
|
||||
XTBL_DIALOG_HANDLE
|
||||
BlDisplayProgressDialog(IN PWCHAR Caption,
|
||||
IN PWCHAR Message,
|
||||
IN UCHAR Percentage);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlEnableConsoleCursor();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnumerateBlockDevices();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlExitBootServices(IN UINT_PTR MapKey);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlFindBootProtocol(IN PWCHAR SystemType,
|
||||
OUT PEFI_GUID BootProtocolGuid);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
IN CONST PWCHAR FileSystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL* DevicePath);
|
||||
|
||||
XTCDECL
|
||||
PWCHAR
|
||||
BlGetConfigValue(IN CONST PWCHAR ConfigName);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap);
|
||||
|
||||
XTCDECL
|
||||
PLIST_ENTRY
|
||||
BlGetModulesList();
|
||||
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
BlGetSecureBootStatus();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeBootLoader();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries,
|
||||
OUT PULONG EntriesCount,
|
||||
OUT PULONG DefaultId);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeConsole();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadModule(IN PWCHAR ModuleName);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadModules(IN PWCHAR ModulesList);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryAllocatePages(IN UINT64 Pages,
|
||||
OUT PEFI_PHYSICAL_ADDRESS Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryAllocatePool(IN UINT_PTR Size,
|
||||
OUT PVOID *Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryFreePages(IN UINT64 Pages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryFreePool(IN PVOID Memory);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_HANDLE DiskHandle,
|
||||
OUT PEFI_FILE_HANDLE *FsHandle);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlOpenProtocol(OUT PEFI_HANDLE Handle,
|
||||
OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlQueryConsoleMode(OUT PUINT_PTR ResX,
|
||||
OUT PUINT_PTR ResY);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
IN CONST PWCHAR FileName,
|
||||
OUT PVOID *FileData,
|
||||
OUT PSIZE_T FileSize);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlReadKeyStroke(OUT PEFI_INPUT_KEY Key);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlRegisterBootMenu(PVOID BootMenuRoutine);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlRegisterBootProtocol(IN PWCHAR SystemType,
|
||||
IN PEFI_GUID BootProtocolGuid);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInstallProtocol(IN PVOID Interface,
|
||||
IN PEFI_GUID Guid);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlResetConsoleInputBuffer();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetConfigValue(IN CONST PWCHAR ConfigName,
|
||||
IN CONST PWCHAR ConfigValue);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetConsoleAttributes(IN ULONGLONG Attributes);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlSetConsoleMode(IN ULONGLONG Mode);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSetCursorPosition(IN ULONGLONG PosX,
|
||||
IN ULONGLONG PosY);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlSleepExecution(IN ULONG_PTR Milliseconds);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlStartLoaderShell();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
IN PEFI_SYSTEM_TABLE SystemTable);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlUpdateProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR Message,
|
||||
IN UCHAR Percentage);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlWaitForEfiEvent(IN UINT_PTR NumberOfEvents,
|
||||
IN PEFI_EVENT Event,
|
||||
OUT PUINT_PTR Index);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpActivateSerialIOController();
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpConsolePrintChar(IN USHORT Character);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDebugPutChar(IN USHORT Character);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDetermineDialogBoxSize(IN OUT PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR Message);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawBootMenu(OUT PXTBL_DIALOG_HANDLE Handle);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawBootMenuEntry(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR MenuEntry,
|
||||
IN UINT Position,
|
||||
IN BOOLEAN Highlighted);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawDialogBox(IN OUT PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR Caption,
|
||||
IN PWCHAR Message);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawDialogButton(IN PXTBL_DIALOG_HANDLE Handle);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawDialogInputField(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR InputFieldText);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawDialogMessage(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN PWCHAR Message);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpDrawDialogProgressBar(IN PXTBL_DIALOG_HANDLE Handle,
|
||||
IN UCHAR Percentage);
|
||||
|
||||
XTCDECL
|
||||
PEFI_DEVICE_PATH_PROTOCOL
|
||||
BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode);
|
||||
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA ParentNode);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInitializeDebugConsole();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInitializeSerialPort(IN ULONG PortNumber,
|
||||
IN ULONG PortAddress,
|
||||
IN ULONG BaudRate);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInstallXtLoaderProtocol();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpLoadConfiguration();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpParseCommandLine(VOID);
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpParseConfigFile(IN CONST PCHAR RawConfig,
|
||||
OUT PLIST_ENTRY Configuration);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpPrintShellPrompt();
|
||||
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory,
|
||||
IN CONST PWCHAR ConfigFile,
|
||||
OUT PCHAR *ConfigData);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN PUINT16 Format,
|
||||
IN ...);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN PUINT16 Format,
|
||||
IN VA_LIST Arguments);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN INT Number,
|
||||
IN UINT Base);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN INT_PTR Number,
|
||||
IN UINT_PTR Base);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN UINT Number,
|
||||
IN UINT Base,
|
||||
IN UINT Padding);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN UINT_PTR Number,
|
||||
IN UINT_PTR Base,
|
||||
IN UINT_PTR Padding);
|
||||
|
||||
XTCDECL
|
||||
UINT64
|
||||
BlpStringReadPadding(IN PUINT16 *Format);
|
||||
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpUpdateConfiguration(IN PLIST_ENTRY NewConfig);
|
||||
|
||||
#endif /* __XTLDR_XTLDR_H */
|
80
xtldr/library/modproto.c
Normal file
80
xtldr/library/modproto.c
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/library/modproto.c
|
||||
* DESCRIPTION: XT Boot Loader protocol support for XTLDR modules
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Finds and opens the XT Boot Loader protocol. This routine should be called by module to access XTLDR protocol.
|
||||
*
|
||||
* @param SystemTable
|
||||
* Provides the EFI system table.
|
||||
*
|
||||
* @param ImageHandle
|
||||
* Firmware-allocated handle that identifies the image.
|
||||
*
|
||||
* @param ProtocolHandler
|
||||
* Receives the pointer to the XT Boot Loader protocol.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetXtLdrProtocol(IN PEFI_SYSTEM_TABLE SystemTable,
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
OUT PXTBL_LOADER_PROTOCOL *ProtocolHandler)
|
||||
{
|
||||
EFI_GUID ProtocolGuid = XT_BOOT_LOADER_PROTOCOL_GUID;
|
||||
PEFI_HANDLE Handles = NULL;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR Count;
|
||||
UINT Index;
|
||||
|
||||
/* Try to locate the handles */
|
||||
Status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, &ProtocolGuid, NULL, &Count, &Handles);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get handles */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if any handles returned */
|
||||
if(Count > 0)
|
||||
{
|
||||
/* Iterate through all given handles */
|
||||
for(Index = 0; Index < Count; Index++)
|
||||
{
|
||||
/* Try to open protocol */
|
||||
Status = SystemTable->BootServices->OpenProtocol(Handles[Index], &ProtocolGuid,
|
||||
(PVOID*)ProtocolHandler, ImageHandle, NULL,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
|
||||
/* Check if successfully opened the loader protocol */
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Protocol found and successfully opened */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free handles */
|
||||
SystemTable->BootServices->FreePool(Handles);
|
||||
|
||||
/* Make sure the loaded protocol has been found */
|
||||
if(*ProtocolHandler == NULL)
|
||||
{
|
||||
/* Protocol not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
495
xtldr/memory.c
495
xtldr/memory.c
@ -2,315 +2,13 @@
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/memory.c
|
||||
* DESCRIPTION: EFI memory management
|
||||
* DESCRIPTION: XT Boot Loader memory management
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.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
|
||||
BlAddVirtualMemoryMapping(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 = BlEfiMemoryAllocatePool(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 = BlEfiMemoryAllocatePool(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 = BlEfiMemoryAllocatePool(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);
|
||||
BlEfiMemoryFreePool(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
|
||||
BlConvertEfiMemoryType(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;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine allocates one or more 4KB pages.
|
||||
*
|
||||
* @param Pages
|
||||
* The number of contiguous 4KB pages to allocate.
|
||||
*
|
||||
* @param Memory
|
||||
* The pointer to a physical address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryAllocatePages(IN UINT64 Pages,
|
||||
OUT PEFI_PHYSICAL_ADDRESS Memory)
|
||||
{
|
||||
return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine allocates a pool memory.
|
||||
*
|
||||
* @param Size
|
||||
* The number of bytes to allocate from the pool.
|
||||
*
|
||||
* @param Memory
|
||||
* The pointer to a physical address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryAllocatePool(IN UINT_PTR Size,
|
||||
OUT PVOID *Memory)
|
||||
{
|
||||
/* Allocate pool */
|
||||
return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine frees memory pages.
|
||||
*
|
||||
* @param Pages
|
||||
* The number of contiguous 4 KB pages to free.
|
||||
*
|
||||
* @param Memory
|
||||
* The base physical address of the pages to be freed.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryFreePages(IN UINT64 Pages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory)
|
||||
{
|
||||
return EfiSystemTable->BootServices->FreePages(Memory, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pool memory to the system.
|
||||
*
|
||||
* @param Memory
|
||||
* The pointer to the buffer to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiMemoryFreePool(IN PVOID Memory)
|
||||
{
|
||||
/* Free pool */
|
||||
return EfiSystemTable->BootServices->FreePool(Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory descriptors which define a memory map of all the physical memory ranges reserved by the UEFI.
|
||||
*
|
||||
@ -352,14 +50,14 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
|
||||
if(MemoryMap->Map)
|
||||
{
|
||||
/* Free allocated memory */
|
||||
BlEfiMemoryFreePool(MemoryMap->Map);
|
||||
BlMemoryFreePool(MemoryMap->Map);
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate the desired amount of memory */
|
||||
MemoryMap->MapSize += 2 * MemoryMap->DescriptorSize;
|
||||
BlEfiMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
|
||||
BlMemoryAllocatePool(MemoryMap->MapSize, (PVOID *)&MemoryMap->Map);
|
||||
}
|
||||
while(Status == STATUS_EFI_BUFFER_TOO_SMALL);
|
||||
|
||||
@ -375,16 +73,13 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find a virtual address of the specified physical address in memory mappings.
|
||||
* This routine allocates one or more 4KB pages.
|
||||
*
|
||||
* @param MemoryMappings
|
||||
* Supplies a pointer to linked list containing all memory mappings.
|
||||
* @param Pages
|
||||
* The number of contiguous 4KB pages to allocate.
|
||||
*
|
||||
* @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.
|
||||
* @param Memory
|
||||
* The pointer to a physical address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
@ -392,58 +87,20 @@ BlGetMemoryMap(OUT PEFI_MEMORY_MAP MemoryMap)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID PhysicalAddress,
|
||||
OUT PVOID *VirtualAddress)
|
||||
BlMemoryAllocatePages(IN UINT64 Pages,
|
||||
OUT PEFI_PHYSICAL_ADDRESS Memory)
|
||||
{
|
||||
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;
|
||||
return EfiSystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, Pages, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes virtual memory by adding known and general mappings.
|
||||
* This routine allocates a pool memory.
|
||||
*
|
||||
* @param MemoryMappings
|
||||
* Supplies a pointer to linked list containing all memory mappings.
|
||||
* @param Size
|
||||
* The number of bytes to allocate from the pool.
|
||||
*
|
||||
* @param MemoryMapAddress
|
||||
* Supplies an address of the mapped virtual memory area.
|
||||
* @param Memory
|
||||
* The pointer to a physical address.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
@ -451,80 +108,48 @@ BlGetVirtualAddress(IN PLIST_ENTRY MemoryMappings,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInitializeVirtualMemory(IN OUT PLIST_ENTRY MemoryMappings,
|
||||
IN OUT PVOID *MemoryMapAddress)
|
||||
BlMemoryAllocatePool(IN UINT_PTR Size,
|
||||
OUT PVOID *Memory)
|
||||
{
|
||||
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 */
|
||||
BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
|
||||
|
||||
/* Get EFI memory map */
|
||||
Status = BlGetMemoryMap(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 = BlConvertEfiMemoryType(Descriptor->Type);
|
||||
|
||||
/* Do memory mappings depending on memory type */
|
||||
if(MemoryType == LoaderFirmwareTemporary)
|
||||
{
|
||||
/* Map EFI firmware code */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, (PVOID)Descriptor->PhysicalStart,
|
||||
(PVOID)Descriptor->PhysicalStart, Descriptor->NumberOfPages, MemoryType);
|
||||
}
|
||||
else if(MemoryType != LoaderFree)
|
||||
{
|
||||
/* Add any non-free memory mapping */
|
||||
Status = BlAddVirtualMemoryMapping(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 = BlAddVirtualMemoryMapping(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;
|
||||
/* Allocate pool */
|
||||
return EfiSystemTable->BootServices->AllocatePool(EfiLoaderData, Size, Memory);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine frees memory pages.
|
||||
*
|
||||
* @param Pages
|
||||
* The number of contiguous 4 KB pages to free.
|
||||
*
|
||||
* @param Memory
|
||||
* The base physical address of the pages to be freed.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryFreePages(IN UINT64 Pages,
|
||||
IN EFI_PHYSICAL_ADDRESS Memory)
|
||||
{
|
||||
return EfiSystemTable->BootServices->FreePages(Memory, Pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pool memory to the system.
|
||||
*
|
||||
* @param Memory
|
||||
* The pointer to the buffer to free.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMemoryFreePool(IN PVOID Memory)
|
||||
{
|
||||
/* Free pool */
|
||||
return EfiSystemTable->BootServices->FreePool(Memory);
|
||||
}
|
||||
|
@ -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)
|
@ -6,7 +6,7 @@
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtos.h>
|
||||
|
||||
|
||||
/**
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
|
||||
IN PVOID *PtePointer)
|
||||
@ -38,11 +38,12 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
PLOADER_MEMORY_MAPPING Mapping;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PEFI_MEMORY_MAP MemoryMap;
|
||||
PLIST_ENTRY ListEntry;
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
EFI_STATUS Status;
|
||||
|
||||
/* Allocate pages for PML4 */
|
||||
Status = BlEfiMemoryAllocatePages(1, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
@ -53,17 +54,34 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
*PtePointer = (PVOID)(UINT_PTR)Address;
|
||||
RtlZeroMemory(*PtePointer, EFI_PAGE_SIZE);
|
||||
|
||||
/* Map XTLDR code */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
|
||||
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
/* Get list of XTLDR modules */
|
||||
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
|
||||
ModulesListEntry = ModulesList->Flink;
|
||||
while(ModulesListEntry != ModulesList)
|
||||
{
|
||||
/* Mapping the boot loader code failed */
|
||||
return Status;
|
||||
/* 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 = BlAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
|
||||
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping PML4 failed */
|
||||
@ -71,7 +89,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Iterate through and map all the mappings*/
|
||||
BlDbgPrint(L"Mapping and dumping EFI memory:\n");
|
||||
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = MemoryMappings->Flink;
|
||||
while(ListEntry != MemoryMappings)
|
||||
{
|
||||
@ -82,11 +100,11 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
if(Mapping->VirtualAddress)
|
||||
{
|
||||
/* Dump memory mapping */
|
||||
BlDbgPrint(L" Type=%02lu, PhysicalBase=0x%016lx, VirtualBase=0x%016lx, Pages=%lu\n", Mapping->MemoryType,
|
||||
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 = BlMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
|
||||
Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
|
||||
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@ -100,15 +118,15 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Map zero page as well */
|
||||
BlMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
|
||||
XtMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
|
||||
|
||||
/* Allocate and zero-fill buffer for EFI memory map */
|
||||
BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
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 */
|
||||
BlDbgPrint(L"Exiting EFI boot services\n");
|
||||
Status = BlGetMemoryMap(MemoryMap);
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get memory map */
|
||||
@ -116,18 +134,26 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Retry as UEFI spec says to do it twice */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey);
|
||||
}
|
||||
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
|
||||
|
||||
/* Check if exitted boot services successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to exit boot services */
|
||||
BlDbgPrint(L"Failed to exit boot services (Status code: %lx)\n", Status);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -165,7 +191,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
IN UINT_PTR VirtualAddress,
|
||||
IN UINT_PTR PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
@ -194,14 +220,14 @@ BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
if(!((PHARDWARE_PTE)(*PtePointer))[Pml4Index].Valid)
|
||||
{
|
||||
/* Allocate pages for the PDPT */
|
||||
Status = BlEfiMemoryAllocatePages(1, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
|
||||
if (Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory mapping failed */
|
||||
return Status;
|
||||
@ -228,14 +254,14 @@ BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
if(!PageDirectoryPointTable[PdpIndex].Valid)
|
||||
{
|
||||
/* Allocate pages for the PD */
|
||||
Status = BlEfiMemoryAllocatePages(1, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
|
||||
if (Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
if (Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory mapping failed */
|
||||
return Status;
|
||||
@ -262,14 +288,14 @@ BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
if(!PageDirectory[PdIndex].Valid)
|
||||
{
|
||||
/* Allocate pages for the PT */
|
||||
Status = BlEfiMemoryAllocatePages(1, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
|
||||
if (Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add new memory mapping */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, (PVOID)(UINT_PTR)Address, 1, LoaderMemoryData);
|
||||
if (Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory mapping failed */
|
||||
return Status;
|
@ -6,7 +6,7 @@
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtos.h>
|
||||
|
||||
|
||||
/**
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
XtEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
IN PVOID VirtualAddress,
|
||||
IN PEFI_LOADED_IMAGE_PROTOCOL ImageProtocol,
|
||||
IN PVOID *PtePointer)
|
||||
@ -41,7 +41,8 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
PEFI_MEMORY_DESCRIPTOR Descriptor;
|
||||
PLOADER_MEMORY_MAPPING Mapping;
|
||||
PEFI_MEMORY_MAP MemoryMap;
|
||||
PLIST_ENTRY ListEntry;
|
||||
PLIST_ENTRY ListEntry, ModulesList, ModulesListEntry;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
EFI_STATUS Status;
|
||||
UINT Index;
|
||||
|
||||
@ -60,16 +61,16 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
if(!(CpuRegisters->Edx & CPUID_FEATURES_EDX_PAE))
|
||||
{
|
||||
/* No PAE support */
|
||||
BlDbgPrint(L"ERROR: PAE extension not supported by the CPU\n");
|
||||
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 */
|
||||
BlEfiMemoryAllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
XtLdrProtocol->Memory.AllocatePool(sizeof(EFI_MEMORY_MAP), (PVOID*)&MemoryMap);
|
||||
RtlZeroMemory(MemoryMap, sizeof(EFI_MEMORY_MAP));
|
||||
|
||||
/* Get EFI memory map */
|
||||
Status = BlGetMemoryMap(MemoryMap);
|
||||
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get memory map */
|
||||
@ -103,7 +104,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Allocate pages for the PDPT address */
|
||||
Status = BlEfiMemoryAllocatePages(1, &PDPTAddress);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &PDPTAddress);
|
||||
if(Status != STATUS_EFI_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
@ -128,7 +129,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
Address = 0x100000;
|
||||
|
||||
/* Allocate pages for the PFN */
|
||||
Status = BlEfiMemoryAllocatePages(4, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(4, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
@ -151,17 +152,34 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
Address += EFI_PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* Map XTLDR code */
|
||||
Status = BlAddVirtualMemoryMapping(MemoryMappings, ImageProtocol->ImageBase, ImageProtocol->ImageBase,
|
||||
EFI_SIZE_TO_PAGES(ImageProtocol->ImageSize), LoaderFirmwareTemporary);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
/* Get list of XTLDR modules */
|
||||
ModulesList = XtLdrProtocol->Protocol.GetModulesList();
|
||||
ModulesListEntry = ModulesList->Flink;
|
||||
while(ModulesListEntry != ModulesList)
|
||||
{
|
||||
/* Mapping the boot loader code failed */
|
||||
return Status;
|
||||
/* 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 = BlAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
|
||||
Status = XtAddVirtualMemoryMapping(MemoryMappings, NULL, *PtePointer, 1, LoaderMemoryData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Mapping PD failed */
|
||||
@ -169,7 +187,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Iterate through and map all the mappings */
|
||||
BlDbgPrint(L"Mapping and dumping EFI memory:\n");
|
||||
XtLdrProtocol->Debug.Print(L"Mapping and dumping EFI memory:\n");
|
||||
ListEntry = MemoryMappings->Flink;
|
||||
while(ListEntry != MemoryMappings)
|
||||
{
|
||||
@ -180,11 +198,11 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
if(Mapping->VirtualAddress)
|
||||
{
|
||||
/* Dump memory mapping */
|
||||
BlDbgPrint(L" Type=%02lu, PhysicalBase=0x%08lx, VirtualBase=0x%08lx, Pages=%lu\n", Mapping->MemoryType,
|
||||
Mapping->PhysicalAddress, Mapping->VirtualAddress, Mapping->NumberOfPages);
|
||||
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 = BlMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
|
||||
Status = XtMapVirtualMemory(MemoryMappings, (UINT_PTR)Mapping->VirtualAddress,
|
||||
(UINT_PTR)Mapping->PhysicalAddress, Mapping->NumberOfPages, PtePointer);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@ -198,14 +216,14 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Map zero page as well */
|
||||
BlMapVirtualMemory(MemoryMappings, 0, 0, 1, PtePointer);
|
||||
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 */
|
||||
BlDbgPrint(L"Exiting EFI boot services\n");
|
||||
Status = BlGetMemoryMap(MemoryMap);
|
||||
XtLdrProtocol->Debug.Print(L"Exiting EFI boot services\n");
|
||||
Status = XtLdrProtocol->Memory.GetMemoryMap(MemoryMap);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get memory map */
|
||||
@ -213,18 +231,27 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
}
|
||||
|
||||
/* Exit EFI Boot Services */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey);
|
||||
Status = XtLdrProtocol->Util.ExitBootServices(MemoryMap->MapKey);
|
||||
|
||||
/* Check if exitted boot services successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Retry as UEFI spec says to do it twice */
|
||||
Status = EfiSystemTable->BootServices->ExitBootServices(EfiImageHandle, MemoryMap->MapKey);
|
||||
/* 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 */
|
||||
BlDbgPrint(L"Failed to exit boot services (Status code: %lx)\n", Status);
|
||||
XtLdrProtocol->Debug.Print(L"Failed to exit boot services (Status code: %lx)\n", Status);
|
||||
return STATUS_EFI_ABORTED;
|
||||
}
|
||||
|
||||
@ -268,7 +295,7 @@ BlEnablePaging(IN PLIST_ENTRY MemoryMappings,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
XtMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
IN UINT_PTR VirtualAddress,
|
||||
IN UINT_PTR PhysicalAddress,
|
||||
IN UINT NumberOfPages,
|
||||
@ -294,7 +321,7 @@ BlMapVirtualMemory(IN PLIST_ENTRY MemoryMappings,
|
||||
/* Validate Page Directory */
|
||||
if(!PageDirectory[PdIndex].Valid) {
|
||||
/* Allocate pages for new page table */
|
||||
Status = BlEfiMemoryAllocatePages(1, &Address);
|
||||
Status = XtLdrProtocol->Memory.AllocatePages(1, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS) {
|
||||
/* Memory allocation failure */
|
||||
return Status;
|
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);
|
||||
}
|
601
xtldr/protocol.c
Normal file
601
xtldr/protocol.c
Normal file
@ -0,0 +1,601 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/protocol.c
|
||||
* DESCRIPTION: XT Boot Loader protocol support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Closes a protocol on a provided handle.
|
||||
*
|
||||
* @param Handle
|
||||
* Supplies a handle for the protocol interface that was previously opened.
|
||||
*
|
||||
* @param ProtocolGuid
|
||||
* Supplies a unique protocol GUID.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlCloseProtocol(IN PEFI_HANDLE Handle,
|
||||
IN PEFI_GUID ProtocolGuid)
|
||||
{
|
||||
return EfiSystemTable->BootServices->CloseProtocol(Handle, ProtocolGuid, EfiImageHandle, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a boot protocol for specified system type.
|
||||
*
|
||||
* @param SystemType
|
||||
* Specifies the system type to search for.
|
||||
*
|
||||
* @param BootProtocolGuid
|
||||
* Receives the GUID of the registered boot protocol, that supports specified system.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlFindBootProtocol(IN PWCHAR SystemType,
|
||||
OUT PEFI_GUID BootProtocolGuid)
|
||||
{
|
||||
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
|
||||
PLIST_ENTRY ProtocolListEntry;
|
||||
|
||||
ProtocolListEntry = BlpBootProtocols.Flink;
|
||||
while(ProtocolListEntry != &BlpBootProtocols)
|
||||
{
|
||||
/* Get boot protocol entry */
|
||||
ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink);
|
||||
|
||||
/* Check if this boot protocol supports specified system */
|
||||
if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0)
|
||||
{
|
||||
/* Boot protocol matched, return success */
|
||||
*BootProtocolGuid = ProtocolEntry->Guid;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Move to the next registered boot protocol */
|
||||
ProtocolListEntry = ProtocolListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Boot protocol not found, return error */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a linked list of all loaded modules.
|
||||
*
|
||||
* @return This routine returns a pointer to a linked list of all loaded modules.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*
|
||||
* @todo This is a temporary solution and it should be replaced by a complex API allowing to map modules.
|
||||
*/
|
||||
XTCDECL
|
||||
PLIST_ENTRY
|
||||
BlGetModulesList()
|
||||
{
|
||||
/* Return a pointer to a list of all loaded modules */
|
||||
return &BlpLoadedModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs XTLDR protocol interface.
|
||||
*
|
||||
* @param Guid
|
||||
* Specifies a unique protocol GUID.
|
||||
*
|
||||
* @param Interface
|
||||
* Supplies a pointer to the protocol interface, or NULL if there is no structure associated.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlInstallProtocol(IN PVOID Interface,
|
||||
IN PEFI_GUID Guid)
|
||||
{
|
||||
EFI_HANDLE Handle = NULL;
|
||||
|
||||
/* Install protocol interface */
|
||||
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, Guid, EFI_NATIVE_INTERFACE, Interface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a specified XTLDR module from disk.
|
||||
*
|
||||
* @param ModuleName
|
||||
* Specifies the name of the module to load.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadModule(IN PWCHAR ModuleName)
|
||||
{
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
EFI_MEMMAP_DEVICE_PATH ModuleDevicePath[2];
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
PEFI_FILE_HANDLE DirHandle, FsHandle;
|
||||
EFI_HANDLE DiskHandle, ModuleHandle;
|
||||
PPECOFF_IMAGE_SECTION_HEADER SectionHeader;
|
||||
PPECOFF_IMAGE_DOS_HEADER DosHeader;
|
||||
PPECOFF_IMAGE_PE_HEADER PeHeader;
|
||||
PXTBL_MODULE_DEPS ModuleDependencies;
|
||||
PXTBL_MODULE_INFO ModuleInfo;
|
||||
PLIST_ENTRY ModuleListEntry;
|
||||
WCHAR ModuleFileName[24];
|
||||
USHORT SectionIndex;
|
||||
SIZE_T ModuleSize;
|
||||
EFI_STATUS Status;
|
||||
PVOID ModuleData;
|
||||
PWCHAR DepsData;
|
||||
|
||||
ModuleListEntry = BlpLoadedModules.Flink;
|
||||
while(ModuleListEntry != &BlpLoadedModules)
|
||||
{
|
||||
/* Get module information */
|
||||
ModuleInfo = CONTAIN_RECORD(ModuleListEntry, XTBL_MODULE_INFO, Flink);
|
||||
|
||||
if(RtlCompareWideStringInsensitive(ModuleInfo->ModuleName, ModuleName, 0) == 0)
|
||||
{
|
||||
/* Module already loaded */
|
||||
BlDebugPrint(L"WARNING: Module '%S' already loaded!\n", ModuleName);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Move to the module */
|
||||
ModuleListEntry = ModuleListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Print debug message */
|
||||
BlDebugPrint(L"Loading module '%S' ...\n", ModuleName);
|
||||
|
||||
/* Set module path */
|
||||
RtlCopyMemory(ModuleFileName, ModuleName, sizeof(ModuleFileName) / sizeof(WCHAR));
|
||||
RtlConcatenateWideString(ModuleFileName, L".EFI", 0);
|
||||
|
||||
/* Open EFI volume */
|
||||
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open a volume */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Open XTLDR modules common directory */
|
||||
Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Modules directory not found, attempt to open XTLDR architecture specific modules directory */
|
||||
Status = FsHandle->Open(FsHandle, &DirHandle, XTBL_ARCH_MODULES_DIRECTORY_PATH, EFI_FILE_MODE_READ, 0);
|
||||
}
|
||||
|
||||
/* Close FS handle */
|
||||
FsHandle->Close(FsHandle);
|
||||
|
||||
/* Check if modules directory opened successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open directory */
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read module file from disk and close directory and EFI volume */
|
||||
Status = BlReadFile(DirHandle, ModuleFileName, &ModuleData, &ModuleSize);
|
||||
DirHandle->Close(DirHandle);
|
||||
BlCloseVolume(DiskHandle);
|
||||
|
||||
/* Make sure module file was read successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to read file */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Allocate memory for module information block */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_INFO), (PVOID*)&ModuleInfo);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero module information block and initialize dependencies list */
|
||||
RtlZeroMemory(ModuleInfo, sizeof(XTBL_MODULE_INFO));
|
||||
RtlInitializeListHead(&ModuleInfo->Dependencies);
|
||||
|
||||
/* Setup PE/COFF EFI image headers */
|
||||
DosHeader = (PPECOFF_IMAGE_DOS_HEADER)ModuleData;
|
||||
PeHeader = (PPECOFF_IMAGE_PE_HEADER)(ModuleData + DosHeader->e_lfanew);
|
||||
SectionHeader = (PPECOFF_IMAGE_SECTION_HEADER)((PUCHAR)&PeHeader->OptionalHeader +
|
||||
PeHeader->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
/* Look for .moddeps and .modinfo sections */
|
||||
for(SectionIndex = 0; SectionIndex < PeHeader->FileHeader.NumberOfSections; SectionIndex++)
|
||||
{
|
||||
/* Check section name */
|
||||
if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".moddeps", 8) == 0)
|
||||
{
|
||||
/* Store address of .moddeps data segment */
|
||||
DepsData = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||
|
||||
/* Iterate over all dependencies stored */
|
||||
while(*DepsData != 0)
|
||||
{
|
||||
/* Load dependency module */
|
||||
BlDebugPrint(L"Module '%S' requires '%S' ...\n", ModuleName, DepsData);
|
||||
Status = BlLoadModule(DepsData);
|
||||
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load module, print error message and return status code */
|
||||
BlDebugPrint(L"Failed to load dependency module '%S', (Status Code: 0x%lx)\n", DepsData, Status);
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Allocate memory for module dependency */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_MODULE_DEPS), (PVOID*)&ModuleDependencies);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocated successfully, store module's dependency */
|
||||
ModuleDependencies->ModuleName = DepsData;
|
||||
RtlInsertTailList(&ModuleInfo->Dependencies, &ModuleDependencies->Flink);
|
||||
}
|
||||
|
||||
/* Get next dependency module name */
|
||||
DepsData += 8;
|
||||
}
|
||||
}
|
||||
else if(RtlCompareString((PCHAR)SectionHeader[SectionIndex].Name, ".modinfo", 8) == 0)
|
||||
{
|
||||
/* Store module description */
|
||||
ModuleInfo->ModuleDescription = ModuleData + SectionHeader[SectionIndex].PointerToRawData;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, store module name */
|
||||
ModuleInfo->ModuleName = ModuleName;
|
||||
|
||||
/* Setup module device path */
|
||||
ModuleDevicePath[0].Header.Length[0] = sizeof(EFI_MEMMAP_DEVICE_PATH);
|
||||
ModuleDevicePath[0].Header.Length[1] = sizeof(EFI_MEMMAP_DEVICE_PATH) >> 8;
|
||||
ModuleDevicePath[0].Header.Type = EFI_HARDWARE_DEVICE_PATH;
|
||||
ModuleDevicePath[0].Header.SubType = EFI_HARDWARE_MEMMAP_DP;
|
||||
ModuleDevicePath[0].MemoryType = EfiLoaderData;
|
||||
ModuleDevicePath[0].StartingAddress = (UINT_PTR)ModuleData;
|
||||
ModuleDevicePath[0].EndingAddress = (UINT_PTR)ModuleData + ModuleSize;
|
||||
ModuleDevicePath[1].Header.Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL);
|
||||
ModuleDevicePath[1].Header.Length[1] = sizeof(EFI_DEVICE_PATH_PROTOCOL) >> 8;
|
||||
ModuleDevicePath[1].Header.Type = EFI_END_DEVICE_PATH;
|
||||
ModuleDevicePath[1].Header.SubType = EFI_END_ENTIRE_DP;
|
||||
|
||||
/* Load EFI image */
|
||||
Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, (PEFI_DEVICE_PATH_PROTOCOL)ModuleDevicePath,
|
||||
ModuleData, ModuleSize, &ModuleHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Check if caused by secure boot */
|
||||
if(Status == STATUS_EFI_ACCESS_DENIED && BlpStatus.SecureBoot >= 1)
|
||||
{
|
||||
/* SecureBoot signature validation failed */
|
||||
BlDebugPrint(L"ERROR: SecureBoot signature validation failed, module '%S' will not be loaded\n", ModuleName);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to load module */
|
||||
BlDebugPrint(L"ERROR: Unable to load module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||
}
|
||||
|
||||
/* Return error status code */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Access module interface for further module type check */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,
|
||||
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open LoadedImage protocol */
|
||||
BlDebugPrint(L"ERROR: Unable to access module interface (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */
|
||||
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
|
||||
{
|
||||
/* Different type set, probably 'runtime driver', refuse to load it */
|
||||
BlDebugPrint(L"ERROR: Loaded module is not a boot system driver\n");
|
||||
|
||||
/* Close protocol and skip module */
|
||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||
}
|
||||
|
||||
/* Save module information */
|
||||
ModuleInfo->ModuleBase = LoadedImage->ImageBase;
|
||||
ModuleInfo->ModuleSize = LoadedImage->ImageSize;
|
||||
ModuleInfo->Revision = LoadedImage->Revision;
|
||||
ModuleInfo->UnloadModule = LoadedImage->Unload;
|
||||
|
||||
/* Close loaded image protocol */
|
||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||
|
||||
/* Start EFI image */
|
||||
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to start module image */
|
||||
BlDebugPrint(L"ERROR: Failed to start module '%S' (Status Code: 0x%lx)\n", ModuleName, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Add module to the list of loaded modules */
|
||||
RtlInsertTailList(&BlpLoadedModules, &ModuleInfo->Flink);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper routine to load all modules supplied in the configuration file.
|
||||
*
|
||||
* @param ModulesList
|
||||
* Supplies a space separated list of XTLDR modules to load (mostly read from configuration file).
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadModules(IN PWCHAR ModulesList)
|
||||
{
|
||||
PWCHAR LastModule, Module;
|
||||
EFI_STATUS ReturnStatus, Status;
|
||||
|
||||
/* Set default return value */
|
||||
ReturnStatus = STATUS_EFI_SUCCESS;
|
||||
|
||||
if(ModulesList != NULL)
|
||||
{
|
||||
/* Tokenize provided list of modules */
|
||||
Module = RtlTokenizeWideString(ModulesList, L" ", &LastModule);
|
||||
|
||||
/* Iterate over all arguments passed to boot loader */
|
||||
while(Module != NULL)
|
||||
{
|
||||
Status = BlLoadModule(Module);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load module, print error message and set new return value */
|
||||
BlDebugPrint(L"ERROR: Failed to load module '%S', (Status Code: 0x%lx)\n", Module, Status);
|
||||
ReturnStatus = STATUS_EFI_LOAD_ERROR;
|
||||
}
|
||||
|
||||
/* Take next module from the list */
|
||||
Module = RtlTokenizeWideString(NULL, L" ", &LastModule);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine locates and opens the requested XT Boot Loader or EFI protocol.
|
||||
*
|
||||
* @param Handle
|
||||
* Supplies the address where a pointer to the handle for the protocol interface.
|
||||
*
|
||||
* @param ProtocolHandler
|
||||
* Supplies the address where a pointer to the opened protocol is returned.
|
||||
*
|
||||
* @param ProtocolGuid
|
||||
* Supplies a pointer to the unique protocol GUID.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlOpenProtocol(OUT PEFI_HANDLE Handle,
|
||||
OUT PVOID *ProtocolHandler,
|
||||
IN PEFI_GUID ProtocolGuid)
|
||||
{
|
||||
PEFI_HANDLE Handles = NULL;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR Count;
|
||||
UINT Index;
|
||||
|
||||
/* Try to locate the handles */
|
||||
Status = EfiSystemTable->BootServices->LocateHandleBuffer(ByProtocol, ProtocolGuid, NULL, &Count, &Handles);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get handles */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if any handles returned */
|
||||
if(Count > 0)
|
||||
{
|
||||
/* Iterate through all given handles */
|
||||
for(Index = 0; Index < Count; Index++)
|
||||
{
|
||||
/* Try to open protocol */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(Handles[Index], ProtocolGuid,
|
||||
ProtocolHandler, EfiImageHandle, NULL,
|
||||
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
|
||||
|
||||
/* Check if successfully opened the loader protocol */
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Protocol found and successfully opened */
|
||||
*Handle = Handles[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Free handles */
|
||||
EfiSystemTable->BootServices->FreePool(Handles);
|
||||
|
||||
/* Make sure the loaded protocol has been found */
|
||||
if(*ProtocolHandler == NULL)
|
||||
{
|
||||
/* Protocol not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a boot menu callback routine, that will be used to display alternative boot menu.
|
||||
*
|
||||
* @param BootMenuRoutine
|
||||
* Supplies a pointer to the boot menu callback routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlRegisterBootMenu(IN PVOID BootMenuRoutine)
|
||||
{
|
||||
/* Set boot menu routine */
|
||||
BlpStatus.BootMenu = BootMenuRoutine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a known boot protocol for a specified OS.
|
||||
*
|
||||
* @param SystemType
|
||||
* Supplies the type of the OS, such as "LINUX", "XTOS", etc. that is supported by the boot protocol.
|
||||
*
|
||||
* @param BootProtocolGuid
|
||||
* Supplies a pointer to the unique protocol GUID.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlRegisterBootProtocol(IN PWCHAR SystemType,
|
||||
IN PEFI_GUID BootProtocolGuid)
|
||||
{
|
||||
PXTBL_KNOWN_BOOT_PROTOCOL ProtocolEntry;
|
||||
PLIST_ENTRY ProtocolListEntry;
|
||||
EFI_STATUS Status;
|
||||
|
||||
ProtocolListEntry = BlpBootProtocols.Flink;
|
||||
while(ProtocolListEntry != &BlpBootProtocols)
|
||||
{
|
||||
/* Get boot protocol entry */
|
||||
ProtocolEntry = CONTAIN_RECORD(ProtocolListEntry, XTBL_KNOWN_BOOT_PROTOCOL, Flink);
|
||||
|
||||
/* Check if boot protocol already registered for specified system */
|
||||
if(RtlCompareWideStringInsensitive(ProtocolEntry->SystemType, SystemType, 0) == 0)
|
||||
{
|
||||
/* Boot protocol already registered */
|
||||
return STATUS_EFI_ABORTED;
|
||||
}
|
||||
|
||||
/* Move to the next registered boot protocol */
|
||||
ProtocolListEntry = ProtocolListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Create new boot protocol entry */
|
||||
Status = BlMemoryAllocatePool(sizeof(XTBL_BOOT_PROTOCOL), (PVOID *)&ProtocolEntry);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/* Set protocol properties and add it to the list */
|
||||
ProtocolEntry->SystemType = SystemType;
|
||||
ProtocolEntry->Guid = *BootProtocolGuid;
|
||||
RtlInsertTailList(&BlpBootProtocols, &ProtocolEntry->Flink);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine installs XTLDR protocol for further usage by modules.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpInstallXtLoaderProtocol()
|
||||
{
|
||||
EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;
|
||||
|
||||
/* Set all routines available via loader protocol */
|
||||
BlpLdrProtocol.Boot.FindProtocol = BlFindBootProtocol;
|
||||
BlpLdrProtocol.Boot.InitializeMenuList = BlInitializeBootMenuList;
|
||||
BlpLdrProtocol.Boot.InvokeProtocol = BlInvokeBootProtocol;
|
||||
BlpLdrProtocol.Boot.RegisterMenu = BlRegisterBootMenu;
|
||||
BlpLdrProtocol.Boot.RegisterProtocol = BlRegisterBootProtocol;
|
||||
BlpLdrProtocol.Config.GetValue = BlGetConfigValue;
|
||||
BlpLdrProtocol.Console.ClearLine = BlClearConsoleLine;
|
||||
BlpLdrProtocol.Console.ClearScreen = BlClearConsoleScreen;
|
||||
BlpLdrProtocol.Console.DisableCursor = BlDisableConsoleCursor;
|
||||
BlpLdrProtocol.Console.EnableCursor = BlEnableConsoleCursor;
|
||||
BlpLdrProtocol.Console.Print = BlConsolePrint;
|
||||
BlpLdrProtocol.Console.QueryMode = BlQueryConsoleMode;
|
||||
BlpLdrProtocol.Console.ReadKeyStroke = BlReadKeyStroke;
|
||||
BlpLdrProtocol.Console.ResetInputBuffer = BlResetConsoleInputBuffer;
|
||||
BlpLdrProtocol.Console.SetAttributes = BlSetConsoleAttributes;
|
||||
BlpLdrProtocol.Console.SetCursorPosition = BlSetCursorPosition;
|
||||
BlpLdrProtocol.Console.Write = BlConsoleWrite;
|
||||
BlpLdrProtocol.Debug.Print = BlDebugPrint;
|
||||
BlpLdrProtocol.Disk.CloseVolume = BlCloseVolume;
|
||||
BlpLdrProtocol.Disk.OpenVolume = BlOpenVolume;
|
||||
BlpLdrProtocol.Disk.ReadFile = BlReadFile;
|
||||
BlpLdrProtocol.Memory.AllocatePages = BlMemoryAllocatePages;
|
||||
BlpLdrProtocol.Memory.AllocatePool = BlMemoryAllocatePool;
|
||||
BlpLdrProtocol.Memory.FreePages = BlMemoryFreePages;
|
||||
BlpLdrProtocol.Memory.FreePool = BlMemoryFreePool;
|
||||
BlpLdrProtocol.Memory.GetMemoryMap = BlGetMemoryMap;
|
||||
BlpLdrProtocol.Protocol.Close = BlCloseProtocol;
|
||||
BlpLdrProtocol.Protocol.GetModulesList = BlGetModulesList;
|
||||
BlpLdrProtocol.Protocol.Open = BlOpenProtocol;
|
||||
BlpLdrProtocol.Protocol.Install = BlInstallProtocol;
|
||||
BlpLdrProtocol.Tui.DisplayErrorDialog = BlDisplayErrorDialog;
|
||||
BlpLdrProtocol.Tui.DisplayInfoDialog = BlDisplayInfoDialog;
|
||||
BlpLdrProtocol.Tui.DisplayInputDialog = BlDisplayInputDialog;
|
||||
BlpLdrProtocol.Tui.DisplayProgressDialog = BlDisplayProgressDialog;
|
||||
BlpLdrProtocol.Tui.UpdateProgressBar = BlUpdateProgressBar;
|
||||
BlpLdrProtocol.Util.ExitBootServices = BlExitBootServices;
|
||||
BlpLdrProtocol.Util.GetSecureBootStatus = BlGetSecureBootStatus;
|
||||
BlpLdrProtocol.Util.SleepExecution = BlSleepExecution;
|
||||
BlpLdrProtocol.Util.WaitForEfiEvent = BlWaitForEfiEvent;
|
||||
|
||||
/* Register XTLDR loader protocol */
|
||||
BlDebugPrint(L"Registering XT loader protocol\n");
|
||||
return BlInstallProtocol(&BlpLdrProtocol, &Guid);
|
||||
}
|
50
xtldr/shell.c
Normal file
50
xtldr/shell.c
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/shell.c
|
||||
* DESCRIPTION: XT Boot Loader shell
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Starts XTLDR shell.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlStartLoaderShell()
|
||||
{
|
||||
/* Initialize console */
|
||||
BlInitializeConsole();
|
||||
|
||||
/* Print prompt */
|
||||
BlpPrintShellPrompt();
|
||||
for(;;);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints XTLDR shell prompt.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpPrintShellPrompt()
|
||||
{
|
||||
/* Set prompt color */
|
||||
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_YELLOW);
|
||||
|
||||
/* Print prompt */
|
||||
BlConsolePrint(L"XTLDR> ");
|
||||
|
||||
/* Reset standard shell colors */
|
||||
BlSetConsoleAttributes(EFI_TEXT_BGCOLOR_BLACK | EFI_TEXT_FGCOLOR_LIGHTGRAY);
|
||||
}
|
190
xtldr/string.c
190
xtldr/string.c
@ -2,73 +2,17 @@
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/string.c
|
||||
* DESCRIPTION: EFI string operations support
|
||||
* DESCRIPTION: EFI string manipulation support
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* Compares two strings without sensitivity to case.
|
||||
*
|
||||
* @param String1
|
||||
* First string to be compared.
|
||||
*
|
||||
* @param String2
|
||||
* Second string to be compared.
|
||||
*
|
||||
* @return This routine returns a value indicating the relationship between the two strings.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
INT
|
||||
BlStringCompareInsensitive(IN PUCHAR String1,
|
||||
IN PUCHAR String2)
|
||||
{
|
||||
UCHAR Character1;
|
||||
UCHAR Character2;
|
||||
ULONG Index = 0;
|
||||
|
||||
/* Iterate through the strings */
|
||||
while(String1[Index] != '\0' && String2[Index] != '\0')
|
||||
{
|
||||
/* Get the characters */
|
||||
Character1 = String1[Index];
|
||||
Character2 = String2[Index];
|
||||
|
||||
/* Lowercase string1 character if needed */
|
||||
if(String1[Index] >= 'A' && String1[Index] <= 'Z')
|
||||
{
|
||||
Character1 = String1[Index] - 'A' + 'a';
|
||||
}
|
||||
|
||||
/* Lowercase string2 character if needed */
|
||||
if(String2[Index] >= 'A' && String2[Index] <= 'Z')
|
||||
{
|
||||
Character2 = String2[Index] - 'A' + 'a';
|
||||
}
|
||||
|
||||
/* Compare the characters */
|
||||
if(Character1 != Character2)
|
||||
{
|
||||
/* Strings are not equal */
|
||||
return Character1 > Character2 ? 1 : -1;
|
||||
}
|
||||
|
||||
/* Get next character */
|
||||
Index++;
|
||||
}
|
||||
|
||||
/* Strings are equal */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine formats the input string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Format
|
||||
@ -83,9 +27,9 @@ BlStringCompareInsensitive(IN PUCHAR String1,
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
IN PUINT16 Format,
|
||||
IN VA_LIST Arguments)
|
||||
BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN PUINT16 Format,
|
||||
IN VA_LIST Arguments)
|
||||
{
|
||||
PEFI_GUID Guid;
|
||||
PUCHAR String;
|
||||
@ -102,20 +46,20 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
{
|
||||
case L'b':
|
||||
/* Boolean */
|
||||
BlpStringFormat(PutChar, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE");
|
||||
BlpStringFormat(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT32) ? "TRUE" : "FALSE");
|
||||
break;
|
||||
case L'c':
|
||||
/* Character */
|
||||
PutChar(VA_ARG(Arguments, INT));
|
||||
PrintCharRoutine(VA_ARG(Arguments, INT));
|
||||
break;
|
||||
case L'd':
|
||||
/* Signed 32-bit integer */
|
||||
BlpStringPrintSigned32(PutChar, VA_ARG(Arguments, INT32), 10);
|
||||
BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10);
|
||||
break;
|
||||
case L'g':
|
||||
/* EFI GUID */
|
||||
Guid = VA_ARG(Arguments, PEFI_GUID);
|
||||
BlpStringFormat(PutChar, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1,
|
||||
BlpStringFormat(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1,
|
||||
Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2],
|
||||
Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]);
|
||||
break;
|
||||
@ -125,48 +69,48 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
{
|
||||
case L'd':
|
||||
/* Signed 64-bit integer */
|
||||
BlpStringPrintSigned64(PutChar, VA_ARG(Arguments, INT_PTR), 10);
|
||||
BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10);
|
||||
break;
|
||||
case L'u':
|
||||
/* Unsigned 64-bit integer */
|
||||
BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 10, 0);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0);
|
||||
break;
|
||||
case L'x':
|
||||
/* Unsigned 64-bit hexadecimal integer */
|
||||
BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, 0);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0);
|
||||
break;
|
||||
default:
|
||||
/* Unknown by default */
|
||||
PutChar(L'?');
|
||||
PrintCharRoutine(L'?');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case L'p':
|
||||
/* Pointer address */
|
||||
BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, 0);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0);
|
||||
break;
|
||||
case L's':
|
||||
/* String of characters */
|
||||
String = VA_ARG(Arguments, PUCHAR);
|
||||
while(*String)
|
||||
{
|
||||
PutChar(*String++);
|
||||
PrintCharRoutine(*String++);
|
||||
}
|
||||
break;
|
||||
case L'S':
|
||||
WideString = VA_ARG(Arguments, PWCHAR);
|
||||
while(*WideString)
|
||||
{
|
||||
PutChar((UCHAR)*WideString++);
|
||||
PrintCharRoutine((UCHAR)*WideString++);
|
||||
}
|
||||
break;
|
||||
case L'u':
|
||||
/* Unsigned 32-bit integer */
|
||||
BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 10, 0);
|
||||
BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, 0);
|
||||
break;
|
||||
case L'x':
|
||||
/* Unsigned 32-bit hexadecimal integer */
|
||||
BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 16, 0);
|
||||
BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, 0);
|
||||
break;
|
||||
case L'0':
|
||||
/* Zero padded numbers */
|
||||
@ -176,7 +120,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
{
|
||||
case L'd':
|
||||
/* Zero-padded, signed 32-bit integer */
|
||||
BlpStringPrintSigned32(PutChar, VA_ARG(Arguments, INT32), 10);
|
||||
BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT32), 10);
|
||||
break;
|
||||
case L'l':
|
||||
/* 64-bit numbers */
|
||||
@ -184,43 +128,43 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
{
|
||||
case L'd':
|
||||
/* Zero-padded, signed 64-bit integer */
|
||||
BlpStringPrintSigned64(PutChar, VA_ARG(Arguments, INT_PTR), 10);
|
||||
BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10);
|
||||
break;
|
||||
case L'u':
|
||||
/* Zero-padded, unsigned 64-bit integer */
|
||||
BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount);
|
||||
break;
|
||||
case L'x':
|
||||
/* Zero-padded, unsigned 64-bit hexadecimal integer */
|
||||
BlpStringPrintUnsigned64(PutChar, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount);
|
||||
break;
|
||||
default:
|
||||
/* Unknown by default */
|
||||
PutChar(L'?');
|
||||
PrintCharRoutine(L'?');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case L'u':
|
||||
/* Zero-padded, unsigned 32-bit integer */
|
||||
BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 10, PaddingCount);
|
||||
BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 10, PaddingCount);
|
||||
break;
|
||||
case L'x':
|
||||
/* Zero-padded, unsigned 32-bit hexadecimal integer */
|
||||
BlpStringPrintUnsigned32(PutChar, VA_ARG(Arguments, UINT32), 16, PaddingCount);
|
||||
BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT32), 16, PaddingCount);
|
||||
break;
|
||||
default:
|
||||
/* Unknown by default */
|
||||
PutChar(L'?');
|
||||
PrintCharRoutine(L'?');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case L'%':
|
||||
/* Percent character */
|
||||
PutChar(L'%');
|
||||
PrintCharRoutine(L'%');
|
||||
break;
|
||||
default:
|
||||
/* Unknown by default */
|
||||
PutChar(L'?');
|
||||
PrintCharRoutine(L'?');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -229,12 +173,12 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
break;
|
||||
case L'\n':
|
||||
/* New line together with carriage return */
|
||||
PutChar(L'\r');
|
||||
PutChar(L'\n');
|
||||
PrintCharRoutine(L'\r');
|
||||
PrintCharRoutine(L'\n');
|
||||
break;
|
||||
default:
|
||||
/* Put character by default */
|
||||
PutChar(*Format);
|
||||
PrintCharRoutine(*Format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -243,7 +187,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
/**
|
||||
* This routine formats the input string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Format
|
||||
@ -258,7 +202,7 @@ BlStringPrint(IN VOID PutChar(IN USHORT Character),
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringFormat(IN VOID PutChar(IN USHORT Character),
|
||||
BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN PUINT16 Format,
|
||||
IN ...)
|
||||
{
|
||||
@ -268,7 +212,7 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character),
|
||||
VA_START(Arguments, Format);
|
||||
|
||||
/* Format and print the string to the desired output */
|
||||
BlStringPrint(PutChar, Format, Arguments);
|
||||
BlpStringPrint(PrintCharRoutine, Format, Arguments);
|
||||
|
||||
/* Clean up the va_list */
|
||||
VA_END(Arguments);
|
||||
@ -277,7 +221,7 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character),
|
||||
/**
|
||||
* This routine converts 32-bit integer as string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Number
|
||||
@ -292,25 +236,25 @@ BlpStringFormat(IN VOID PutChar(IN USHORT Character),
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character),
|
||||
IN INT32 Number,
|
||||
IN UINT32 Base)
|
||||
BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN INT Number,
|
||||
IN UINT Base)
|
||||
{
|
||||
/* Print - (minus) if this is negative value */
|
||||
if(Number < 0)
|
||||
{
|
||||
PutChar(L'-');
|
||||
PrintCharRoutine(L'-');
|
||||
Number *= -1;
|
||||
}
|
||||
|
||||
/* Print the integer value */
|
||||
BlpStringPrintUnsigned32(PutChar, Number, Base, 0);
|
||||
BlpStringPrintUnsigned32(PrintCharRoutine, Number, Base, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine converts 64-bit integer as string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Number
|
||||
@ -325,25 +269,25 @@ BlpStringPrintSigned32(IN VOID PutChar(IN USHORT Character),
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character),
|
||||
BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN INT_PTR Number,
|
||||
IN UINT_PTR Base)
|
||||
{
|
||||
/* Print - (minus) if this is negative value */
|
||||
if(Number < 0)
|
||||
{
|
||||
PutChar(L'-');
|
||||
PrintCharRoutine(L'-');
|
||||
Number *= -1;
|
||||
}
|
||||
|
||||
/* Print the integer value */
|
||||
BlpStringPrintUnsigned64(PutChar, Number, Base, 0);
|
||||
BlpStringPrintUnsigned64(PrintCharRoutine, Number, Base, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine converts 32-bit unsigned integer as string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Number
|
||||
@ -361,23 +305,27 @@ BlpStringPrintSigned64(IN VOID PutChar(IN USHORT Character),
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character),
|
||||
IN UINT32 Number,
|
||||
IN UINT32 Base,
|
||||
IN UINT32 Padding)
|
||||
BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN UINT Number,
|
||||
IN UINT Base,
|
||||
IN UINT Padding)
|
||||
{
|
||||
UINT32 Buffer[20];
|
||||
PUINT32 Pointer = Buffer + ARRAY_SIZE(Buffer);
|
||||
UINT Buffer[20];
|
||||
UINT NumberLength;
|
||||
PUINT Pointer;
|
||||
|
||||
/* Set pointer to the end of buffer */
|
||||
Pointer = Buffer + ARRAY_SIZE(Buffer);
|
||||
|
||||
/* Convert value to specified base system */
|
||||
*--Pointer = 0;
|
||||
do
|
||||
{
|
||||
*--Pointer = EfiHexTable[Number % Base];
|
||||
*--Pointer = BlpHexTable[Number % Base];
|
||||
} while(Pointer >= Buffer && (Number /= Base));
|
||||
|
||||
/* Calculate number length */
|
||||
UINT32 NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1;
|
||||
NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1;
|
||||
|
||||
/* Check if leading zeros are needed */
|
||||
if(NumberLength < Padding)
|
||||
@ -386,21 +334,21 @@ BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character),
|
||||
while(Padding--)
|
||||
{
|
||||
/* Write leading zeroes */
|
||||
PutChar(L'0');
|
||||
PrintCharRoutine(L'0');
|
||||
}
|
||||
}
|
||||
|
||||
/* Print value to the console */
|
||||
for(; *Pointer; ++Pointer)
|
||||
{
|
||||
PutChar(*Pointer);
|
||||
PrintCharRoutine(*Pointer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine converts 64-bit unsigned integer as string and prints it using specified routine.
|
||||
*
|
||||
* @param PutChar
|
||||
* @param PrintCharRoutine
|
||||
* Pointer to the routine that writes an input data to specific device.
|
||||
*
|
||||
* @param Number
|
||||
@ -418,23 +366,27 @@ BlpStringPrintUnsigned32(IN VOID PutChar(IN USHORT Character),
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character),
|
||||
BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine,
|
||||
IN UINT_PTR Number,
|
||||
IN UINT_PTR Base,
|
||||
IN UINT_PTR Padding)
|
||||
{
|
||||
UINT16 Buffer[20];
|
||||
PUINT16 Pointer = Buffer + ARRAY_SIZE(Buffer);
|
||||
UINT_PTR NumberLength;
|
||||
PUINT16 Pointer;
|
||||
|
||||
/* Set pointer to the end of buffer */
|
||||
Pointer = Buffer + ARRAY_SIZE(Buffer);
|
||||
|
||||
/* Convert value to specified base system */
|
||||
*--Pointer = 0;
|
||||
do
|
||||
{
|
||||
*--Pointer = EfiHexTable[Number % Base];
|
||||
*--Pointer = BlpHexTable[Number % Base];
|
||||
} while(Pointer >= Buffer && (Number /= Base));
|
||||
|
||||
/* Calculate number length */
|
||||
UINT_PTR NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1;
|
||||
NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1;
|
||||
|
||||
/* Check if leading zeros are needed */
|
||||
if(NumberLength < Padding)
|
||||
@ -443,14 +395,14 @@ BlpStringPrintUnsigned64(IN VOID PutChar(IN USHORT Character),
|
||||
while(Padding--)
|
||||
{
|
||||
/* Write leading zeroes */
|
||||
PutChar(L'0');
|
||||
PrintCharRoutine(L'0');
|
||||
}
|
||||
}
|
||||
|
||||
/* Print value to the console */
|
||||
for(; *Pointer; ++Pointer)
|
||||
{
|
||||
PutChar(*Pointer);
|
||||
PrintCharRoutine(*Pointer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,77 +0,0 @@
|
||||
/**
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/system.c
|
||||
* DESCRIPTION: EFI system information
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
|
||||
|
||||
/**
|
||||
* This routine checks whether SecureBoot is enabled or not.
|
||||
*
|
||||
* @return Numeric representation of SecureBoot status (0 = Disabled, >0 = Enabled, <0 SetupMode).
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
INT_PTR
|
||||
BlEfiGetSecureBootStatus()
|
||||
{
|
||||
EFI_GUID VarGuid = EFI_GLOBAL_VARIABLE_GUID;
|
||||
INT_PTR SecureBootStatus = 0;
|
||||
UCHAR VarValue = 0;
|
||||
UINT_PTR Size;
|
||||
|
||||
Size = sizeof(VarValue);
|
||||
if(EfiSystemTable->RuntimeServices->GetVariable(L"SecureBoot", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
SecureBootStatus = (INT_PTR)VarValue;
|
||||
|
||||
if((EfiSystemTable->RuntimeServices->GetVariable(L"SetupMode", &VarGuid,
|
||||
NULL, &Size, &VarValue) == STATUS_EFI_SUCCESS) && VarValue != 0)
|
||||
{
|
||||
SecureBootStatus = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return SecureBoot status */
|
||||
return SecureBootStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read system configuration from a specified table.
|
||||
*
|
||||
* @param TableGuid
|
||||
* Supplies a pointer to the GUID to search for.
|
||||
*
|
||||
* @param Table
|
||||
* Supplies a pointer that will point to the configuration table.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEfiGetSystemConfigurationTable(IN PEFI_GUID TableGuid,
|
||||
OUT PVOID *Table)
|
||||
{
|
||||
SIZE_T Size = sizeof(EFI_GUID);
|
||||
UINT_PTR Index;
|
||||
|
||||
for(Index = 0; Index < EfiSystemTable->NumberOfTableEntries; Index++)
|
||||
{
|
||||
if(RtlCompareMemory((PVOID)&EfiSystemTable->ConfigurationTable[Index].VendorGuid, TableGuid, Size) == Size)
|
||||
{
|
||||
*Table = EfiSystemTable->ConfigurationTable[Index].VendorTable;
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Table not found */
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
1288
xtldr/textui.c
Normal file
1288
xtldr/textui.c
Normal file
File diff suppressed because it is too large
Load Diff
239
xtldr/volume.c
239
xtldr/volume.c
@ -6,7 +6,7 @@
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ BlCloseVolume(IN PEFI_HANDLE VolumeHandle)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlEnumerateEfiBlockDevices()
|
||||
BlEnumerateBlockDevices()
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL LastNode = NULL;
|
||||
PEFI_BLOCK_DEVICE_DATA ParentNode = NULL;
|
||||
@ -70,7 +70,7 @@ BlEnumerateEfiBlockDevices()
|
||||
Status = BlpDiscoverEfiBlockDevices(&BlockDevices);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDbgPrint(L"ERROR: Failed to discover EFI block devices (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"ERROR: Failed to discover EFI block devices (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -82,16 +82,16 @@ BlEnumerateEfiBlockDevices()
|
||||
BlockDeviceData = CONTAIN_RECORD(ListEntry, EFI_BLOCK_DEVICE_DATA, ListEntry);
|
||||
|
||||
/* Find last node */
|
||||
Status = BlpFindLastEfiBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
|
||||
Status = BlpFindLastBlockDeviceNode(BlockDeviceData->DevicePath, &LastNode);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDbgPrint(L"WARNING: Block device last node not found\n");
|
||||
BlDebugPrint(L"WARNING: Block device last node not found\n");
|
||||
ListEntry = ListEntry->Flink;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Set drive type to 'unknown' by default */
|
||||
DriveType = XT_BOOT_DEVICE_UNKNOWN;
|
||||
DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
|
||||
|
||||
/* Check last node type */
|
||||
if(LastNode->Type == EFI_ACPI_DEVICE_PATH && LastNode->SubType == EFI_ACPI_DP)
|
||||
@ -102,12 +102,12 @@ BlEnumerateEfiBlockDevices()
|
||||
{
|
||||
/* Floppy drive found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XT_BOOT_DEVICE_FLOPPY;
|
||||
DriveType = XTBL_BOOT_DEVICE_FLOPPY;
|
||||
DriveNumber = FDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
|
||||
BlDebugPrint(L"Found Floppy Disk (DiskNumber: %lu, MediaPresent: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->ReadOnly);
|
||||
}
|
||||
}
|
||||
@ -118,12 +118,12 @@ BlEnumerateEfiBlockDevices()
|
||||
{
|
||||
/* Optical drive found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XT_BOOT_DEVICE_CDROM;
|
||||
DriveType = XTBL_BOOT_DEVICE_CDROM;
|
||||
DriveNumber = CDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
|
||||
BlDebugPrint(L"Found CD-ROM drive (DriveNumber: %lu, MediaPresent: %u, RemovableMedia: %u, RO: %u)\n",
|
||||
DriveNumber, Media->MediaPresent, Media->RemovableMedia, Media->ReadOnly);
|
||||
}
|
||||
else if(LastNode->SubType == EFI_MEDIA_HARDDRIVE_DP)
|
||||
@ -131,13 +131,13 @@ BlEnumerateEfiBlockDevices()
|
||||
/* Hard disk partition found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
HDPath = (PEFI_HARDDRIVE_DEVICE_PATH)LastNode;
|
||||
DriveType = XT_BOOT_DEVICE_HARDDISK;
|
||||
DriveType = XTBL_BOOT_DEVICE_HARDDISK;
|
||||
DriveNumber = (HDPath->PartitionNumber == 1) ? HDCount++ : HDCount - 1;
|
||||
PartitionNumber = HDPath->PartitionNumber;
|
||||
PartitionGuid = (PEFI_GUID)HDPath->Signature;
|
||||
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
|
||||
BlDebugPrint(L"Found Hard Disk partition (DiskNumber: %lu, PartNumber: %lu, "
|
||||
L"MBRType: %u, GUID: {%g}, PartSize: %luB)\n",
|
||||
DriveNumber, PartitionNumber, HDPath->MBRType,
|
||||
PartitionGuid, HDPath->PartitionSize * Media->BlockSize);
|
||||
@ -146,30 +146,30 @@ BlEnumerateEfiBlockDevices()
|
||||
{
|
||||
/* RAM disk found */
|
||||
Media = BlockDeviceData->BlockIo->Media;
|
||||
DriveType = XT_BOOT_DEVICE_RAMDISK;
|
||||
DriveType = XTBL_BOOT_DEVICE_RAMDISK;
|
||||
DriveNumber = RDCount++;
|
||||
PartitionNumber = 0;
|
||||
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
|
||||
BlDebugPrint(L"Found RAM Disk (DiskNumber: %lu, MediaPresent: %u)\n",
|
||||
DriveNumber, Media->MediaPresent);
|
||||
}
|
||||
|
||||
if(!BlpFindParentEfiBlockDevice(&BlockDevices, BlockDeviceData, ParentNode))
|
||||
if(!BlpFindParentBlockDevice(&BlockDevices, BlockDeviceData, ParentNode))
|
||||
{
|
||||
BlDbgPrint(L"WARNING: No parent device found, skipping orphaned media device path\n");
|
||||
BlDebugPrint(L"WARNING: No parent device found, skipping orphaned media device path\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the device found has valid type set */
|
||||
if(DriveType != XT_BOOT_DEVICE_UNKNOWN)
|
||||
if(DriveType != XTBL_BOOT_DEVICE_UNKNOWN)
|
||||
{
|
||||
/* Allocate memory for block device */
|
||||
Status = BlEfiMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
|
||||
Status = BlMemoryAllocatePool(sizeof(EFI_BLOCK_DEVICE), (PVOID *)&BlockDevice);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDbgPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status);
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
FsPathLength = RtlWideStringLength(FileSystemPath, 0) * sizeof(WCHAR);
|
||||
|
||||
/* Allocate memory pool for device path */
|
||||
Status = BlEfiMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
|
||||
Status = BlMemoryAllocatePool(FsPathLength + DevicePathLength + sizeof(EFI_DEVICE_PATH_PROTOCOL),
|
||||
(PVOID *)DevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
@ -294,16 +294,16 @@ BlFindVolumeDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL FsHandle,
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlGetVolumeDevicePath(IN PUCHAR SystemPath,
|
||||
BlGetVolumeDevicePath(IN PWCHAR SystemPath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
||||
OUT PUCHAR *ArcName,
|
||||
OUT PUCHAR *Path)
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path)
|
||||
{
|
||||
PEFI_BLOCK_DEVICE Device;
|
||||
USHORT DriveType;
|
||||
ULONG DriveNumber;
|
||||
ULONG PartNumber;
|
||||
PUCHAR Volume;
|
||||
PWCHAR Volume;
|
||||
ULONG PathLength;
|
||||
PLIST_ENTRY ListEntry;
|
||||
EFI_STATUS Status;
|
||||
@ -333,13 +333,13 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath,
|
||||
if(PathLength == GUID_STRING_LENGTH)
|
||||
{
|
||||
/* This is EFI GUID */
|
||||
BlDbgPrint(L"EFI/GPT GUID in system path is not supported yet\n");
|
||||
BlDebugPrint(L"WARNING: EFI/GPT GUID in system path is not supported\n");
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
else if(PathLength == PARTUUID_STRING_LENGTH)
|
||||
{
|
||||
/* This is MBR UUID */
|
||||
BlDbgPrint(L"MBR partition UUID in system path is not supported yet\n");
|
||||
BlDebugPrint(L"WARNING: MBR partition UUID in system path is not supported\n");
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
else
|
||||
@ -358,7 +358,7 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath,
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse system path */
|
||||
BlDbgPrint(L"Failed to parse system path: '%s' with status code: %lx\n", SystemPath, Status);
|
||||
BlDebugPrint(L"ERROR: Failed to parse system path: '%s' (Status Code: 0x%lx)\n", SystemPath, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ BlGetVolumeDevicePath(IN PUCHAR SystemPath,
|
||||
if(*DevicePath == NULL)
|
||||
{
|
||||
/* Failed to find volume */
|
||||
BlDbgPrint(L"Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
|
||||
BlDebugPrint(L"ERROR: Volume (DriveType: %u, DriveNumber: %lu, PartNumber: %lu) not found\n",
|
||||
DriveType, DriveNumber, PartNumber);
|
||||
return STATUS_EFI_NOT_FOUND;
|
||||
}
|
||||
@ -470,6 +470,125 @@ BlOpenVolume(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the file.
|
||||
*
|
||||
* @param DirHandle
|
||||
* Supplies a handle of the opened filesystem directory.
|
||||
*
|
||||
* @param FileName
|
||||
* Supplies the name of the file to read.
|
||||
*
|
||||
* @param FileData
|
||||
* Provides a buffer to store the data read from the file.
|
||||
*
|
||||
* @param FileSize
|
||||
* Provides a pointer to the variable to store a size of the buffer.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlReadFile(IN PEFI_FILE_HANDLE DirHandle,
|
||||
IN CONST PWCHAR FileName,
|
||||
OUT PVOID *FileData,
|
||||
OUT PSIZE_T FileSize)
|
||||
{
|
||||
EFI_GUID FileInfoGuid = EFI_FILE_INFO_PROTOCOL_GUID;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
PEFI_FILE_HANDLE FileHandle;
|
||||
PEFI_FILE_INFO FileInfo;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR ReadSize;
|
||||
SIZE_T Pages;
|
||||
|
||||
Status = DirHandle->Open(DirHandle, &FileHandle, FileName, EFI_FILE_MODE_READ,
|
||||
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open file */
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set required size for getting file information */
|
||||
ReadSize = sizeof(EFI_FILE_INFO) + 32;
|
||||
|
||||
/* Allocate necessary amount of memory */
|
||||
Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
FileHandle->Close(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* First attempt to get file information */
|
||||
FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);
|
||||
if(Status == STATUS_EFI_BUFFER_TOO_SMALL)
|
||||
{
|
||||
/* Buffer is too small, but EFI tells the required size, so reallocate */
|
||||
BlMemoryFreePool(&FileInfo);
|
||||
Status = BlMemoryAllocatePool(ReadSize, (PVOID *)&FileInfo);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
FileHandle->Close(FileHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Second attempt to get file information */
|
||||
Status = FileHandle->GetInfo(FileHandle, &FileInfoGuid, &ReadSize, FileInfo);
|
||||
}
|
||||
|
||||
/* Check if file information got successfully */
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Unable to get file information */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlMemoryFreePool(&FileInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Store file size and calculate number of pages */
|
||||
*FileSize = FileInfo->FileSize;
|
||||
Pages = EFI_SIZE_TO_PAGES(FileInfo->FileSize);
|
||||
|
||||
/* Allocate pages */
|
||||
Status = BlMemoryAllocatePages(Pages, &Address);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Pages allocation failure */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlMemoryFreePool(&FileInfo);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Calculate number of bytes to read and zero memory*/
|
||||
ReadSize = Pages * EFI_PAGE_SIZE;
|
||||
*FileData = (PCHAR)(UINT_PTR)Address;
|
||||
RtlZeroMemory(*FileData, ReadSize);
|
||||
|
||||
/* Read data from the file */
|
||||
Status = FileHandle->Read(FileHandle, &ReadSize, *FileData);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to read data */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlMemoryFreePool(&FileInfo);
|
||||
BlMemoryFreePages(Pages, (EFI_PHYSICAL_ADDRESS)(UINT_PTR)*FileData);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close handle and free memory */
|
||||
FileHandle->Close(FileHandle);
|
||||
BlMemoryFreePool(&FileInfo);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of block devices from an EFI enabled BIOS.
|
||||
*
|
||||
@ -498,7 +617,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to locate handles */
|
||||
BlDbgPrint(L"ERROR: Failed to locate block devices handles (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"ERROR: Failed to locate block devices handles (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
@ -506,7 +625,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
for(Index = 0; Index < HandlesCount; Index++)
|
||||
{
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
|
||||
BlDebugPrint(L"Opening %lu block device from %lu discovered\n", Index + 1, HandlesCount);
|
||||
|
||||
/* Open I/O protocol for given handle */
|
||||
Io = NULL;
|
||||
@ -515,7 +634,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
if(Status != STATUS_EFI_SUCCESS || Io == NULL)
|
||||
{
|
||||
/* Failed to open I/O protocol, skip it */
|
||||
BlDbgPrint(L"WARNING: Failed to open EFI Block I/O protocol (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"WARNING: Failed to open EFI Block I/O protocol (Status Code: 0x%lx)\n", Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -523,7 +642,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
if(Io->Media && Io->Media->BlockSize == 1 && Io->Media->MediaId == 0x69505845U)
|
||||
{
|
||||
/* Skip stub as it is non-functional */
|
||||
BlDbgPrint(L"WARNING: iPXE stub block I/O protocol");
|
||||
BlDebugPrint(L"WARNING: Skipping iPXE stub block I/O protocol");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -533,17 +652,17 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
if(Status != STATUS_EFI_SUCCESS || DevicePath == NULL)
|
||||
{
|
||||
/* Device failed to handle DP protocol */
|
||||
BlDbgPrint(L"WARNING: Unable to open DevicePath protocol (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"WARNING: Unable to open DevicePath protocol (Status Code: 0x%lx)\n", Status);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate memory for block device */
|
||||
Status = BlEfiMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
|
||||
Status = BlMemoryAllocatePool(sizeof(*BlockDevice), (PVOID *)&BlockDevice);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Memory allocation failure */
|
||||
BlDbgPrint(L"ERROR: Unable to allocate memory pool for block device (status code: %lx)\n", Status);
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for block device (Status Code: 0x%lx)\n", Status);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &DevicePathGuid, EfiImageHandle, NULL);
|
||||
EfiSystemTable->BootServices->CloseProtocol(Handles[Index], &IoGuid, EfiImageHandle, NULL);
|
||||
return Status;
|
||||
@ -556,7 +675,7 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
}
|
||||
|
||||
/* Free handles buffer */
|
||||
BlEfiMemoryFreePool(Handles);
|
||||
BlMemoryFreePool(Handles);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
@ -586,36 +705,36 @@ BlpDiscoverEfiBlockDevices(OUT PLIST_ENTRY BlockDevices)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
OUT PUCHAR *ArcName,
|
||||
OUT PUCHAR *Path,
|
||||
BlpDissectVolumeArcPath(IN PWCHAR SystemPath,
|
||||
OUT PWCHAR *ArcName,
|
||||
OUT PWCHAR *Path,
|
||||
OUT PUSHORT DriveType,
|
||||
OUT PULONG DriveNumber,
|
||||
OUT PULONG PartNumber)
|
||||
{
|
||||
PUCHAR ArcPath, LocalArcName;
|
||||
PWCHAR ArcPath, LocalArcName;
|
||||
ULONG ArcLength = 0;
|
||||
|
||||
/* Set default values */
|
||||
*DriveType = XT_BOOT_DEVICE_UNKNOWN;
|
||||
*DriveType = XTBL_BOOT_DEVICE_UNKNOWN;
|
||||
*DriveNumber = 0;
|
||||
*PartNumber = 0;
|
||||
|
||||
/* Look for the ARC path */
|
||||
if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"ramdisk(0)") == 0)
|
||||
if(RtlCompareWideStringInsensitive(SystemPath, L"ramdisk(0)", 0) == 0)
|
||||
{
|
||||
/* This is RAM disk */
|
||||
ArcLength = 10;
|
||||
*DriveType = XT_BOOT_DEVICE_RAMDISK;
|
||||
*DriveType = XTBL_BOOT_DEVICE_RAMDISK;
|
||||
}
|
||||
else if(BlStringCompareInsensitive(SystemPath, (PUCHAR)"multi(0)disk(0)") == 0)
|
||||
else if(RtlCompareWideStringInsensitive(SystemPath, L"multi(0)disk(0)", 0) == 0)
|
||||
{
|
||||
/* This is a multi-disk port */
|
||||
ArcLength = 15;
|
||||
ArcPath = SystemPath + ArcLength;
|
||||
|
||||
/* Check for disk type */
|
||||
if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"cdrom(") == 0)
|
||||
if(RtlCompareWideStringInsensitive(ArcPath, L"cdrom(", 0) == 0)
|
||||
{
|
||||
/* This is an optical drive */
|
||||
ArcLength += 6;
|
||||
@ -633,10 +752,10 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
}
|
||||
|
||||
/* Set proper drive type */
|
||||
*DriveType = XT_BOOT_DEVICE_CDROM;
|
||||
*DriveType = XTBL_BOOT_DEVICE_CDROM;
|
||||
ArcLength++;
|
||||
}
|
||||
else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"fdisk(") == 0)
|
||||
else if(RtlCompareWideStringInsensitive(ArcPath, L"fdisk(", 0) == 0)
|
||||
{
|
||||
/* This is a floppy drive */
|
||||
ArcLength += 6;
|
||||
@ -654,10 +773,10 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
}
|
||||
|
||||
/* Set proper drive type */
|
||||
*DriveType = XT_BOOT_DEVICE_FLOPPY;
|
||||
*DriveType = XTBL_BOOT_DEVICE_FLOPPY;
|
||||
ArcLength++;
|
||||
}
|
||||
else if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"rdisk(") == 0)
|
||||
else if(RtlCompareWideStringInsensitive(ArcPath, L"rdisk(", 0) == 0)
|
||||
{
|
||||
/* This is a hard disk */
|
||||
ArcLength += 6;
|
||||
@ -675,12 +794,12 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
}
|
||||
|
||||
/* Set proper drive type */
|
||||
*DriveType = XT_BOOT_DEVICE_HARDDISK;
|
||||
*DriveType = XTBL_BOOT_DEVICE_HARDDISK;
|
||||
ArcLength++;
|
||||
ArcPath = SystemPath + ArcLength;
|
||||
|
||||
/* Look for a partition */
|
||||
if(BlStringCompareInsensitive(ArcPath, (PUCHAR)"partition(") == 0)
|
||||
if(RtlCompareWideStringInsensitive(ArcPath, L"partition(", 0) == 0)
|
||||
{
|
||||
/* Partition information found */
|
||||
ArcLength += 10;
|
||||
@ -720,8 +839,8 @@ BlpDissectVolumeArcPath(IN PUCHAR SystemPath,
|
||||
/* Store ARC name if possible */
|
||||
if(ArcName)
|
||||
{
|
||||
BlEfiMemoryAllocatePool(ArcLength, (PVOID *)&LocalArcName);
|
||||
RtlCopyMemory(LocalArcName, SystemPath, ArcLength);
|
||||
BlMemoryAllocatePool(ArcLength * sizeof(WCHAR), (PVOID *)&LocalArcName);
|
||||
RtlCopyMemory(LocalArcName, SystemPath, ArcLength * sizeof(WCHAR));
|
||||
LocalArcName[ArcLength] = '\0';
|
||||
*ArcName = LocalArcName;
|
||||
}
|
||||
@ -770,11 +889,11 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
|
||||
}
|
||||
|
||||
/* Allocate memory for the new device path */
|
||||
Status = BlEfiMemoryAllocatePool(Length, (PVOID *)&DevicePathClone);
|
||||
Status = BlMemoryAllocatePool(Length, (PVOID *)&DevicePathClone);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory */
|
||||
BlDbgPrint(L"ERROR: Unable to allocate memory pool for device path duplicate\n");
|
||||
BlDebugPrint(L"ERROR: Failed to allocate memory pool for device path duplicate (Status Code: 0x%lx)\n", Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -800,8 +919,8 @@ BlpDuplicateDevicePath(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath)
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
|
||||
BlpFindLastBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
OUT PEFI_DEVICE_PATH_PROTOCOL *LastNode)
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL EndNode, NextNode;
|
||||
|
||||
@ -846,9 +965,9 @@ BlpFindLastEfiBlockDeviceNode(IN PEFI_DEVICE_PATH_PROTOCOL DevicePath,
|
||||
*/
|
||||
XTCDECL
|
||||
BOOLEAN
|
||||
BlpFindParentEfiBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA ParentNode)
|
||||
BlpFindParentBlockDevice(IN PLIST_ENTRY BlockDevices,
|
||||
IN PEFI_BLOCK_DEVICE_DATA ChildNode,
|
||||
OUT PEFI_BLOCK_DEVICE_DATA ParentNode)
|
||||
{
|
||||
PEFI_DEVICE_PATH_PROTOCOL ChildDevicePath, ParentDevicePath;
|
||||
PEFI_BLOCK_DEVICE_DATA BlockDeviceData;
|
||||
|
583
xtldr/xtldr.c
583
xtldr/xtldr.c
@ -2,216 +2,161 @@
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* FILE: xtldr/xtldr.c
|
||||
* DESCRIPTION: UEFI XT Bootloader
|
||||
* DESCRIPTION: XTOS UEFI Boot Loader
|
||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||
*/
|
||||
|
||||
#include <xtbl.h>
|
||||
#include <xtldr.h>
|
||||
|
||||
|
||||
/**
|
||||
* This routine loads XTLDR EFI modules.
|
||||
* Initializes EFI Boot Loader (XTLDR).
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadEfiModules()
|
||||
VOID
|
||||
BlInitializeBootLoader()
|
||||
{
|
||||
CONST PWCHAR ModulesDirPath = L"\\EFI\\BOOT\\XTLDR\\";
|
||||
EFI_GUID DevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
|
||||
EFI_GUID LIPGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_DEVICE_PATH_PROTOCOL VolumeDevicePath, DevicePath;
|
||||
EFI_GUID LipGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
|
||||
PEFI_LOADED_IMAGE_PROTOCOL LoadedImage;
|
||||
PEFI_FILE_HANDLE FsHandle, ModulesDir;
|
||||
EFI_HANDLE DiskHandle, ModuleHandle;
|
||||
SIZE_T Length;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
UINT_PTR DirSize;
|
||||
CHAR Buffer[1024];
|
||||
WCHAR ModulePath[1024];
|
||||
PWCHAR ModuleName;
|
||||
|
||||
/* Open EFI volume */
|
||||
Status = BlOpenVolume(NULL, &DiskHandle, &FsHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
/* Set current XTLDR's EFI BootServices status */
|
||||
BlpStatus.BootServices = TRUE;
|
||||
|
||||
/* Initialize console */
|
||||
BlInitializeConsole();
|
||||
|
||||
/* Print XTLDR version */
|
||||
BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
||||
|
||||
/* Initialize XTLDR configuration linked lists */
|
||||
RtlInitializeListHead(&BlpBootProtocols);
|
||||
RtlInitializeListHead(&BlpConfig);
|
||||
RtlInitializeListHead(&BlpLoadedModules);
|
||||
|
||||
/* Store SecureBoot status */
|
||||
BlpStatus.SecureBoot = BlGetSecureBootStatus();
|
||||
|
||||
/* Check if debug is enabled */
|
||||
if(DEBUG)
|
||||
{
|
||||
/* Failed to open a volume */
|
||||
return Status;
|
||||
/* Attempt to open EFI LoadedImage protocol */
|
||||
Status = BlOpenProtocol(&Handle, (PVOID *)&LoadedImage, &LipGuid);
|
||||
if(Status == STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Protocol opened successfully, print useful debug information */
|
||||
BlConsolePrint(L"\n---------- BOOTLOADER DEBUG ----------\n"
|
||||
L"Pointer Size : %d\n"
|
||||
L"Image Base Address: 0x%lx\n"
|
||||
L"Image Base Size : 0x%lx\n"
|
||||
L"Image Revision : 0x%lx\n"
|
||||
L"--------------------------------------\n",
|
||||
sizeof(PVOID),
|
||||
LoadedImage->ImageBase,
|
||||
LoadedImage->ImageSize,
|
||||
LoadedImage->Revision);
|
||||
BlSleepExecution(3000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Open EFI/BOOT/XTLDR directory, which contains all the modules and close the FS immediately */
|
||||
Status = FsHandle->Open(FsHandle, &ModulesDir, ModulesDirPath, EFI_FILE_MODE_READ, 0);
|
||||
FsHandle->Close(FsHandle);
|
||||
|
||||
/* Check if modules directory opened successfully */
|
||||
if(Status == STATUS_EFI_NOT_FOUND)
|
||||
{
|
||||
/* Directory not found, nothing to load */
|
||||
BlDbgPrint(L"WARNING: Boot loader directory (EFI/BOOT/XTLDR) not found\n");
|
||||
|
||||
/* Close volume */
|
||||
BlCloseVolume(DiskHandle);
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
else if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open directory */
|
||||
BlDbgPrint(L"ERROR: Unable to open XTLDR directory (EFI/BOOT/XTLDR)\n");
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Open EFI device path protocol */
|
||||
Status = EfiSystemTable->BootServices->HandleProtocol(DiskHandle, &DevicePathGuid, (PVOID *)&DevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Close volume */
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Iterate through files inside XTLDR directory */
|
||||
while(TRUE)
|
||||
{
|
||||
/* Read directory */
|
||||
DirSize = sizeof(Buffer);
|
||||
Status = ModulesDir->Read(ModulesDir, &DirSize, Buffer);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to read directory */
|
||||
BlDbgPrint(L"\n");
|
||||
|
||||
/* Close directory and volume */
|
||||
ModulesDir->Close(ModulesDir);
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Check if read anything */
|
||||
if(DirSize == 0)
|
||||
{
|
||||
/* Already read all contents, break loop execution */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Take filename and its length */
|
||||
ModuleName = ((PEFI_FILE_INFO)Buffer)->FileName;
|
||||
Length = RtlWideStringLength(ModuleName, 0);
|
||||
|
||||
/* Make sure we deal with .EFI executable file */
|
||||
if(Length < 4 || ModuleName[Length - 4] != '.' ||
|
||||
(ModuleName[Length - 3] != 'E' && ModuleName[Length - 3] != 'e') ||
|
||||
(ModuleName[Length - 2] != 'F' && ModuleName[Length - 2] != 'f') ||
|
||||
(ModuleName[Length - 1] != 'I' && ModuleName[Length - 1] != 'i'))
|
||||
{
|
||||
/* Skip non .EFI file */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Print debug message */
|
||||
BlDbgPrint(L"Loading module '%S' ... ", ModuleName);
|
||||
|
||||
/* Set correct path to the module file */
|
||||
RtlCopyMemory(ModulePath, ModulesDirPath, sizeof(ModulePath) / sizeof(WCHAR));
|
||||
RtlConcatenateWideString(ModulePath, ModuleName, 0);
|
||||
|
||||
/* Find valid device path */
|
||||
Status = BlFindVolumeDevicePath(DevicePath, ModulePath, &VolumeDevicePath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to set path */
|
||||
BlDbgPrint(L"FAIL\n");
|
||||
BlDbgPrint(L"ERROR: Unable to set valid device path\n");
|
||||
|
||||
/* Close directory and volume */
|
||||
ModulesDir->Close(ModulesDir);
|
||||
BlCloseVolume(DiskHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load the module into memory */
|
||||
Status = EfiSystemTable->BootServices->LoadImage(FALSE, EfiImageHandle, VolumeDevicePath,
|
||||
NULL, 0, &ModuleHandle);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Module failed */
|
||||
BlDbgPrint(L"FAIL\n");
|
||||
|
||||
/* Check if caused by secure boot */
|
||||
if(Status == STATUS_EFI_ACCESS_DENIED && EfiSecureBoot >= 1)
|
||||
{
|
||||
BlDbgPrint(L"ERROR: SecureBoot signature validation failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
BlDbgPrint(L"ERROR: Unable to load module (Status code: %lx)\n", Status);
|
||||
}
|
||||
|
||||
/* Free memory and skip module */
|
||||
BlEfiMemoryFreePool(VolumeDevicePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
BlEfiMemoryFreePool(VolumeDevicePath);
|
||||
|
||||
/* Access module interface for further module type check */
|
||||
Status = EfiSystemTable->BootServices->OpenProtocol(ModuleHandle, &LIPGuid, (PVOID *)&LoadedImage,
|
||||
EfiImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open protocol */
|
||||
BlDbgPrint(L"FAIL\n");
|
||||
BlDbgPrint(L"ERROR: Unable to access module interface\n");
|
||||
|
||||
/* Skip to the next module */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Some firmwares do not allow to start drivers which are not of 'boot system driver' type, so check it */
|
||||
if(LoadedImage->ImageCodeType != EfiBootServicesCode)
|
||||
{
|
||||
/* Different type set, probably 'runtime driver', refuse to load it */
|
||||
BlDbgPrint(L"FAIL\n");
|
||||
BlDbgPrint(L"ERROR: Loaded module is not a boot system driver\n");
|
||||
|
||||
/* Close protocol and skip module */
|
||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Close loaded image protocol */
|
||||
EfiSystemTable->BootServices->CloseProtocol(LoadedImage, &LIPGuid, LoadedImage, NULL);
|
||||
|
||||
/* Start the module */
|
||||
Status = EfiSystemTable->BootServices->StartImage(ModuleHandle, NULL, NULL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Module failed */
|
||||
BlDbgPrint(L"FAIL\n");
|
||||
BlDbgPrint(L"ERROR: Unable to start module\n");
|
||||
|
||||
/* Skip module */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Module loaded successfully */
|
||||
BlDbgPrint(L"OK\n");
|
||||
}
|
||||
|
||||
/* Close directory and volume */
|
||||
ModulesDir->Close(ModulesDir);
|
||||
BlCloseVolume(DiskHandle);
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine attempts to start XT Operating System.
|
||||
* Initializes a list of operating systems for XTLDR boot menu.
|
||||
*
|
||||
* @param MenuEntries
|
||||
* Supplies a pointer to memory area where operating systems list will be stored.
|
||||
*
|
||||
* @param EntriesCount
|
||||
* Supplies a pointer to memory area where number of menu entries will be stored.
|
||||
*
|
||||
* @param DefaultId
|
||||
* Supplies a pointer to memory area where ID of default menu entry will be stored.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
VOID
|
||||
BlInitializeBootMenuList(OUT PXTBL_BOOTMENU_ITEM MenuEntries,
|
||||
OUT PULONG EntriesCount,
|
||||
OUT PULONG DefaultId)
|
||||
{
|
||||
PWCHAR DefaultMenuEntry, MenuEntryName;
|
||||
PLIST_ENTRY MenuEntrySectionList, MenuEntryList;
|
||||
PXTBL_CONFIG_SECTION MenuEntrySection;
|
||||
PXTBL_CONFIG_ENTRY MenuEntryOption;
|
||||
PXTBL_BOOTMENU_ITEM OsList;
|
||||
ULONG DefaultOS, NumberOfEntries;
|
||||
|
||||
/* Set default values */
|
||||
DefaultOS = 0;
|
||||
NumberOfEntries = 0;
|
||||
OsList = NULL;
|
||||
|
||||
/* Get default menu entry from configuration */
|
||||
DefaultMenuEntry = BlGetConfigValue(L"DEFAULT");
|
||||
|
||||
/* Iterate through all menu sections */
|
||||
MenuEntrySectionList = BlpMenuList->Flink;
|
||||
while(MenuEntrySectionList != BlpMenuList)
|
||||
{
|
||||
/* NULLify menu entry name */
|
||||
MenuEntryName = NULL;
|
||||
|
||||
/* Get menu section */
|
||||
MenuEntrySection = CONTAIN_RECORD(MenuEntrySectionList, XTBL_CONFIG_SECTION, Flink);
|
||||
|
||||
/* Check if this is the default menu entry */
|
||||
if(RtlCompareWideStringInsensitive(MenuEntrySection->SectionName, DefaultMenuEntry, 0) == 0)
|
||||
{
|
||||
/* Set default OS ID */
|
||||
DefaultOS = NumberOfEntries;
|
||||
}
|
||||
|
||||
/* Iterate through all entry parameters */
|
||||
MenuEntryList = MenuEntrySection->Options.Flink;
|
||||
while(MenuEntryList != &MenuEntrySection->Options)
|
||||
{
|
||||
/* Get menu entry parameter */
|
||||
MenuEntryOption = CONTAIN_RECORD(MenuEntryList, XTBL_CONFIG_ENTRY, Flink);
|
||||
|
||||
/* Check if this is the menu entry display name */
|
||||
if(RtlCompareWideStringInsensitive(MenuEntryOption->Name, L"SYSTEMNAME", 0) == 0)
|
||||
{
|
||||
/* Set menu entry display name */
|
||||
MenuEntryName = MenuEntryOption->Value;
|
||||
}
|
||||
|
||||
/* Get next parameter for this menu entry */
|
||||
MenuEntryList = MenuEntryList->Flink;
|
||||
}
|
||||
|
||||
/* Add OS to the boot menu list */
|
||||
OsList[NumberOfEntries].EntryName = MenuEntryName;
|
||||
OsList[NumberOfEntries].Options = &MenuEntrySection->Options;
|
||||
|
||||
/* Get next menu entry */
|
||||
MenuEntrySectionList = MenuEntrySectionList->Flink;
|
||||
NumberOfEntries++;
|
||||
}
|
||||
|
||||
/* Set return values */
|
||||
*DefaultId = DefaultOS;
|
||||
*EntriesCount = NumberOfEntries;
|
||||
MenuEntries = OsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all necessary modules and invokes boot protocol.
|
||||
*
|
||||
* @param OptionsList
|
||||
* Supplies a pointer to list of options associated with chosen boot menu entry.
|
||||
*
|
||||
* @return This routine returns a status code.
|
||||
*
|
||||
@ -219,90 +164,118 @@ BlLoadEfiModules()
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlLoadXtSystem()
|
||||
BlInvokeBootProtocol(IN PLIST_ENTRY OptionsList)
|
||||
{
|
||||
EFI_GUID ProtocolGuid = XT_XTOS_BOOT_PROTOCOL_GUID;
|
||||
XT_BOOT_PROTOCOL_PARAMETERS BootParameters;
|
||||
PXT_BOOT_PROTOCOL BootProtocol;
|
||||
PUCHAR ArcName, SystemPath;
|
||||
XTBL_BOOT_PARAMETERS BootParameters;
|
||||
PXTBL_BOOT_PROTOCOL BootProtocol;
|
||||
PLIST_ENTRY OptionsListEntry;
|
||||
PXTBL_CONFIG_ENTRY Option;
|
||||
EFI_GUID BootProtocolGuid;
|
||||
SIZE_T ModuleListLength;
|
||||
PWCHAR ModulesList;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_STATUS Status;
|
||||
PCHAR ArcPath;
|
||||
SIZE_T Length;
|
||||
|
||||
/* Set ARC path */
|
||||
ArcPath = "multi(0)disk(0)rdisk(0)partition(1)/ExectOS";
|
||||
/* Initialize boot parameters and a list of modules */
|
||||
RtlZeroMemory(&BootParameters, sizeof(XTBL_BOOT_PARAMETERS));
|
||||
ModulesList = NULL;
|
||||
|
||||
/* Zero boot parameters structure to NULLify all pointers */
|
||||
RtlZeroMemory(&BootParameters, sizeof(XT_BOOT_PROTOCOL_PARAMETERS));
|
||||
|
||||
/* Get boot volume path */
|
||||
Status = BlGetVolumeDevicePath((PUCHAR)ArcPath, &BootParameters.DevicePath, &ArcName, &SystemPath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
/* Iterate through all options provided by boot menu entry and propagate boot parameters */
|
||||
OptionsListEntry = OptionsList->Flink;
|
||||
while(OptionsListEntry != OptionsList)
|
||||
{
|
||||
/* Failed to find volume */
|
||||
BlDbgPrint(L"ERROR: Unable to find volume device path\n");
|
||||
return Status;
|
||||
/* Get option */
|
||||
Option = CONTAIN_RECORD(OptionsListEntry, XTBL_CONFIG_ENTRY, Flink);
|
||||
|
||||
/* Look for boot protocol and modules list */
|
||||
if(RtlCompareWideStringInsensitive(Option->Name, L"BOOTMODULES", 0) == 0)
|
||||
{
|
||||
/* Check a length of modules list */
|
||||
ModuleListLength = RtlWideStringLength(Option->Value, 0);
|
||||
|
||||
Status = BlMemoryAllocatePool(sizeof(PWCHAR) * ModuleListLength, (PVOID *)&ModulesList);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to allocate memory, print error message and return status code */
|
||||
BlDebugPrint(L"ERROR: Memory allocation failure (Status Code: 0x%lx)\n", Status);
|
||||
return STATUS_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
/* Make a copy of modules list */
|
||||
RtlCopyMemory(ModulesList, Option->Value, sizeof(PWCHAR) * ModuleListLength);
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMTYPE", 0) == 0)
|
||||
{
|
||||
/* Boot protocol found */
|
||||
BootParameters.SystemType = Option->Value;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"SYSTEMPATH", 0) == 0)
|
||||
{
|
||||
/* System path found, get volume device path */
|
||||
Status = BlGetVolumeDevicePath((PWCHAR)Option->Value, &BootParameters.DevicePath, &BootParameters.ArcName, &BootParameters.SystemPath);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to find volume */
|
||||
BlDebugPrint(L"ERROR: Failed to find volume device path (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"KERNELFILE", 0) == 0)
|
||||
{
|
||||
/* Kernel file name found */
|
||||
BootParameters.KernelFile = Option->Value;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"INITRDFILE", 0) == 0)
|
||||
{
|
||||
/* Initrd file name found */
|
||||
BootParameters.InitrdFile = Option->Value;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"HALFILE", 0) == 0)
|
||||
{
|
||||
/* Hal file name found */
|
||||
BootParameters.HalFile = Option->Value;
|
||||
}
|
||||
else if(RtlCompareWideStringInsensitive(Option->Name, L"PARAMETERS", 0) == 0)
|
||||
{
|
||||
/* Kernel parameters found */
|
||||
BootParameters.Parameters = Option->Value;
|
||||
}
|
||||
|
||||
/* Move to the next option entry */
|
||||
OptionsListEntry = OptionsListEntry->Flink;
|
||||
}
|
||||
|
||||
/* Store ARC name in boot parameters */
|
||||
Length = RtlStringLength(ArcName, 0);
|
||||
BlEfiMemoryAllocatePool(Length + 1, (PVOID *)&BootParameters.ArcName);
|
||||
RtlStringToWideString(BootParameters.ArcName, &ArcName, Length * 2);
|
||||
/* Load all necessary modules */
|
||||
Status = BlLoadModules(ModulesList);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load modules, print error message and return status code */
|
||||
BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status);
|
||||
return STATUS_EFI_NOT_READY;
|
||||
}
|
||||
|
||||
/* Store system path in boot parameters */
|
||||
Length = RtlStringLength(SystemPath, 0);
|
||||
BlEfiMemoryAllocatePool(Length + 1, (PVOID *)&BootParameters.SystemPath);
|
||||
RtlStringToWideString(BootParameters.SystemPath, &SystemPath, Length + 1);
|
||||
/* Attempt to get boot protocol GUID */
|
||||
Status = BlFindBootProtocol(BootParameters.SystemType, &BootProtocolGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to get boot protocol GUID */
|
||||
BlDebugPrint(L"ERROR: Unable to find appropriate boot protocol (Status Code: 0x%lx)\n", Status);
|
||||
return STATUS_EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Open the XT boot protocol */
|
||||
Status = BlLoadXtProtocol((PVOID *)&BootProtocol, &ProtocolGuid);
|
||||
/* Open boot protocol */
|
||||
Status = BlOpenProtocol(&Handle, (PVOID *)&BootProtocol, &BootProtocolGuid);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to open boot protocol */
|
||||
BlDbgPrint(L"ERROR: Unable to load boot protocol\n");
|
||||
return STATUS_EFI_PROTOCOL_ERROR;
|
||||
BlDebugPrint(L"ERROR: Failed to open boot protocol (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Boot operating system */
|
||||
/* Boot Operating System */
|
||||
return BootProtocol->BootSystem(&BootParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine registers XTLDR protocol for further usage by modules.
|
||||
*
|
||||
* @return This routine returns status code.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTCDECL
|
||||
EFI_STATUS
|
||||
BlRegisterXtLoaderProtocol()
|
||||
{
|
||||
EFI_GUID Guid = XT_BOOT_LOADER_PROTOCOL_GUID;
|
||||
EFI_HANDLE Handle = NULL;
|
||||
|
||||
/* Set all routines available via loader protocol */
|
||||
EfiLdrProtocol.AddVirtualMemoryMapping = BlAddVirtualMemoryMapping;
|
||||
EfiLdrProtocol.AllocatePages = BlEfiMemoryAllocatePages;
|
||||
EfiLdrProtocol.AllocatePool = BlEfiMemoryAllocatePool;
|
||||
EfiLdrProtocol.FreePages = BlEfiMemoryFreePages;
|
||||
EfiLdrProtocol.FreePool = BlEfiMemoryFreePool;
|
||||
EfiLdrProtocol.EnablePaging = BlEnablePaging;
|
||||
EfiLdrProtocol.GetMemoryMap = BlGetMemoryMap;
|
||||
EfiLdrProtocol.GetVirtualAddress = BlGetVirtualAddress;
|
||||
EfiLdrProtocol.InitializeVirtualMemory = BlInitializeVirtualMemory;
|
||||
EfiLdrProtocol.MapVirtualMemory = BlMapVirtualMemory;
|
||||
EfiLdrProtocol.DbgPrint = BlDbgPrint;
|
||||
EfiLdrProtocol.EfiPrint = BlEfiPrint;
|
||||
EfiLdrProtocol.CloseVolume = BlCloseVolume;
|
||||
EfiLdrProtocol.OpenVolume = BlOpenVolume;
|
||||
|
||||
/* Register loader protocol */
|
||||
BlDbgPrint(L"Registering XT loader protocol\n");
|
||||
return EfiSystemTable->BootServices->InstallProtocolInterface(&Handle, &Guid, EFI_NATIVE_INTERFACE,
|
||||
&EfiLdrProtocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine is the entry point of the XT EFI boot loader.
|
||||
*
|
||||
@ -327,71 +300,101 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
|
||||
EfiImageHandle = ImageHandle;
|
||||
EfiSystemTable = SystemTable;
|
||||
|
||||
/* Initialize EFI console */
|
||||
BlConsoleInitialize();
|
||||
BlEfiPrint(L"XTLDR boot loader v%s\n", XTOS_VERSION);
|
||||
/* Initialize XTLDR and */
|
||||
BlInitializeBootLoader();
|
||||
|
||||
/* Early initialize COM port for debugging */
|
||||
/* Parse configuration options passed from UEFI shell */
|
||||
Status = BlpParseCommandLine();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to parse command line options */
|
||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to parse command line parameters.");
|
||||
}
|
||||
|
||||
/* Attempt to early initialize debug console */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = BlComPortInitialize();
|
||||
Status = BlpInitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, try printing error to stdout and serial console */
|
||||
BlEfiPrint(L"ERROR: Failed to initialize serial console\n");
|
||||
/* Initialization failed, notify user on stdout */
|
||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check SecureBoot status */
|
||||
EfiSecureBoot = BlEfiGetSecureBootStatus();
|
||||
/* Load XTLDR configuration file */
|
||||
Status = BlpLoadConfiguration();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to load/parse config file */
|
||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to load and parse configuration file ");
|
||||
}
|
||||
|
||||
/* Print firmware information */
|
||||
BlDbgPrint(L"UEFI v%d.%d (%S 0x%08x), SecureBoot %S\n", EfiSystemTable->Hdr.Revision >> 16,
|
||||
EfiSystemTable->Hdr.Revision & 0xFFFF, EfiSystemTable->FirmwareVendor, EfiSystemTable->FirmwareRevision,
|
||||
EfiSecureBoot == 0 ? L"DISABLED" : EfiSecureBoot > 0 ? L"ENABLED" : L"SETUP");
|
||||
/* Reinitialize debug console if it was not initialized earlier */
|
||||
if(DEBUG)
|
||||
{
|
||||
Status = BlpInitializeDebugConsole();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Initialization failed, notify user on stdout */
|
||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to initialize debug console.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable watchdog timer */
|
||||
Status = EfiSystemTable->BootServices->SetWatchdogTimer(0, 0x10000, 0, NULL);
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to disable the timer, print message */
|
||||
BlDbgPrint(L"WARNING: Failed to disable watchdog timer\n");
|
||||
BlDebugPrint(L"WARNING: Failed to disable watchdog timer (Status Code: 0x%lx)\n", Status);
|
||||
}
|
||||
|
||||
/* Register loader protocol */
|
||||
Status = BlRegisterXtLoaderProtocol();
|
||||
/* Install loader protocol */
|
||||
Status = BlpInstallXtLoaderProtocol();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Failed to register loader protocol */
|
||||
BlDbgPrint(L"ERROR: Failed to register XTLDR loader protocol\n");
|
||||
BlDebugPrint(L"ERROR: Failed to register XTLDR loader protocol (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Load XTLDR modules */
|
||||
Status = BlLoadEfiModules();
|
||||
/* Load boot loader modules */
|
||||
Status = BlLoadModules(BlGetConfigValue(L"MODULES"));
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
BlDbgPrint(L"ERROR: Failed to load XTLDR modules\n");
|
||||
/* Failed to load modules */
|
||||
BlDebugPrint(L"ERROR: Failed to load XTLDR modules (Status Code: 0x%lx)\n", Status);
|
||||
BlDisplayErrorDialog(L"XTLDR", L"Failed to load some XTLDR modules.");
|
||||
}
|
||||
|
||||
/* Discover and enumerate EFI block devices */
|
||||
BlEnumerateEfiBlockDevices();
|
||||
|
||||
/* Boot XTOS */
|
||||
Status = BlLoadXtSystem();
|
||||
Status = BlEnumerateBlockDevices();
|
||||
if(Status != STATUS_EFI_SUCCESS)
|
||||
{
|
||||
/* Boot process failed */
|
||||
BlEfiPrint(L"Failed to start XT OS (Status code: %lx)!\n", Status);
|
||||
/* Failed to enumerate block devices */
|
||||
BlDebugPrint(L"ERROR: Failed to discover and enumerate block devices (Status Code: 0x%lx)\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Infinite bootloader loop */
|
||||
BlEfiPrint(L"System halted!");
|
||||
for(;;)
|
||||
/* Main boot loader loop */
|
||||
while(TRUE)
|
||||
{
|
||||
ArClearInterruptFlag();
|
||||
ArHalt();
|
||||
/* Check if custom boot menu registered */
|
||||
if(BlpStatus.BootMenu != NULL)
|
||||
{
|
||||
/* Display alternative boot menu */
|
||||
BlpStatus.BootMenu();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Display default boot menu */
|
||||
BlDisplayBootMenu();
|
||||
}
|
||||
|
||||
/* Fallback to shell, if boot menu returned */
|
||||
BlStartLoaderShell();
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return STATUS_EFI_SUCCESS;
|
||||
/* This point should be never reached, if this happen return error code */
|
||||
return STATUS_EFI_LOAD_ERROR;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user