Code:
Here is the error:
make
g++ -I/usr/include/elf -I/usr/include/common -I/usr/include/triton -I/usr/include/efi -I/usr/include/efi/x86_64 -I/usr/include/efi/protocol -fno-stack-protector -fpic -fshort-wchar -mno-red-zone -Wall -DEFI_FUNCTION_WRAPPER -c main.c -o main.o
In file included from main.c:13:0:
/usr/include/boot.h:62:23: error: ‘vm’ has not been declared
/usr/include/boot.h:66:15: error: ‘vm’ does not name a type
/usr/include/boot.h:73:15: error: ‘vm’ does not name a type
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:54:9: error: expected ‘;’ before ‘typedef’
main.c:47:1: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
main.c: In function ‘void WaitDebugger()’:
main.c:97:57: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
main.c:98:57: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:99:37: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:103:24: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c: In function ‘EFI_STATUS ProcessOptions(CHAR16*, UINT32)’:
main.c:148:46: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:166:23: error: invalid conversion from ‘void*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
main.c: In function ‘size_t SeekImageFile(Elf_File*, size_t, Elf_Seek_Whence)’:
main.c:228:39: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
main.c: In function ‘Elf_File* OpenImageFile(SIMPLE_READ_FILE)’:
main.c:267:51: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:24:0:
loader.h:46:6: error: initializing argument 1 of ‘void debugPrint_0(CHAR16*)’ [-fpermissive]
main.c:268:16: error: invalid conversion from ‘void*’ to ‘Elf_File* {aka Elf_File_s*}’ [-fpermissive]
main.c:275:51: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:24:0:
loader.h:46:6: error: initializing argument 1 of ‘void debugPrint_0(CHAR16*)’ [-fpermissive]
main.c:277:16: error: invalid conversion from ‘void*’ to ‘Elf_File* {aka Elf_File_s*}’ [-fpermissive]
main.c:286:51: error: ‘GetSimpleReadFileHandle’ was not declared in this scope
main.c:292:50: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:24:0:
loader.h:46:6: error: initializing argument 1 of ‘void debugPrint_0(CHAR16*)’ [-fpermissive]
main.c:294:16: error: invalid conversion from ‘void*’ to ‘Elf_File* {aka Elf_File_s*}’ [-fpermissive]
main.c: In function ‘wchar_t* LoaderStrConvert(const char*)’:
main.c:309:59: error: invalid conversion from ‘void*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
main.c:314:12: error: invalid conversion from ‘CHAR16* {aka short unsigned int*}’ to ‘wchar_t*’ [-fpermissive]
main.c: In function ‘int LoaderGetMemory(vaddr_t, u64)’:
main.c:326:1: error: invalid conversion from ‘EFI_ALLOCATE_PAGES {aka long unsigned int (*)(EFI_ALLOCATE_TYPE, EFI_MEMORY_TYPE, long unsigned int, long unsigned int*)}’ to ‘void*’ [-fpermissive]
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:319:8: error: initializing argument 1 of ‘UINT64 efi_call4(void*, UINT64, UINT64, UINT64, UINT64)’ [-fpermissive]
main.c: In function ‘int LoaderReadFile(Elf_File*, u64, u64, void*)’:
main.c:346:67: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
main.c:235:1: error: initializing argument 3 of ‘size_t ReadImageFileOff(Elf_File*, u64, char*, size_t)’ [-fpermissive]
main.c:350:32: error: ‘ASSERT’ was not declared in this scope
main.c: In function ‘EFI_STATUS StartKernel(vaddr_t)’:
main.c:377:44: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:387:1: error: invalid conversion from ‘EFI_EXIT_BOOT_SERVICES {aka long unsigned int (*)(void*, long unsigned int)}’ to ‘void*’ [-fpermissive]
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:317:8: error: initializing argument 1 of ‘UINT64 efi_call2(void*, UINT64, UINT64)’ [-fpermissive]
main.c:389:57: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:394:17: error: invalid conversion from ‘void*’ to ‘SIMPLE_INPUT_INTERFACE* {aka _SIMPLE_INPUT_INTERFACE*}’ [-fpermissive]
main.c:396:18: error: invalid conversion from ‘void*’ to ‘SIMPLE_TEXT_OUTPUT_INTERFACE* {aka _SIMPLE_TEXT_OUTPUT_INTERFACE*}’ [-fpermissive]
main.c:398:18: error: invalid conversion from ‘void*’ to ‘SIMPLE_TEXT_OUTPUT_INTERFACE* {aka _SIMPLE_TEXT_OUTPUT_INTERFACE*}’ [-fpermissive]
main.c:399:24: error: invalid conversion from ‘void*’ to ‘EFI_BOOT_SERVICES* {aka _EFI_BOOT_SERVICES*}’ [-fpermissive]
main.c: In function ‘EFI_STATUS LoadImage(SIMPLE_READ_FILE)’:
main.c:420:45: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:426:71: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:430:46: error: invalid conversion from ‘void*’ to ‘Elf* {aka Elf_s*}’ [-fpermissive]
In file included from main.c:19:0:
/usr/include/efi/libelf.h:205:13: error: initializing argument 3 of ‘Elf* elf_begin(Elf_File*, Elf_Cmd, Elf*)’ [-fpermissive]
main.c:433:63: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c: In function ‘EFI_STATUS LoadKernel()’:
main.c:451:53: error: cannot convert ‘const char*’ to ‘CHAR16* {aka short unsigned int*}’ for argument ‘1’ to ‘void debugPrint_1(CHAR16*, CHAR16*)’
main.c:464:1: error: invalid conversion from ‘EFI_LOCATE_HANDLE_BUFFER {aka long unsigned int (*)(EFI_LOCATE_SEARCH_TYPE, EFI_GUID*, void*, long unsigned int*, void***)}’ to ‘void*’ [-fpermissive]
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:321:8: error: initializing argument 1 of ‘UINT64 efi_call5(void*, UINT64, UINT64, UINT64, UINT64, UINT64)’ [-fpermissive]
main.c:484:16: error: invalid conversion from ‘void*’ to ‘EFI_DEVICE_PATH* {aka _EFI_DEVICE_PATH*}’ [-fpermissive]
main.c: In function ‘EFI_STATUS efi_main(EFI_HANDLE, EFI_SYSTEM_TABLE*)’:
main.c:517:1: error: invalid conversion from ‘EFI_OPEN_PROTOCOL {aka long unsigned int (*)(void*, EFI_GUID*, void**, void*, void*, unsigned int)}’ to ‘void*’ [-fpermissive]
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:323:8: error: initializing argument 1 of ‘UINT64 efi_call6(void*, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64)’ [-fpermissive]
main.c:519:44: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
/usr/include/efi/efilib.h:389:1: error: initializing argument 1 of ‘UINTN Print(CHAR16*, ...)’ [-fpermissive]
main.c:529:70: error: invalid conversion from ‘void*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
main.c:112:1: error: initializing argument 1 of ‘EFI_STATUS ProcessOptions(CHAR16*, UINT32)’ [-fpermissive]
main.c:543:1: error: invalid conversion from ‘EFI_CLOSE_PROTOCOL {aka long unsigned int (*)(void*, EFI_GUID*, void*, void*)}’ to ‘void*’ [-fpermissive]
In file included from /usr/include/efi/efi_sys.h:35:0,
from main.c:17:
/usr/include/efi/efibind.h:319:8: error: initializing argument 1 of ‘UINT64 efi_call4(void*, UINT64, UINT64, UINT64, UINT64)’ [-fpermissive]
main.c:545:45: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
main.c:549:43: error: invalid conversion from ‘const wchar_t*’ to ‘CHAR16* {aka short unsigned int*}’ [-fpermissive]
In file included from main.c:18:0:
Here is the line in boot.h is complaining about (boot.h is under /usr/include):
/** This structure is passed to the higher level kernel entry point. */
struct BootstrapParam {
BootParam *bootParam; /**< Boot parameters from the boot loader. */
vaddr_t heap; /**< Current heap pointer. */
paddr_t defaultLatRoot; /**< Default LAT root table. */
vaddr_t quickMap; /**< Quick map pages. They are allocated consequentially. */
void *quickMapPte[vm::NUM_QUICK_MAP]; /**< Quick map PTEs. */
};
/** Convert bootstrap identity mapped address to kernel virtual address. */
static inline vm::Vaddr
BootToMapped(vm::Vaddr va)
{
return va - LOAD_ADDRESS + vm::VMA_KERNEL_TEXT;
}
/** Convert kernel virtual address to bootstrap identity mapped address. */
static inline vm::Vaddr
MappedToBoot(vm::Vaddr va)
{
return va - KERNEL_ADDRESS + LOAD_ADDRESS;
}
Here is the lines in EFIBIND.h that is complaining about:
// 54:
#ifdef __FreeBSD__
#include <sys/stdint.h>
#else
//
// Basic int types of various widths
//
#if (__STDC_VERSION__ < 199901L )
// No ANSI C 1999/2000 stdint.h integer width declarations
#if _MSC_EXTENSIONS
// Use Microsoft C compiler integer width declarations
typedef unsigned __int64 uint64_t;
typedef __int64 int64_t;
typedef unsigned __int32 uint32_t;
typedef __int32 int32_t;
typedef unsigned __int16 uint16_t;
typedef __int16 int16_t;
typedef unsigned __int8 uint8_t;
typedef __int8 int8_t;
#else
#ifdef UNIX_LP64
// Use LP64 programming model from C_FLAGS for integer width declarations
typedef unsigned long uint64_t;
typedef long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef char int8_t;
#else
// Assume P64 programming model from C_FLAGS for integer width declarations
typedef unsigned long long uint64_t;
typedef long long int64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;
typedef short int16_t;
typedef unsigned char uint8_t;
typedef char int8_t;
#endif
#endif
#endif
#endif /* __FreeBSD__ */
Here is main.c:
/* Boot loader options */
static int optDebugger;
static struct Option {
CHAR16 *name;
int *flag;
} options[] = {
{ L"--debugger", &optDebugger }
};
static EFI_HANDLE imageHandle;
static EFI_LOADED_IMAGE *loadedImage;
static inline int IsSpace(CHAR16 c)
{
return c == L' ' || c == L'\t' || c == L'\r' || c == L'\n';
}
static CHAR16 *
SkipSpaces(CHAR16 *str, UINT32 *size)
{
while (*size && IsSpace(*str)) {
str++;
(*size)--;
}
return str;
}
static CHAR16 *
SkipWord(CHAR16 *str, UINT32 *size)
{
while (*size && !IsSpace(*str)) {
str++;
(*size)--;
}
return str;
}
static int
WordCompare(CHAR16 *str, UINT32 *size, CHAR16 *word)
{
UINT32 len = *size;
while (len && *word && *str == *word) {
len--;
str++;
word++;
}
if (*word || (*str && !IsSpace(*str))) {
return -1;
}
return 0;
}
static void
WaitDebugger()
{
/* Change this value to non-zero in a debugger when attached */
volatile int isAttached = FALSE;
Print(L"Image base: 0x%lx\n", loadedImage->ImageBase);
Print(L"Image size: 0x%lx\n", loadedImage->ImageSize);
Print(L"Waiting for debugger...");
while (!isAttached) {
__asm__ __volatile__("pause");
}
Print(L"Attached\n");
}
/*
* Process command line options.
* optionsSize: length of options string in characters. Actual string length
* may be shorter.
*/
static EFI_STATUS
ProcessOptions(CHAR16 *optionsStr, UINT32 optionsSize)
{
struct Option *opt;
UINT32 i;
if (!optionsSize) {
return EFI_INVALID_PARAMETER;
}
/* Correct options size if null terminator is before the buffer end. */
for (i = 0; i < optionsSize; i++) {
if (!optionsStr[i]) {
optionsSize = i;
}
}
/* Skip loader image path */
optionsStr = SkipSpaces(optionsStr, &optionsSize);
optionsStr = SkipWord(optionsStr, &optionsSize);
do {
size_t optIdx;
opt = 0;
optionsStr = SkipSpaces(optionsStr, &optionsSize);
for (optIdx = 0; optIdx < sizeof(options) / sizeof(options[0]); optIdx++) {
if (!WordCompare(optionsStr, &optionsSize, options[optIdx].name)) {
opt = &options[optIdx];
*opt->flag = 1;
optionsStr = SkipWord(optionsStr, &optionsSize);
break;
}
}
} while (opt);
if (!optionsSize) {
Print(L"Kernel image not specified\n");
return EFI_INVALID_PARAMETER;
}
/* Extract kernel image file name */
i = optionsSize;
CHAR16 *nextPtr = SkipWord(optionsStr, &i);
kernelImage = (CHAR16 *)AllocatePool((nextPtr - optionsStr + 1) * sizeof(CHAR16));
if (!kernelImage) {
return EFI_OUT_OF_RESOURCES;
}
RtCopyMem(kernelImage, optionsStr, (nextPtr - optionsStr) * sizeof(CHAR16));
kernelImage[nextPtr - optionsStr] = 0;
/* Convert kernel command line to ASCII */
kernelCmdLine = (char *)AllocatePool(optionsSize / sizeof(CHAR16) + 1);
if (!kernelCmdLine) {
FreePool(kernelImage);
kernelImage = NULL;
return EFI_OUT_OF_RESOURCES;
}
for (i = 0; i < optionsSize; i++) {
kernelCmdLine[i] = (char)optionsStr[i];
}
kernelCmdLine[optionsSize] = 0;
return EFI_SUCCESS;
}
static void * _elf_malloc(size_t size)
{
return AllocatePool(size);
}
static void
_elf_mfree(void *ptr)
{
FreePool(ptr);
}
static void *
_elf_mrealloc(void *ptr, size_t size)
{
FreePool(ptr);
return AllocatePool(size);
}
typedef struct {
UINTN size;
INTN cur_offset;
SIMPLE_READ_FILE file;
EFI_FILE_HANDLE hFile;
} ImageFile;
static void
CloseImageFile(Elf_File *file)
{
if (file->f_priv) {
FreePool(file->f_priv);
}
FreePool(file);
}
static size_t
SeekImageFile(Elf_File *file, size_t offset, Elf_Seek_Whence whence)
{
ImageFile *img = (ImageFile *)file->f_priv;
switch (whence) {
case ELF_SEEK_SET:
img->cur_offset = offset;
break;
case ELF_SEEK_CUR:
img->cur_offset += offset;
break;
case ELF_SEEK_END:
img->cur_offset = img->size + offset;
break;
}
if (img->cur_offset < 0) {
img->cur_offset = 0;
} else if (img->cur_offset > img->size) {
img->cur_offset = img->size;
}
return img->cur_offset;
}
static size_t
ReadImageFileOff(Elf_File *file, u64 offset, char *buffer, size_t len)
{
ImageFile *img = (ImageFile *)file->f_priv;
UINTN read_len;
if (len > img->size - offset) {
read_len = img->size - offset;
} else {
read_len = len;
}
if (read_len && EFI_ERROR(ReadSimpleReadFile(img->file, offset,
&read_len, buffer))) {
return 0;
}
return read_len;
}
static size_t
ReadImageFile(Elf_File *file, char *buffer, size_t len)
{
ImageFile *img = (ImageFile *)file->f_priv;
size_t read_len = ReadImageFileOff(file, img->cur_offset, buffer, len);
img->cur_offset += read_len;
return read_len;
}
static Elf_File *
OpenImageFile(SIMPLE_READ_FILE file)
{
Elf_File *ef = (Elf_File *)AllocatePool(sizeof(*ef));
if (!ef) {
// DebugPrint(D_INFO, "Memory allocation failed\n");
debugPrint_0(L"Memory allocation failed\n");
return NULL;
}
RtZeroMem(ef, sizeof(*ef));
ef->f_priv = AllocatePool(sizeof(ImageFile));
if (!ef->f_priv) {
// DebugPrint(D_INFO, "Memory allocation failed\n");
debugPrint_0(L"Memory allocation failed\n");
CloseImageFile(ef);
return NULL;
}
ef->Close = CloseImageFile;
ef->Seek = SeekImageFile;
ef->Read = ReadImageFile;
ImageFile *img = (ImageFile *)ef->f_priv;
RtZeroMem(img, sizeof(*img));
img->file = file;
img->hFile = GetSimpleReadFileHandle(img->file);
/* Get file size */
EFI_FILE_INFO *info = LibFileInfo(img->hFile);
if (!info) {
// DebugPrint(D_INFO, "Failed to get file info\n");
debugPrint_0(L"Failed to get file info\n");
CloseImageFile(ef);
return NULL;
}
img->size = info->FileSize;
FreePool(info);
return ef;
}
WCHAR_T *
LoaderStrConvert(const char *str)
{
size_t len, i;
for (len = 0; str[len]; len++);
CHAR16 *msgW = AllocatePool((len + 1) * sizeof(CHAR16));
for (i = 0; i < len; i++) {
msgW[i] = str[i];
}
msgW[len] = 0;
return msgW;
}
int
LoaderGetMemory(vaddr_t address, u64 pages)
{
EFI_STATUS rc;
rc = uefi_call_wrapper(BS->AllocatePages, 4,
AllocateAddress,
EfiRuntimeServicesCode,
pages,
&address);
return EFI_ERROR(rc) ? -1 : 0;
}
void *
LoaderAlloc(size_t size)
{
return AllocatePool(size);
}
void
LoaderFree(void *ptr)
{
return FreePool(ptr);
}
int
LoaderReadFile(Elf_File *file, u64 offset, u64 size, void *mem)
{
while (size) {
size_t num_read = ReadImageFileOff(file, offset, mem, size);
if (!num_read) {
return -1;
}
ASSERT(size >= num_read);
size -= num_read;
offset += num_read;
}
return 0;
}
typedef void (*KernelEntry)(BootParam *bootParam);
static EFI_STATUS
StartKernel(vaddr_t entry_addr)
{
/* Prepare boot parameters */
/* Kernel command line */
bootParam.cmdLine = kernelCmdLine;
for (bootParam.cmdLineSize = 0;
bootParam.cmdLine[bootParam.cmdLineSize];
bootParam.cmdLineSize++);
bootParam.cmdLineSize++;
/* Get memory map */
UINTN mapKey, mapDescSize, numEntries;
UINT32 mapDescVersion;
EFI_MEMORY_DESCRIPTOR *map = LibMemoryMap(&numEntries, &mapKey,
&mapDescSize, &mapDescVersion);
if (!map) {
Print(L"Failed to get memory map\n");
return EFI_LOAD_ERROR;
}
bootParam.memMap = map;
bootParam.memMapNumDesc = numEntries;
bootParam.memMapDescSize = mapDescSize;
bootParam.memMapDescVersion = mapDescVersion;
/* Take control over the system */
EFI_STATUS rc = uefi_call_wrapper(BS->ExitBootServices, 2,
imageHandle, mapKey);
if (EFI_ERROR(rc)) {
Print(L"Failed to exit boot services (%r)\n", rc);
return rc;
}
/* The system is ours */
ST->ConsoleInHandle = NULL;
ST->ConIn = NULL;
ST->ConsoleOutHandle = NULL;
ST->ConOut = NULL;
ST->StandardErrorHandle = NULL;
ST->StdErr = NULL;
ST->BootServices = NULL;
SetCrc(&ST->Hdr);
bootParam.efiSystemTable = (paddr_t)ST;
/* Pass control to the kernel */
KernelEntry ke = (KernelEntry)entry_addr;
ke(&bootParam);
/* NOT REACHED */
return EFI_SUCCESS;
}
static EFI_STATUS
LoadImage(SIMPLE_READ_FILE file)
{
elf_malloc = _elf_malloc;
elf_mfree = _elf_mfree;
elf_mrealloc = _elf_mrealloc;
Elf_File *ef = OpenImageFile(file);
if (!ef) {
Print(L"Failed to open image file\n");
return EFI_LOAD_ERROR;
}
if (elf_version(EV_CURRENT) == EV_NONE) {
CloseImageFile(ef);
Print(L"ELF library initialization failed: %a", elf_errmsg(-1));
return EFI_LOAD_ERROR;
}
Elf *elf = elf_begin(ef, ELF_C_READ, NULL);
if (!elf) {
CloseImageFile(ef);
Print(L"Failed to open ELF file: %a\n", elf_errmsg(-1));
return EFI_LOAD_ERROR;
}
vaddr_t entry_addr;
EFI_STATUS rc = LoadElfImage(ef, elf, &entry_addr) ? EFI_LOAD_ERROR : EFI_SUCCESS;
elf_end(elf);
if (!EFI_ERROR(rc)) {
rc = StartKernel(entry_addr);
}
return rc;
}
static EFI_STATUS
LoadKernel()
{
// DebugPrint(D_INFO, "Kernel image: '%s'\n", kernelImage);
debugPrint_1("Kernel image: '%s'\n", kernelImage);
EFI_DEVICE_PATH *path;
EFI_STATUS rc = EFI_SUCCESS;
SIMPLE_READ_FILE readHandle = NULL;
UINTN handleCount, handleIdx;
EFI_HANDLE *handleBuffer;
rc = uefi_call_wrapper(BS->LocateHandleBuffer, 5,
ByProtocol,
&FileSystemProtocol,
NULL,
&handleCount,
&handleBuffer);
if (EFI_ERROR(rc)) {
return rc;
}
for (handleIdx = 0; handleIdx < handleCount; handleIdx++) {
EFI_HANDLE deviceHandle;
path = FileDevicePath(handleBuffer[handleIdx], kernelImage);
if (!path) {
rc = EFI_NOT_FOUND;
break;
}
rc = OpenSimpleReadFile(TRUE, NULL, 0, &path, &deviceHandle, &readHandle);
if (!EFI_ERROR(rc)) {
break;
}
FreePool(path);
path = NULL;
}
if (!EFI_ERROR(rc)) {
rc = LoadImage(readHandle);
}
if (readHandle) {
CloseSimpleReadFile(readHandle);
}
if (path) {
FreePool(path);
}
FreePool(handleBuffer);
return rc;
}
EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
{
EFI_STATUS status, rc;
InitializeLib(image, systab);
imageHandle = image;
status = uefi_call_wrapper(BS->OpenProtocol,
6,
image,
&LoadedImageProtocol,
(void **)&loadedImage,
image,
NULL,
EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if (EFI_ERROR(status)) {
Print(L"OpenProtocol: %r\n", status);
return status;
}
# ifdef EFI_DEBUG
// DebugPrint(D_INFO, "Image base: 0x%lx\n", loadedImage->ImageBase);
debugPrint_1(L"Image base: 0x%lx\n", loadedImage->ImageBase);
# endif
rc = ProcessOptions(loadedImage->LoadOptions,
loadedImage->LoadOptionsSize / sizeof(CHAR16));
if (!EFI_ERROR(rc)) {
if (optDebugger) {
WaitDebugger();
}
rc = LoadKernel();
}
status = uefi_call_wrapper(BS->CloseProtocol,
4,
image,
&LoadedImageProtocol,
image,
NULL);
if (EFI_ERROR(status)) {
Print(L"CloseProtocol: %r\n", status);
}
if (EFI_ERROR(rc)) {
Print(L"Exit with error: %r\n", rc);
}
return rc;
}