Refactor boot_info.h and related files for improved abstraction and consistency. Updated function signatures to use generic types, replaced UEFI-specific types with kernel types, and enhanced documentation for clarity. Adjusted kernel entry point and service wrappers to align with new structure.
This commit is contained in:
60
boot_info.h
60
boot_info.h
@@ -1,45 +1,67 @@
|
||||
/*
|
||||
* boot_info.h – Shared interface between the UEFI loader and the kernel.
|
||||
* boot_info.h – Shared interface between the firmware loader and kernel.
|
||||
*
|
||||
* The BootInfo struct is populated by the loader (main.c) and passed to
|
||||
* the kernel entry point (kmain). It provides function pointers that
|
||||
* abstract UEFI Boot/Runtime Services so the kernel can use console I/O,
|
||||
* memory allocation, and system control without linking against GNU-EFI.
|
||||
* The BootInfo struct is populated by the platform-specific loader
|
||||
* (currently the UEFI loader in main.c) and passed to the kernel entry
|
||||
* point (kmain). It exposes only generic types and function pointers so
|
||||
* that the kernel remains independent of any particular firmware API.
|
||||
*/
|
||||
|
||||
#ifndef BOOT_INFO_H
|
||||
#define BOOT_INFO_H
|
||||
|
||||
#include <efi.h>
|
||||
/*
|
||||
* Status code returned by loader-provided services (0 = success).
|
||||
* The underlying integer type (UINT64) must be provided by including
|
||||
* either the firmware headers (e.g. <efi.h>) or the kernel type
|
||||
* header before including this file.
|
||||
*/
|
||||
typedef UINT64 KSTATUS;
|
||||
|
||||
/* Printf-style print function (backed by UEFI ConOut). */
|
||||
/* Simple key event used by the kernel's input path. */
|
||||
typedef struct {
|
||||
UINT16 scan_code;
|
||||
CHAR16 unicode_char;
|
||||
} KeyEvent;
|
||||
|
||||
/* Printf-style print function (typically backed by firmware console). */
|
||||
typedef UINTN (*KernelPrintFn)(const CHAR16 *Format, ...);
|
||||
|
||||
/* Console output helpers. */
|
||||
typedef KSTATUS (*ConsoleClearFn)(void);
|
||||
typedef KSTATUS (*ConsoleSetAttrFn)(UINTN Attribute);
|
||||
|
||||
/* Keyboard input helpers. */
|
||||
typedef KSTATUS (*KeyReadFn)(KeyEvent *Key);
|
||||
|
||||
/*
|
||||
* BootInfo – everything the kernel needs from the UEFI environment.
|
||||
* BootInfo – everything the kernel needs from the loader at boot time.
|
||||
*
|
||||
* All function pointers are optional: the kernel must NULL-check before
|
||||
* calling. If a service is unavailable the corresponding field is NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
EFI_SYSTEM_TABLE *SystemTable; /* UEFI System Table */
|
||||
|
||||
/* Console I/O */
|
||||
KernelPrintFn print; /* formatted text output */
|
||||
EFI_STATUS (*clear_screen)(void); /* clear the console */
|
||||
EFI_STATUS (*set_attribute)(UINTN Attribute); /* set text colour/attr */
|
||||
EFI_STATUS (*read_key)(EFI_INPUT_KEY *Key); /* blocking key read */
|
||||
EFI_STATUS (*try_read_key)(EFI_INPUT_KEY *Key); /* non-blocking key read */
|
||||
KernelPrintFn print; /* formatted text output */
|
||||
ConsoleClearFn clear_screen; /* clear the console */
|
||||
ConsoleSetAttrFn set_attribute; /* set text colour/attr */
|
||||
KeyReadFn read_key; /* blocking key read */
|
||||
KeyReadFn try_read_key; /* non-blocking key read */
|
||||
|
||||
/* System control */
|
||||
void (*shutdown)(void); /* power-off the machine */
|
||||
void (*shutdown)(void); /* power-off the machine */
|
||||
|
||||
/* Physical memory */
|
||||
EFI_STATUS (*alloc_pages)(UINTN pages, EFI_PHYSICAL_ADDRESS *addr);
|
||||
EFI_STATUS (*free_pages)(EFI_PHYSICAL_ADDRESS addr, UINTN pages);
|
||||
KSTATUS (*alloc_pages)(UINTN pages, UINT64 *addr);
|
||||
KSTATUS (*free_pages)(UINT64 addr, UINTN pages);
|
||||
|
||||
/* Firmware metadata (for informational commands only). */
|
||||
const CHAR16 *firmware_vendor;
|
||||
UINT32 firmware_major;
|
||||
UINT32 firmware_minor;
|
||||
} BootInfo;
|
||||
|
||||
/* Kernel entry point signature (called by the UEFI loader). */
|
||||
/* Kernel entry point signature (called by the loader). */
|
||||
typedef void (*KernelEntryFn)(BootInfo *Boot);
|
||||
|
||||
#endif /* BOOT_INFO_H */
|
||||
|
||||
21
commands.c
21
commands.c
@@ -11,7 +11,7 @@
|
||||
* 3. Append an entry to commands[] (before the sentinel)
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include "kernel_types.h"
|
||||
#include "commands.h"
|
||||
#include "string_utils.h"
|
||||
#include "memory.h"
|
||||
@@ -112,10 +112,6 @@ static Command commands[] = {
|
||||
* System control
|
||||
* ================================================================ */
|
||||
|
||||
/*
|
||||
* Try Boot->shutdown first, then fall back to RuntimeServices, then
|
||||
* print an error if neither is available.
|
||||
*/
|
||||
static void request_shutdown(BootInfo *Boot)
|
||||
{
|
||||
if (Boot == NULL) {
|
||||
@@ -127,14 +123,6 @@ static void request_shutdown(BootInfo *Boot)
|
||||
return;
|
||||
}
|
||||
|
||||
if (Boot->SystemTable != NULL &&
|
||||
Boot->SystemTable->RuntimeServices != NULL &&
|
||||
Boot->SystemTable->RuntimeServices->ResetSystem != NULL) {
|
||||
Boot->SystemTable->RuntimeServices->ResetSystem(
|
||||
EfiResetShutdown, EFI_SUCCESS, 0, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_PRINT(Boot, L"Shutdown service unavailable.\n\r");
|
||||
}
|
||||
|
||||
@@ -185,13 +173,14 @@ static void cmd_man(BootInfo *Boot, CHAR16 *Args)
|
||||
|
||||
static void cmd_clear(BootInfo *Boot, CHAR16 *Args)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
KSTATUS Status;
|
||||
(void)Args;
|
||||
|
||||
if (Boot != NULL && Boot->clear_screen != NULL) {
|
||||
Status = Boot->clear_screen();
|
||||
if (EFI_ERROR(Status)) {
|
||||
SAFE_PRINT(Boot, L"Failed to clear screen: %r\n\r", Status);
|
||||
if (Status != 0) {
|
||||
SAFE_PRINT(Boot, L"Failed to clear screen (status=%ld)\n\r",
|
||||
(UINT64)Status);
|
||||
}
|
||||
} else {
|
||||
SAFE_PRINT(Boot, L"Clear screen function unavailable.\n\r");
|
||||
|
||||
2
idt.h
2
idt.h
@@ -8,7 +8,7 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include <efi.h>
|
||||
#include "kernel_types.h"
|
||||
#include "boot_info.h"
|
||||
|
||||
/*
|
||||
|
||||
69
kernel.c
69
kernel.c
@@ -1,17 +1,16 @@
|
||||
/*
|
||||
* kernel.c – Kernel entry point and interactive shell loop.
|
||||
*
|
||||
* kmain() is called by the UEFI loader (main.c) after the ELF kernel
|
||||
* has been mapped into memory. It initialises subsystems (IDT, memory,
|
||||
* tasks), prints a welcome banner, and enters an interactive read-
|
||||
* eval-print loop that dispatches typed commands via commands.c.
|
||||
* kmain() is called by the loader (main.c) after the ELF kernel has been
|
||||
* mapped into memory. It initialises subsystems (IDT, memory, tasks),
|
||||
* prints a welcome banner, and enters an interactive read-eval-print
|
||||
* loop that dispatches typed commands via commands.c.
|
||||
*
|
||||
* While waiting for keyboard input, the shell yields to the cooperative
|
||||
* scheduler so that background tasks can make progress.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "boot_info.h"
|
||||
#include "commands.h"
|
||||
#include "idt.h"
|
||||
@@ -26,14 +25,21 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Simple text attribute helper (modelled after UEFI TEXT_ATTR). */
|
||||
#define TEXT_ATTR(fg, bg) (UINTN)(((fg) & 0x0F) | (((bg) & 0x0F) << 4))
|
||||
|
||||
/* Basic colour constants (compatible with UEFI's palette). */
|
||||
#define COLOR_BLACK 0x0
|
||||
#define COLOR_LIGHTGREEN 0xA
|
||||
|
||||
/* ================================================================
|
||||
* Kernel entry point
|
||||
* ================================================================ */
|
||||
|
||||
void kmain(BootInfo *Boot)
|
||||
{
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_STATUS Status;
|
||||
KeyEvent Key;
|
||||
KSTATUS Status;
|
||||
UINTN read_errors = 0;
|
||||
|
||||
if (Boot == NULL) {
|
||||
@@ -42,15 +48,17 @@ void kmain(BootInfo *Boot)
|
||||
|
||||
if (Boot->clear_screen != NULL) {
|
||||
Status = Boot->clear_screen();
|
||||
if (EFI_ERROR(Status)) {
|
||||
SAFE_PRINT(Boot, L"clear_screen failed: %r\n\r", Status);
|
||||
if (Status != 0) {
|
||||
SAFE_PRINT(Boot, L"clear_screen failed (status=%ld)\n\r",
|
||||
(UINT64)Status);
|
||||
}
|
||||
}
|
||||
|
||||
if (Boot->set_attribute != NULL) {
|
||||
Status = Boot->set_attribute(EFI_TEXT_ATTR(EFI_LIGHTGREEN, EFI_BLACK));
|
||||
if (EFI_ERROR(Status)) {
|
||||
SAFE_PRINT(Boot, L"set_attribute failed: %r\n\r", Status);
|
||||
Status = Boot->set_attribute(TEXT_ATTR(COLOR_LIGHTGREEN, COLOR_BLACK));
|
||||
if (Status != 0) {
|
||||
SAFE_PRINT(Boot, L"set_attribute failed (status=%ld)\n\r",
|
||||
(UINT64)Status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,26 +72,18 @@ void kmain(BootInfo *Boot)
|
||||
SAFE_PRINT(Boot, L"================================================\n\r");
|
||||
SAFE_PRINT(Boot, L"\n\r");
|
||||
SAFE_PRINT(Boot, L"System Information:\n\r");
|
||||
if (Boot->SystemTable != NULL) {
|
||||
SAFE_PRINT(Boot, L" UEFI Firmware Vendor: %s\n\r",
|
||||
Boot->SystemTable->FirmwareVendor);
|
||||
SAFE_PRINT(Boot, L" UEFI Firmware Revision: %d.%d\n\r",
|
||||
Boot->SystemTable->FirmwareRevision >> 16,
|
||||
Boot->SystemTable->FirmwareRevision & 0xFFFF);
|
||||
if (Boot->firmware_vendor != NULL) {
|
||||
SAFE_PRINT(Boot, L" Firmware Vendor: %s\n\r", Boot->firmware_vendor);
|
||||
SAFE_PRINT(Boot, L" Firmware Revision: %d.%d\n\r",
|
||||
Boot->firmware_major, Boot->firmware_minor);
|
||||
} else {
|
||||
SAFE_PRINT(Boot, L" UEFI System Table: Unavailable\n\r");
|
||||
SAFE_PRINT(Boot, L" Firmware information: Unavailable\n\r");
|
||||
}
|
||||
SAFE_PRINT(Boot, L"\n\r");
|
||||
|
||||
SAFE_PRINT(Boot, L"Available Services:\n\r");
|
||||
SAFE_PRINT(Boot, L" - Console Input/Output: %s\n\r",
|
||||
(Boot->read_key != NULL && Boot->print != NULL) ? L"Active" : L"Unavailable");
|
||||
SAFE_PRINT(Boot, L" - Runtime Services: %s\n\r",
|
||||
(Boot->SystemTable != NULL &&
|
||||
Boot->SystemTable->RuntimeServices != NULL) ? L"Active" : L"Unavailable");
|
||||
SAFE_PRINT(Boot, L" - Boot Services: %s\n\r",
|
||||
(Boot->SystemTable != NULL &&
|
||||
Boot->SystemTable->BootServices != NULL) ? L"Active" : L"Unavailable");
|
||||
SAFE_PRINT(Boot, L"\n\r");
|
||||
SAFE_PRINT(Boot, L"Type 'help' for a list of commands.\n\r\n\r");
|
||||
|
||||
@@ -97,7 +97,7 @@ void kmain(BootInfo *Boot)
|
||||
/* Try non-blocking read first; yield to other tasks while idle */
|
||||
if (Boot->try_read_key != NULL) {
|
||||
Status = Boot->try_read_key(&Key);
|
||||
if (Status == EFI_NOT_READY) {
|
||||
if (Status != 0) {
|
||||
task_yield();
|
||||
continue;
|
||||
}
|
||||
@@ -108,16 +108,17 @@ void kmain(BootInfo *Boot)
|
||||
break;
|
||||
}
|
||||
|
||||
if (EFI_ERROR(Status)) {
|
||||
if (Status != 0) {
|
||||
read_errors++;
|
||||
if (read_errors == 1 || (read_errors % 64) == 0) {
|
||||
SAFE_PRINT(Boot, L"read_key failed: %r\n\r", Status);
|
||||
SAFE_PRINT(Boot, L"read_key failed (status=%ld)\n\r",
|
||||
(UINT64)Status);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
read_errors = 0;
|
||||
|
||||
if (Key.UnicodeChar == L'\r' || Key.UnicodeChar == L'\n') {
|
||||
if (Key.unicode_char == L'\r' || Key.unicode_char == L'\n') {
|
||||
/* Enter pressed: execute the buffered command */
|
||||
line[len] = L'\0';
|
||||
SAFE_PRINT(Boot, L"\n\r");
|
||||
@@ -126,17 +127,17 @@ void kmain(BootInfo *Boot)
|
||||
/* Reset for next command */
|
||||
len = 0;
|
||||
SAFE_PRINT(Boot, L"-> ");
|
||||
} else if (Key.ScanCode == 0x08 || Key.UnicodeChar == L'\b' || Key.UnicodeChar == 0x7F) {
|
||||
} else if (Key.scan_code == 0x08 || Key.unicode_char == L'\b' || Key.unicode_char == 0x7F) {
|
||||
/* Backspace */
|
||||
if (len > 0) {
|
||||
len--;
|
||||
SAFE_PRINT(Boot, L"\b \b");
|
||||
}
|
||||
} else if (Key.UnicodeChar >= 32 && Key.UnicodeChar < 127) {
|
||||
} else if (Key.unicode_char >= 32 && Key.unicode_char < 127) {
|
||||
/* Printable ASCII */
|
||||
if (len < (sizeof(line) / sizeof(line[0]) - 1)) {
|
||||
line[len++] = Key.UnicodeChar;
|
||||
SAFE_PRINT(Boot, L"%c", Key.UnicodeChar);
|
||||
line[len++] = Key.unicode_char;
|
||||
SAFE_PRINT(Boot, L"%c", Key.unicode_char);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
kernel_types.h
Normal file
38
kernel_types.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* kernel_types.h – Common fixed-width and utility types for the kernel.
|
||||
*
|
||||
* This header deliberately avoids pulling in any firmware- or
|
||||
* platform-specific headers (such as UEFI's <efi.h>). All core kernel
|
||||
* code should include this instead of <efi.h>.
|
||||
*/
|
||||
|
||||
#ifndef KERNEL_TYPES_H
|
||||
#define KERNEL_TYPES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t UINT8;
|
||||
typedef uint16_t UINT16;
|
||||
typedef uint32_t UINT32;
|
||||
typedef uint64_t UINT64;
|
||||
|
||||
typedef size_t UINTN;
|
||||
|
||||
#ifndef BOOLEAN
|
||||
typedef bool BOOLEAN;
|
||||
#endif
|
||||
|
||||
typedef uint16_t CHAR16;
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE ((BOOLEAN)true)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE ((BOOLEAN)false)
|
||||
#endif
|
||||
|
||||
#endif /* KERNEL_TYPES_H */
|
||||
|
||||
76
main.c
76
main.c
@@ -5,7 +5,7 @@
|
||||
* firmware via the PE32+ entry point. It:
|
||||
* 1. Reads kernel.elf from the EFI System Partition
|
||||
* 2. Parses the ELF64 headers and maps PT_LOAD segments into memory
|
||||
* 3. Populates a BootInfo struct with UEFI service wrappers
|
||||
* 3. Populates a BootInfo struct with generic service wrappers
|
||||
* 4. Jumps to the kernel entry point (kmain)
|
||||
*/
|
||||
|
||||
@@ -227,26 +227,44 @@ static EFI_STATUS load_elf_kernel(VOID *Image, UINTN Size, UINT64 *EntryOut)
|
||||
* UEFI service wrappers (passed to the kernel via BootInfo)
|
||||
* ================================================================ */
|
||||
|
||||
static EFI_STATUS loader_clear_screen(void)
|
||||
static KSTATUS loader_clear_screen(void)
|
||||
{
|
||||
return uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
EFI_STATUS Status = uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
static EFI_STATUS loader_set_attribute(UINTN Attribute)
|
||||
static KSTATUS loader_set_attribute(UINTN Attribute)
|
||||
{
|
||||
return uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, Attribute);
|
||||
EFI_STATUS Status = uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, Attribute);
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
static EFI_STATUS loader_read_key(EFI_INPUT_KEY *Key)
|
||||
static KSTATUS loader_read_key(KeyEvent *Key)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_INPUT_KEY EfiKey;
|
||||
UINTN Index = 0;
|
||||
|
||||
uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &Index);
|
||||
return uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key);
|
||||
Status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &EfiKey);
|
||||
if (!EFI_ERROR(Status) && Key != NULL) {
|
||||
Key->scan_code = EfiKey.ScanCode;
|
||||
Key->unicode_char = EfiKey.UnicodeChar;
|
||||
}
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
static EFI_STATUS loader_try_read_key(EFI_INPUT_KEY *Key)
|
||||
static KSTATUS loader_try_read_key(KeyEvent *Key)
|
||||
{
|
||||
return uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, Key);
|
||||
EFI_STATUS Status;
|
||||
EFI_INPUT_KEY EfiKey;
|
||||
|
||||
Status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &EfiKey);
|
||||
if (!EFI_ERROR(Status) && Key != NULL) {
|
||||
Key->scan_code = EfiKey.ScanCode;
|
||||
Key->unicode_char = EfiKey.UnicodeChar;
|
||||
}
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
static void loader_shutdown(void)
|
||||
@@ -254,15 +272,23 @@ static void loader_shutdown(void)
|
||||
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetShutdown, EFI_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static EFI_STATUS loader_alloc_pages(UINTN pages, EFI_PHYSICAL_ADDRESS *addr)
|
||||
static KSTATUS loader_alloc_pages(UINTN pages, UINT64 *addr)
|
||||
{
|
||||
return uefi_call_wrapper(BS->AllocatePages, 4,
|
||||
AllocateAnyPages, EfiLoaderData, pages, addr);
|
||||
EFI_PHYSICAL_ADDRESS Phys = 0;
|
||||
EFI_STATUS Status = uefi_call_wrapper(BS->AllocatePages, 4,
|
||||
AllocateAnyPages, EfiLoaderData,
|
||||
pages, &Phys);
|
||||
if (!EFI_ERROR(Status) && addr != NULL) {
|
||||
*addr = (UINT64)Phys;
|
||||
}
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
static EFI_STATUS loader_free_pages(EFI_PHYSICAL_ADDRESS addr, UINTN pages)
|
||||
static KSTATUS loader_free_pages(UINT64 addr, UINTN pages)
|
||||
{
|
||||
return uefi_call_wrapper(BS->FreePages, 2, addr, pages);
|
||||
EFI_STATUS Status = uefi_call_wrapper(BS->FreePages, 2,
|
||||
(EFI_PHYSICAL_ADDRESS)addr, pages);
|
||||
return (KSTATUS)Status;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
@@ -297,16 +323,18 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Populate the BootInfo struct with UEFI service wrappers */
|
||||
Boot.SystemTable = ST;
|
||||
Boot.print = Print;
|
||||
Boot.clear_screen = loader_clear_screen;
|
||||
Boot.set_attribute = loader_set_attribute;
|
||||
Boot.read_key = loader_read_key;
|
||||
Boot.try_read_key = loader_try_read_key;
|
||||
Boot.shutdown = loader_shutdown;
|
||||
Boot.alloc_pages = loader_alloc_pages;
|
||||
Boot.free_pages = loader_free_pages;
|
||||
/* Populate the BootInfo struct with generic UEFI-backed services */
|
||||
Boot.print = Print;
|
||||
Boot.clear_screen = loader_clear_screen;
|
||||
Boot.set_attribute = loader_set_attribute;
|
||||
Boot.read_key = loader_read_key;
|
||||
Boot.try_read_key = loader_try_read_key;
|
||||
Boot.shutdown = loader_shutdown;
|
||||
Boot.alloc_pages = loader_alloc_pages;
|
||||
Boot.free_pages = loader_free_pages;
|
||||
Boot.firmware_vendor = SystemTable->FirmwareVendor;
|
||||
Boot.firmware_major = (SystemTable->FirmwareRevision >> 16) & 0xFFFF;
|
||||
Boot.firmware_minor = SystemTable->FirmwareRevision & 0xFFFF;
|
||||
|
||||
/* Jump to the kernel – this should not return */
|
||||
EntryFn = (KernelEntryFn)(UINTN)KernelEntry;
|
||||
|
||||
12
memory.c
12
memory.c
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Implements three layers:
|
||||
* PMM – bitmap-based physical page-frame allocator backed by a
|
||||
* 16 MB pool obtained from UEFI at boot.
|
||||
* 16 MB pool obtained from the loader at boot.
|
||||
* Paging – walks and creates 4-level x86-64 page tables; supports
|
||||
* map, unmap, and virtual-to-physical translation.
|
||||
* Heap – first-fit free-list allocator with block splitting and
|
||||
@@ -62,8 +62,8 @@ static BOOLEAN pmm_test_bit(UINTN idx)
|
||||
*/
|
||||
void pmm_init(BootInfo *Boot)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS pool_addr = 0;
|
||||
KSTATUS Status;
|
||||
UINT64 pool_addr = 0;
|
||||
UINTN i;
|
||||
|
||||
/* Zero the bitmap – all pages start free */
|
||||
@@ -77,9 +77,9 @@ void pmm_init(BootInfo *Boot)
|
||||
}
|
||||
|
||||
Status = Boot->alloc_pages(PMM_POOL_PAGES, &pool_addr);
|
||||
if (EFI_ERROR(Status)) {
|
||||
SAFE_PRINT(Boot, L"PMM: failed to allocate pool (%d pages): %r\n\r",
|
||||
(UINTN)PMM_POOL_PAGES, Status);
|
||||
if (Status != 0) {
|
||||
SAFE_PRINT(Boot, L"PMM: failed to allocate pool (%d pages), status=%ld\n\r",
|
||||
(UINTN)PMM_POOL_PAGES, (UINT64)Status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
2
memory.h
2
memory.h
@@ -10,7 +10,7 @@
|
||||
#ifndef MEMORY_H
|
||||
#define MEMORY_H
|
||||
|
||||
#include <efi.h>
|
||||
#include "kernel_types.h"
|
||||
#include "boot_info.h"
|
||||
|
||||
/* ================================================================
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#ifndef STRING_UTILS_H
|
||||
#define STRING_UTILS_H
|
||||
|
||||
#include <efi.h>
|
||||
#include "kernel_types.h"
|
||||
|
||||
/* Return TRUE if Ch is a space or horizontal tab. */
|
||||
BOOLEAN is_space16(CHAR16 Ch);
|
||||
|
||||
Reference in New Issue
Block a user