mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
[boot] Add initial stubs for loading kernel ELF
This commit is contained in:
@@ -60,6 +60,7 @@ modules:
|
|||||||
- src/boot/error.cpp
|
- src/boot/error.cpp
|
||||||
- src/boot/fs.cpp
|
- src/boot/fs.cpp
|
||||||
- src/boot/hardware.cpp
|
- src/boot/hardware.cpp
|
||||||
|
- src/boot/loader.cpp
|
||||||
- src/boot/memory.cpp
|
- src/boot/memory.cpp
|
||||||
|
|
||||||
nulldrv:
|
nulldrv:
|
||||||
|
|||||||
@@ -1,46 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef ELF_VERSION
|
namespace boot {
|
||||||
#define ELF_VERSION 1
|
namespace elf {
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ELF_WORDSIZE
|
constexpr uint8_t version = 1;
|
||||||
#define ELF_WORDSIZE 2
|
constexpr uint8_t word_size = 2;
|
||||||
#endif
|
constexpr uint8_t endianness = 1;
|
||||||
|
constexpr uint8_t os_abi = 1;
|
||||||
#ifndef ELF_ENDIAN
|
constexpr uint16_t machine = 0x3e;
|
||||||
#define ELF_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ELF_OSABI
|
|
||||||
#define ELF_OSABI 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ELF_MACHINE
|
|
||||||
#define ELF_MACHINE 0x3e
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const unsigned ELF_PT_LOAD = 1;
|
const unsigned ELF_PT_LOAD = 1;
|
||||||
const unsigned ELF_ST_PROGBITS = 1;
|
const unsigned ELF_ST_PROGBITS = 1;
|
||||||
const unsigned ELF_ST_NOBITS = 8;
|
const unsigned ELF_ST_NOBITS = 8;
|
||||||
const unsigned long ELF_SHF_ALLOC = 0x2;
|
const unsigned long ELF_SHF_ALLOC = 0x2;
|
||||||
|
|
||||||
struct elf_ident
|
struct header
|
||||||
{
|
{
|
||||||
char magic[4];
|
char magic[4];
|
||||||
|
|
||||||
uint8_t word_size;
|
uint8_t word_size;
|
||||||
uint8_t endianness;
|
uint8_t endianness;
|
||||||
uint8_t version;
|
uint8_t header_version;
|
||||||
uint8_t os_abi;
|
uint8_t os_abi;
|
||||||
|
|
||||||
uint64_t reserved;
|
uint64_t reserved;
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct elf_header
|
|
||||||
{
|
|
||||||
struct elf_ident ident;
|
|
||||||
|
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t machine;
|
uint16_t machine;
|
||||||
@@ -64,7 +48,7 @@ struct elf_header
|
|||||||
uint16_t sh_str_idx;
|
uint16_t sh_str_idx;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct elf_program_header
|
struct program_header
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@@ -79,7 +63,7 @@ struct elf_program_header
|
|||||||
uint64_t align;
|
uint64_t align;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct elf_section_header
|
struct section_header
|
||||||
{
|
{
|
||||||
uint32_t name;
|
uint32_t name;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
@@ -92,3 +76,6 @@ struct elf_section_header
|
|||||||
uint64_t align;
|
uint64_t align;
|
||||||
uint64_t entry_size;
|
uint64_t entry_size;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
} // namespace elf
|
||||||
|
} // namespace boot
|
||||||
|
|||||||
@@ -1,193 +1,33 @@
|
|||||||
#include "elf.h"
|
#include <uefi/boot_services.h>
|
||||||
#include "guids.h"
|
#include <uefi/types.h>
|
||||||
|
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "memory.h"
|
#include "console.h"
|
||||||
#include "utility.h"
|
#include "elf.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
#define PAGE_SIZE 0x1000
|
namespace boot {
|
||||||
|
namespace loader {
|
||||||
|
|
||||||
static wchar_t kernel_name[] = KERNEL_FILENAME;
|
static bool
|
||||||
static wchar_t initrd_name[] = INITRD_FILENAME;
|
is_elfheader_valid(const elf::header *header)
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
loader_alloc_aligned(
|
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
|
||||||
EFI_MEMORY_TYPE mem_type,
|
|
||||||
size_t *length,
|
|
||||||
void **pages)
|
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
return false;
|
||||||
EFI_PHYSICAL_ADDRESS addr;
|
|
||||||
|
|
||||||
size_t alignment = PAGE_SIZE;
|
|
||||||
while (alignment < *length)
|
|
||||||
alignment *= 2;
|
|
||||||
|
|
||||||
size_t page_count = alignment / PAGE_SIZE;
|
|
||||||
*length = alignment;
|
|
||||||
|
|
||||||
con_debug(L"Trying to find %d aligned pages for %x", page_count, mem_type);
|
|
||||||
|
|
||||||
status = bootsvc->AllocatePages(AllocateAnyPages, mem_type, page_count * 2, &addr);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating %d pages for alignment", page_count * 2);
|
|
||||||
con_debug(L" Found %d pages at %lx", page_count * 2, addr);
|
|
||||||
|
|
||||||
EFI_PHYSICAL_ADDRESS aligned = addr;
|
|
||||||
aligned = ((aligned - 1) & ~(alignment - 1)) + alignment;
|
|
||||||
con_debug(L" Aligning %lx to %lx", addr, aligned);
|
|
||||||
|
|
||||||
size_t before =
|
|
||||||
(reinterpret_cast<uint64_t>(aligned) -
|
|
||||||
reinterpret_cast<uint64_t>(addr)) /
|
|
||||||
PAGE_SIZE;
|
|
||||||
|
|
||||||
if (before) {
|
|
||||||
con_debug(L" Freeing %d initial pages", before);
|
|
||||||
bootsvc->FreePages(addr, before);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t after = page_count - before;
|
kernel::entrypoint
|
||||||
if (after) {
|
load_elf(
|
||||||
EFI_PHYSICAL_ADDRESS end =
|
const void *data,
|
||||||
reinterpret_cast<EFI_PHYSICAL_ADDRESS>(
|
size_t size,
|
||||||
reinterpret_cast<uint64_t>(aligned) +
|
uefi::boot_services *bs)
|
||||||
page_count * PAGE_SIZE);
|
|
||||||
con_debug(L" Freeing %d remaining pages", after);
|
|
||||||
bootsvc->FreePages(end, after);
|
|
||||||
}
|
|
||||||
|
|
||||||
*pages = (void *)aligned;
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
loader_alloc_pages(
|
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
|
||||||
EFI_MEMORY_TYPE mem_type,
|
|
||||||
size_t *length,
|
|
||||||
void **pages)
|
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
status_line status(L"Loading kernel ELF binary");
|
||||||
|
|
||||||
size_t page_count = ((*length - 1) / PAGE_SIZE) + 1;
|
if (size < sizeof(elf::header) ||
|
||||||
EFI_PHYSICAL_ADDRESS addr = (EFI_PHYSICAL_ADDRESS)*pages;
|
!is_elfheader_valid(reinterpret_cast<const elf::header*>(data)))
|
||||||
|
error::raise(uefi::status::load_error, L"Kernel ELF not valid");
|
||||||
con_debug(L"Trying to find %d non-aligned pages for %x at %lx",
|
|
||||||
page_count, mem_type, addr);
|
|
||||||
|
|
||||||
status = bootsvc->AllocatePages(AllocateAddress, mem_type, page_count, &addr);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status,
|
|
||||||
L"Allocating %d kernel pages type %x",
|
|
||||||
page_count, mem_type);
|
|
||||||
|
|
||||||
*length = page_count * PAGE_SIZE;
|
|
||||||
*pages = (void *)addr;
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
loader_load_initrd(
|
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
|
||||||
EFI_FILE_PROTOCOL *root,
|
|
||||||
struct loader_data *data)
|
|
||||||
{
|
|
||||||
EFI_STATUS status;
|
|
||||||
|
|
||||||
EFI_FILE_PROTOCOL *file = NULL;
|
|
||||||
status = root->Open(root, &file, (wchar_t *)initrd_name, EFI_FILE_MODE_READ,
|
|
||||||
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
|
||||||
|
|
||||||
if (status == EFI_NOT_FOUND)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Opening file %s", initrd_name);
|
|
||||||
|
|
||||||
char info[sizeof(EFI_FILE_INFO) + 100];
|
|
||||||
size_t info_length = sizeof(info);
|
|
||||||
|
|
||||||
status = file->GetInfo(file, &guid_file_info, &info_length, info);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Getting file info");
|
|
||||||
|
|
||||||
data->initrd_length = ((EFI_FILE_INFO *)info)->FileSize;
|
|
||||||
|
|
||||||
status = loader_alloc_aligned(
|
|
||||||
bootsvc,
|
|
||||||
memtype_initrd,
|
|
||||||
&data->initrd_length,
|
|
||||||
&data->initrd);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Allocating pages");
|
|
||||||
|
|
||||||
status = file->Read(file, &data->initrd_length, data->initrd);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading file");
|
|
||||||
|
|
||||||
status = file->Close(file);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Closing file handle");
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
loader_load_elf(
|
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
|
||||||
EFI_FILE_PROTOCOL *root,
|
|
||||||
struct loader_data *data)
|
|
||||||
{
|
|
||||||
EFI_STATUS status;
|
|
||||||
|
|
||||||
con_debug(L"Opening kernel file %s", (wchar_t *)kernel_name);
|
|
||||||
|
|
||||||
EFI_FILE_PROTOCOL *file = NULL;
|
|
||||||
status = root->Open(root, &file, (wchar_t *)kernel_name, EFI_FILE_MODE_READ,
|
|
||||||
EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
|
|
||||||
|
|
||||||
if (status == EFI_NOT_FOUND)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
uint64_t length = 0;
|
|
||||||
data->kernel = 0;
|
|
||||||
data->kernel_entry = 0;
|
|
||||||
data->kernel_length = 0;
|
|
||||||
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Opening file %s", kernel_name);
|
|
||||||
|
|
||||||
struct elf_header header;
|
|
||||||
|
|
||||||
length = sizeof(struct elf_header);
|
|
||||||
status = file->Read(file, &length, &header);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading ELF header");
|
|
||||||
|
|
||||||
con_debug(L"Read %u bytes of ELF header", length);
|
|
||||||
|
|
||||||
if (length < sizeof(struct elf_header))
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"Incomplete read of ELF header");
|
|
||||||
|
|
||||||
static const char expected[] = {0x7f, 'E', 'L', 'F'};
|
|
||||||
for (int i = 0; i < sizeof(expected); ++i) {
|
|
||||||
if (header.ident.magic[i] != expected[i])
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"Bad ELF magic number");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (header.ident.word_size != ELF_WORDSIZE)
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"ELF load error: 32 bit ELF not supported");
|
|
||||||
|
|
||||||
if (header.ph_entsize != sizeof(struct elf_program_header))
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"ELF load error: program header size mismatch");
|
|
||||||
|
|
||||||
if (header.ident.version != ELF_VERSION ||
|
|
||||||
header.version != ELF_VERSION)
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"ELF load error: wrong ELF version");
|
|
||||||
|
|
||||||
if (header.ident.endianness != 1 ||
|
|
||||||
header.ident.os_abi != 0 ||
|
|
||||||
header.machine != 0x3e)
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_LOAD_ERROR, L"ELF load error: wrong machine architecture");
|
|
||||||
|
|
||||||
con_debug(L"ELF is valid, entrypoint %lx", header.entrypoint);
|
|
||||||
|
|
||||||
data->kernel_entry = (void *)header.entrypoint;
|
|
||||||
|
|
||||||
|
/*
|
||||||
struct elf_program_header prog_header;
|
struct elf_program_header prog_header;
|
||||||
for (int i = 0; i < header.ph_num; ++i) {
|
for (int i = 0; i < header.ph_num; ++i) {
|
||||||
|
|
||||||
@@ -242,57 +82,11 @@ loader_load_elf(
|
|||||||
status = file->Close(file);
|
status = file->Close(file);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Closing file handle");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Closing file handle");
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return reinterpret_cast<kernel::entrypoint>(kernel.entrypoint());
|
||||||
|
*/
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace loader
|
||||||
EFI_STATUS
|
} // namespace boot
|
||||||
loader_load_kernel(
|
|
||||||
EFI_BOOT_SERVICES *bootsvc,
|
|
||||||
struct loader_data *data)
|
|
||||||
{
|
|
||||||
if (data == NULL)
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(EFI_INVALID_PARAMETER, L"NULL loader_data");
|
|
||||||
|
|
||||||
EFI_STATUS status;
|
|
||||||
EFI_HANDLE *handles = NULL;
|
|
||||||
size_t handleCount = 0;
|
|
||||||
|
|
||||||
status = bootsvc->LocateHandleBuffer(ByProtocol, &guid_simple_filesystem, NULL, &handleCount, &handles);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"LocateHandleBuffer");
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < handleCount; ++i) {
|
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fileSystem = NULL;
|
|
||||||
|
|
||||||
status = bootsvc->HandleProtocol(handles[i], &guid_simple_filesystem, (void **)&fileSystem);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"HandleProtocol");
|
|
||||||
|
|
||||||
EFI_FILE_PROTOCOL *root = NULL;
|
|
||||||
status = fileSystem->OpenVolume(fileSystem, &root);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"OpenVolume");
|
|
||||||
|
|
||||||
status = loader_load_elf(bootsvc, root, data);
|
|
||||||
if (status == EFI_NOT_FOUND)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_elf: %s", kernel_name);
|
|
||||||
|
|
||||||
data->data = (void *)((uint64_t)data->kernel + data->kernel_length);
|
|
||||||
data->data_length += PAGE_SIZE; // extra page for map growth
|
|
||||||
|
|
||||||
status = loader_alloc_aligned(
|
|
||||||
bootsvc,
|
|
||||||
memtype_data,
|
|
||||||
&data->data_length,
|
|
||||||
&data->data);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_alloc_aligned: kernel data");
|
|
||||||
|
|
||||||
data->initrd = (void *)((uint64_t)data->data + data->data_length);
|
|
||||||
status = loader_load_initrd(bootsvc, root, data);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"loader_load_file: %s", initrd_name);
|
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EFI_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,35 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <efi/efi.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#define PAGE_SIZE 0x1000
|
#include "kernel_args.h"
|
||||||
|
|
||||||
#ifndef KERNEL_PHYS_ADDRESS
|
namespace boot {
|
||||||
#define KERNEL_PHYS_ADDRESS 0x100000
|
namespace loader {
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KERNEL_VIRT_ADDRESS
|
kernel::entrypoint load_elf(const void *data, size_t size, uefi::boot_services *bs);
|
||||||
#define KERNEL_VIRT_ADDRESS 0xFFFFFF0000000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KERNEL_FILENAME
|
} // namespace loader
|
||||||
#define KERNEL_FILENAME L"kernel.elf"
|
} // namespace boot
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef INITRD_FILENAME
|
|
||||||
#define INITRD_FILENAME L"initrd.img"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct loader_data {
|
|
||||||
void *kernel;
|
|
||||||
void *kernel_entry;
|
|
||||||
size_t kernel_length;
|
|
||||||
|
|
||||||
void *initrd;
|
|
||||||
size_t initrd_length;
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
size_t data_length;
|
|
||||||
};
|
|
||||||
|
|
||||||
EFI_STATUS loader_load_kernel(EFI_BOOT_SERVICES *bootsvc, struct loader_data *data);
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
|
#include "loader.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include "kernel_args.h"
|
#include "kernel_args.h"
|
||||||
@@ -38,7 +39,6 @@ struct kernel_header {
|
|||||||
uint32_t gitsha;
|
uint32_t gitsha;
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
using kernel_entry = void (*)(kernel_args *);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace boot {
|
namespace boot {
|
||||||
@@ -84,7 +84,8 @@ detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) {
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
void
|
|
||||||
|
kernel::args::module *
|
||||||
load_module(
|
load_module(
|
||||||
fs::file &disk,
|
fs::file &disk,
|
||||||
kernel::args::header *args,
|
kernel::args::header *args,
|
||||||
@@ -100,9 +101,10 @@ load_module(
|
|||||||
module.location = file.load(&module.size);
|
module.location = file.load(&module.size);
|
||||||
|
|
||||||
console::print(L" Loaded at: 0x%lx, %d bytes\r\n", module.location, module.size);
|
console::print(L" Loaded at: 0x%lx, %d bytes\r\n", module.location, module.size);
|
||||||
|
return &module;
|
||||||
}
|
}
|
||||||
|
|
||||||
uefi::status
|
kernel::entrypoint
|
||||||
bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con)
|
bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con)
|
||||||
{
|
{
|
||||||
error::uefi_handler handler(con);
|
error::uefi_handler handler(con);
|
||||||
@@ -122,28 +124,15 @@ bootloader_main_uefi(uefi::handle image, uefi::system_table *st, console &con)
|
|||||||
|
|
||||||
fs::file disk = fs::get_boot_volume(image, bs);
|
fs::file disk = fs::get_boot_volume(image, bs);
|
||||||
load_module(disk, args, L"initrd", L"initrd.img", kernel::args::type::initrd);
|
load_module(disk, args, L"initrd", L"initrd.img", kernel::args::type::initrd);
|
||||||
|
|
||||||
|
kernel::args::module *kernel =
|
||||||
load_module(disk, args, L"kernel", L"jsix.elf", kernel::args::type::kernel);
|
load_module(disk, args, L"kernel", L"jsix.elf", kernel::args::type::kernel);
|
||||||
|
|
||||||
return uefi::status::success;
|
kernel::entrypoint entry = loader::load_elf(kernel->location, kernel->size, bs);
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Compute necessary number of data pages
|
|
||||||
//
|
|
||||||
size_t data_length = 0;
|
|
||||||
status = memory_get_map_length(bootsvc, &data_length);
|
|
||||||
CHECK_EFI_STATUS_OR_FAIL(status);
|
|
||||||
|
|
||||||
size_t header_size = sizeof(kernel_args);
|
|
||||||
const size_t header_align = alignof(kernel_args);
|
|
||||||
if (header_size % header_align)
|
|
||||||
header_size += header_align - (header_size % header_align);
|
|
||||||
|
|
||||||
data_length += header_size;
|
|
||||||
|
|
||||||
// Load the kernel image from disk and check it
|
|
||||||
//
|
|
||||||
console::print(L"Loading kernel into memory...\r\n");
|
|
||||||
|
|
||||||
struct loader_data load;
|
struct loader_data load;
|
||||||
load.data_length = data_length;
|
load.data_length = data_length;
|
||||||
@@ -253,9 +242,10 @@ efi_main(uefi::handle image_handle, uefi::system_table *st)
|
|||||||
error::cpu_assert_handler handler;
|
error::cpu_assert_handler handler;
|
||||||
console con(st->boot_services, st->con_out);
|
console con(st->boot_services, st->con_out);
|
||||||
|
|
||||||
/*return*/ bootloader_main_uefi(image_handle, st, con);
|
kernel::entrypoint kernel_main =
|
||||||
|
bootloader_main_uefi(image_handle, st, con);
|
||||||
|
|
||||||
while(1);
|
while(1);
|
||||||
return uefi::status::success;
|
return uefi::status::unsupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ inline constexpr size_t bytes_to_pages(size_t bytes) {
|
|||||||
return ((bytes - 1) / page_size) + 1;
|
return ((bytes - 1) / page_size) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_pointer_fixup(uefi::boot_services *bs, uefi::runtime_services *rs);
|
void init_pointer_fixup(
|
||||||
|
uefi::boot_services *bs,
|
||||||
|
uefi::runtime_services *rs);
|
||||||
|
|
||||||
void mark_pointer_fixup(void **p);
|
void mark_pointer_fixup(void **p);
|
||||||
|
|
||||||
kernel::args::header * allocate_args_structure(uefi::boot_services *bs, size_t max_modules);
|
kernel::args::header * allocate_args_structure(uefi::boot_services *bs, size_t max_modules);
|
||||||
|
|||||||
@@ -59,4 +59,7 @@ __attribute__((aligned(alignof(max_align_t))));
|
|||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
} // namespace args
|
} // namespace args
|
||||||
|
|
||||||
|
using entrypoint = void (*)(args::header *);
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|||||||
Reference in New Issue
Block a user