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:
56
boot_info.h
56
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 BootInfo struct is populated by the platform-specific loader
|
||||||
* the kernel entry point (kmain). It provides function pointers that
|
* (currently the UEFI loader in main.c) and passed to the kernel entry
|
||||||
* abstract UEFI Boot/Runtime Services so the kernel can use console I/O,
|
* point (kmain). It exposes only generic types and function pointers so
|
||||||
* memory allocation, and system control without linking against GNU-EFI.
|
* that the kernel remains independent of any particular firmware API.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BOOT_INFO_H
|
#ifndef BOOT_INFO_H
|
||||||
#define 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, ...);
|
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
|
* All function pointers are optional: the kernel must NULL-check before
|
||||||
* calling. If a service is unavailable the corresponding field is NULL.
|
* calling. If a service is unavailable the corresponding field is NULL.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
EFI_SYSTEM_TABLE *SystemTable; /* UEFI System Table */
|
|
||||||
|
|
||||||
/* Console I/O */
|
/* Console I/O */
|
||||||
KernelPrintFn print; /* formatted text output */
|
KernelPrintFn print; /* formatted text output */
|
||||||
EFI_STATUS (*clear_screen)(void); /* clear the console */
|
ConsoleClearFn clear_screen; /* clear the console */
|
||||||
EFI_STATUS (*set_attribute)(UINTN Attribute); /* set text colour/attr */
|
ConsoleSetAttrFn set_attribute; /* set text colour/attr */
|
||||||
EFI_STATUS (*read_key)(EFI_INPUT_KEY *Key); /* blocking key read */
|
KeyReadFn read_key; /* blocking key read */
|
||||||
EFI_STATUS (*try_read_key)(EFI_INPUT_KEY *Key); /* non-blocking key read */
|
KeyReadFn try_read_key; /* non-blocking key read */
|
||||||
|
|
||||||
/* System control */
|
/* System control */
|
||||||
void (*shutdown)(void); /* power-off the machine */
|
void (*shutdown)(void); /* power-off the machine */
|
||||||
|
|
||||||
/* Physical memory */
|
/* Physical memory */
|
||||||
EFI_STATUS (*alloc_pages)(UINTN pages, EFI_PHYSICAL_ADDRESS *addr);
|
KSTATUS (*alloc_pages)(UINTN pages, UINT64 *addr);
|
||||||
EFI_STATUS (*free_pages)(EFI_PHYSICAL_ADDRESS addr, UINTN pages);
|
KSTATUS (*free_pages)(UINT64 addr, UINTN pages);
|
||||||
|
|
||||||
|
/* Firmware metadata (for informational commands only). */
|
||||||
|
const CHAR16 *firmware_vendor;
|
||||||
|
UINT32 firmware_major;
|
||||||
|
UINT32 firmware_minor;
|
||||||
} BootInfo;
|
} BootInfo;
|
||||||
|
|
||||||
/* Kernel entry point signature (called by the UEFI loader). */
|
/* Kernel entry point signature (called by the loader). */
|
||||||
typedef void (*KernelEntryFn)(BootInfo *Boot);
|
typedef void (*KernelEntryFn)(BootInfo *Boot);
|
||||||
|
|
||||||
#endif /* BOOT_INFO_H */
|
#endif /* BOOT_INFO_H */
|
||||||
|
|||||||
21
commands.c
21
commands.c
@@ -11,7 +11,7 @@
|
|||||||
* 3. Append an entry to commands[] (before the sentinel)
|
* 3. Append an entry to commands[] (before the sentinel)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
@@ -112,10 +112,6 @@ static Command commands[] = {
|
|||||||
* System control
|
* 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)
|
static void request_shutdown(BootInfo *Boot)
|
||||||
{
|
{
|
||||||
if (Boot == NULL) {
|
if (Boot == NULL) {
|
||||||
@@ -127,14 +123,6 @@ static void request_shutdown(BootInfo *Boot)
|
|||||||
return;
|
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");
|
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)
|
static void cmd_clear(BootInfo *Boot, CHAR16 *Args)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
KSTATUS Status;
|
||||||
(void)Args;
|
(void)Args;
|
||||||
|
|
||||||
if (Boot != NULL && Boot->clear_screen != NULL) {
|
if (Boot != NULL && Boot->clear_screen != NULL) {
|
||||||
Status = Boot->clear_screen();
|
Status = Boot->clear_screen();
|
||||||
if (EFI_ERROR(Status)) {
|
if (Status != 0) {
|
||||||
SAFE_PRINT(Boot, L"Failed to clear screen: %r\n\r", Status);
|
SAFE_PRINT(Boot, L"Failed to clear screen (status=%ld)\n\r",
|
||||||
|
(UINT64)Status);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SAFE_PRINT(Boot, L"Clear screen function unavailable.\n\r");
|
SAFE_PRINT(Boot, L"Clear screen function unavailable.\n\r");
|
||||||
|
|||||||
2
idt.h
2
idt.h
@@ -8,7 +8,7 @@
|
|||||||
#ifndef IDT_H
|
#ifndef IDT_H
|
||||||
#define IDT_H
|
#define IDT_H
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
#include "boot_info.h"
|
#include "boot_info.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
69
kernel.c
69
kernel.c
@@ -1,17 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
* kernel.c – Kernel entry point and interactive shell loop.
|
* kernel.c – Kernel entry point and interactive shell loop.
|
||||||
*
|
*
|
||||||
* kmain() is called by the UEFI loader (main.c) after the ELF kernel
|
* kmain() is called by the loader (main.c) after the ELF kernel has been
|
||||||
* has been mapped into memory. It initialises subsystems (IDT, memory,
|
* mapped into memory. It initialises subsystems (IDT, memory, tasks),
|
||||||
* tasks), prints a welcome banner, and enters an interactive read-
|
* prints a welcome banner, and enters an interactive read-eval-print
|
||||||
* eval-print loop that dispatches typed commands via commands.c.
|
* loop that dispatches typed commands via commands.c.
|
||||||
*
|
*
|
||||||
* While waiting for keyboard input, the shell yields to the cooperative
|
* While waiting for keyboard input, the shell yields to the cooperative
|
||||||
* scheduler so that background tasks can make progress.
|
* scheduler so that background tasks can make progress.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
|
|
||||||
#include "boot_info.h"
|
#include "boot_info.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
@@ -26,14 +25,21 @@
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} 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
|
* Kernel entry point
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|
||||||
void kmain(BootInfo *Boot)
|
void kmain(BootInfo *Boot)
|
||||||
{
|
{
|
||||||
EFI_INPUT_KEY Key;
|
KeyEvent Key;
|
||||||
EFI_STATUS Status;
|
KSTATUS Status;
|
||||||
UINTN read_errors = 0;
|
UINTN read_errors = 0;
|
||||||
|
|
||||||
if (Boot == NULL) {
|
if (Boot == NULL) {
|
||||||
@@ -42,15 +48,17 @@ void kmain(BootInfo *Boot)
|
|||||||
|
|
||||||
if (Boot->clear_screen != NULL) {
|
if (Boot->clear_screen != NULL) {
|
||||||
Status = Boot->clear_screen();
|
Status = Boot->clear_screen();
|
||||||
if (EFI_ERROR(Status)) {
|
if (Status != 0) {
|
||||||
SAFE_PRINT(Boot, L"clear_screen failed: %r\n\r", Status);
|
SAFE_PRINT(Boot, L"clear_screen failed (status=%ld)\n\r",
|
||||||
|
(UINT64)Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Boot->set_attribute != NULL) {
|
if (Boot->set_attribute != NULL) {
|
||||||
Status = Boot->set_attribute(EFI_TEXT_ATTR(EFI_LIGHTGREEN, EFI_BLACK));
|
Status = Boot->set_attribute(TEXT_ATTR(COLOR_LIGHTGREEN, COLOR_BLACK));
|
||||||
if (EFI_ERROR(Status)) {
|
if (Status != 0) {
|
||||||
SAFE_PRINT(Boot, L"set_attribute failed: %r\n\r", Status);
|
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"\n\r");
|
SAFE_PRINT(Boot, L"\n\r");
|
||||||
SAFE_PRINT(Boot, L"System Information:\n\r");
|
SAFE_PRINT(Boot, L"System Information:\n\r");
|
||||||
if (Boot->SystemTable != NULL) {
|
if (Boot->firmware_vendor != NULL) {
|
||||||
SAFE_PRINT(Boot, L" UEFI Firmware Vendor: %s\n\r",
|
SAFE_PRINT(Boot, L" Firmware Vendor: %s\n\r", Boot->firmware_vendor);
|
||||||
Boot->SystemTable->FirmwareVendor);
|
SAFE_PRINT(Boot, L" Firmware Revision: %d.%d\n\r",
|
||||||
SAFE_PRINT(Boot, L" UEFI Firmware Revision: %d.%d\n\r",
|
Boot->firmware_major, Boot->firmware_minor);
|
||||||
Boot->SystemTable->FirmwareRevision >> 16,
|
|
||||||
Boot->SystemTable->FirmwareRevision & 0xFFFF);
|
|
||||||
} else {
|
} 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"\n\r");
|
||||||
|
|
||||||
SAFE_PRINT(Boot, L"Available Services:\n\r");
|
SAFE_PRINT(Boot, L"Available Services:\n\r");
|
||||||
SAFE_PRINT(Boot, L" - Console Input/Output: %s\n\r",
|
SAFE_PRINT(Boot, L" - Console Input/Output: %s\n\r",
|
||||||
(Boot->read_key != NULL && Boot->print != NULL) ? L"Active" : L"Unavailable");
|
(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"\n\r");
|
||||||
SAFE_PRINT(Boot, L"Type 'help' for a list of commands.\n\r\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 */
|
/* Try non-blocking read first; yield to other tasks while idle */
|
||||||
if (Boot->try_read_key != NULL) {
|
if (Boot->try_read_key != NULL) {
|
||||||
Status = Boot->try_read_key(&Key);
|
Status = Boot->try_read_key(&Key);
|
||||||
if (Status == EFI_NOT_READY) {
|
if (Status != 0) {
|
||||||
task_yield();
|
task_yield();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -108,16 +108,17 @@ void kmain(BootInfo *Boot)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR(Status)) {
|
if (Status != 0) {
|
||||||
read_errors++;
|
read_errors++;
|
||||||
if (read_errors == 1 || (read_errors % 64) == 0) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
read_errors = 0;
|
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 */
|
/* Enter pressed: execute the buffered command */
|
||||||
line[len] = L'\0';
|
line[len] = L'\0';
|
||||||
SAFE_PRINT(Boot, L"\n\r");
|
SAFE_PRINT(Boot, L"\n\r");
|
||||||
@@ -126,17 +127,17 @@ void kmain(BootInfo *Boot)
|
|||||||
/* Reset for next command */
|
/* Reset for next command */
|
||||||
len = 0;
|
len = 0;
|
||||||
SAFE_PRINT(Boot, L"-> ");
|
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 */
|
/* Backspace */
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
len--;
|
len--;
|
||||||
SAFE_PRINT(Boot, L"\b \b");
|
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 */
|
/* Printable ASCII */
|
||||||
if (len < (sizeof(line) / sizeof(line[0]) - 1)) {
|
if (len < (sizeof(line) / sizeof(line[0]) - 1)) {
|
||||||
line[len++] = Key.UnicodeChar;
|
line[len++] = Key.unicode_char;
|
||||||
SAFE_PRINT(Boot, L"%c", Key.UnicodeChar);
|
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 */
|
||||||
|
|
||||||
60
main.c
60
main.c
@@ -5,7 +5,7 @@
|
|||||||
* firmware via the PE32+ entry point. It:
|
* firmware via the PE32+ entry point. It:
|
||||||
* 1. Reads kernel.elf from the EFI System Partition
|
* 1. Reads kernel.elf from the EFI System Partition
|
||||||
* 2. Parses the ELF64 headers and maps PT_LOAD segments into memory
|
* 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)
|
* 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)
|
* 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;
|
UINTN Index = 0;
|
||||||
|
|
||||||
uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey, &Index);
|
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)
|
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);
|
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,
|
EFI_PHYSICAL_ADDRESS Phys = 0;
|
||||||
AllocateAnyPages, EfiLoaderData, pages, addr);
|
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,8 +323,7 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate the BootInfo struct with UEFI service wrappers */
|
/* Populate the BootInfo struct with generic UEFI-backed services */
|
||||||
Boot.SystemTable = ST;
|
|
||||||
Boot.print = Print;
|
Boot.print = Print;
|
||||||
Boot.clear_screen = loader_clear_screen;
|
Boot.clear_screen = loader_clear_screen;
|
||||||
Boot.set_attribute = loader_set_attribute;
|
Boot.set_attribute = loader_set_attribute;
|
||||||
@@ -307,6 +332,9 @@ efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
|||||||
Boot.shutdown = loader_shutdown;
|
Boot.shutdown = loader_shutdown;
|
||||||
Boot.alloc_pages = loader_alloc_pages;
|
Boot.alloc_pages = loader_alloc_pages;
|
||||||
Boot.free_pages = loader_free_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 */
|
/* Jump to the kernel – this should not return */
|
||||||
EntryFn = (KernelEntryFn)(UINTN)KernelEntry;
|
EntryFn = (KernelEntryFn)(UINTN)KernelEntry;
|
||||||
|
|||||||
12
memory.c
12
memory.c
@@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Implements three layers:
|
* Implements three layers:
|
||||||
* PMM – bitmap-based physical page-frame allocator backed by a
|
* 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
|
* Paging – walks and creates 4-level x86-64 page tables; supports
|
||||||
* map, unmap, and virtual-to-physical translation.
|
* map, unmap, and virtual-to-physical translation.
|
||||||
* Heap – first-fit free-list allocator with block splitting and
|
* 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)
|
void pmm_init(BootInfo *Boot)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
KSTATUS Status;
|
||||||
EFI_PHYSICAL_ADDRESS pool_addr = 0;
|
UINT64 pool_addr = 0;
|
||||||
UINTN i;
|
UINTN i;
|
||||||
|
|
||||||
/* Zero the bitmap – all pages start free */
|
/* 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);
|
Status = Boot->alloc_pages(PMM_POOL_PAGES, &pool_addr);
|
||||||
if (EFI_ERROR(Status)) {
|
if (Status != 0) {
|
||||||
SAFE_PRINT(Boot, L"PMM: failed to allocate pool (%d pages): %r\n\r",
|
SAFE_PRINT(Boot, L"PMM: failed to allocate pool (%d pages), status=%ld\n\r",
|
||||||
(UINTN)PMM_POOL_PAGES, Status);
|
(UINTN)PMM_POOL_PAGES, (UINT64)Status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
memory.h
2
memory.h
@@ -10,7 +10,7 @@
|
|||||||
#ifndef MEMORY_H
|
#ifndef MEMORY_H
|
||||||
#define MEMORY_H
|
#define MEMORY_H
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
#include "boot_info.h"
|
#include "boot_info.h"
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#ifndef STRING_UTILS_H
|
#ifndef STRING_UTILS_H
|
||||||
#define STRING_UTILS_H
|
#define STRING_UTILS_H
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
|
|
||||||
/* Return TRUE if Ch is a space or horizontal tab. */
|
/* Return TRUE if Ch is a space or horizontal tab. */
|
||||||
BOOLEAN is_space16(CHAR16 Ch);
|
BOOLEAN is_space16(CHAR16 Ch);
|
||||||
|
|||||||
2
task.h
2
task.h
@@ -9,7 +9,7 @@
|
|||||||
#ifndef TASK_H
|
#ifndef TASK_H
|
||||||
#define TASK_H
|
#define TASK_H
|
||||||
|
|
||||||
#include <efi.h>
|
#include "kernel_types.h"
|
||||||
#include "boot_info.h"
|
#include "boot_info.h"
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user