First step of moving bootloader to C++

This commit is contained in:
Justin C. Miller
2019-02-03 01:38:12 -08:00
parent a71af1be96
commit 579f6f64e6
15 changed files with 71 additions and 67 deletions

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env bash
build=${1:-"$(dirname $0)/build"}
ninja -C $build
kvm=""
if [[ -f /dev/kvm ]]; then
kvm="--enable-kvm"
fi
ninja -C $build && \
exec qemu-system-x86_64 \
-drive "if=pflash,format=raw,file=${build}/flash.img" \
-drive "format=raw,file=${build}/popcorn.img" \

View File

@@ -12,8 +12,8 @@ ccflags = $ccflags $
-DHAVE_USE_MS_ABI $
-DEFI_DEBUG=0 $
-DEFI_DEBUG_CLEAR_MEMORY=0 $
-fPIC $
-fshort-wchar
-DBOOTLOADER_DEBUG $
-fPIC
ldflags = $ldflags $
-T ${srcroot}/src/arch/x86_64/boot.ld $

View File

@@ -17,11 +17,11 @@ ccflags = $ccflags $
-fno-builtin $
-mno-sse $
-fno-omit-frame-pointer $
-mno-red-zone
-mno-red-zone $
-fshort-wchar
cxxflags = $cxxflags $
-nostdlibinc $
-isystem${srcroot}/sysroot/include/c++/v1 $
-fno-exceptions $
-fno-rtti

View File

@@ -11,7 +11,7 @@ size_t COLS = 0;
static EFI_SIMPLE_TEXT_OUT_PROTOCOL *con_out = 0;
const CHAR16 digits[] = {u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'};
const wchar_t digits[] = {u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'};
EFI_STATUS
con_pick_mode(EFI_BOOT_SERVICES *bootsvc)
@@ -54,7 +54,7 @@ con_pick_mode(EFI_BOOT_SERVICES *bootsvc)
}
EFI_STATUS
con_initialize(EFI_SYSTEM_TABLE *system_table, const CHAR16 *version)
con_initialize(EFI_SYSTEM_TABLE *system_table, const wchar_t *version)
{
EFI_STATUS status;
@@ -73,13 +73,13 @@ con_initialize(EFI_SYSTEM_TABLE *system_table, const CHAR16 *version)
CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen");
con_out->SetAttribute(con_out, EFI_LIGHTCYAN);
con_out->OutputString(con_out, (CHAR16 *)L"Popcorn loader ");
con_out->OutputString(con_out, (wchar_t *)L"Popcorn loader ");
con_out->SetAttribute(con_out, EFI_LIGHTMAGENTA);
con_out->OutputString(con_out, (CHAR16 *)version);
con_out->OutputString(con_out, (wchar_t *)version);
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L" booting...\r\n\n");
con_out->OutputString(con_out, (wchar_t *)L" booting...\r\n\n");
return status;
}
@@ -87,8 +87,8 @@ con_initialize(EFI_SYSTEM_TABLE *system_table, const CHAR16 *version)
size_t
con_print_hex(uint32_t n)
{
CHAR16 buffer[9];
CHAR16 *p = buffer;
wchar_t buffer[9];
wchar_t *p = buffer;
for (int i = 7; i >= 0; --i) {
uint8_t nibble = (n & (0xf << (i*4))) >> (i*4);
*p++ = digits[nibble];
@@ -101,8 +101,8 @@ con_print_hex(uint32_t n)
size_t
con_print_long_hex(uint64_t n)
{
CHAR16 buffer[17];
CHAR16 *p = buffer;
wchar_t buffer[17];
wchar_t *p = buffer;
for (int i = 15; i >= 0; --i) {
uint8_t nibble = (n & (0xf << (i*4))) >> (i*4);
*p++ = digits[nibble];
@@ -115,8 +115,8 @@ con_print_long_hex(uint64_t n)
size_t
con_print_dec(uint32_t n)
{
CHAR16 buffer[11];
CHAR16 *p = buffer + 10;
wchar_t buffer[11];
wchar_t *p = buffer + 10;
*p-- = 0;
do {
*p-- = digits[n % 10];
@@ -130,8 +130,8 @@ con_print_dec(uint32_t n)
size_t
con_print_long_dec(uint64_t n)
{
CHAR16 buffer[21];
CHAR16 *p = buffer + 20;
wchar_t buffer[21];
wchar_t *p = buffer + 20;
*p-- = 0;
do {
*p-- = digits[n % 10];
@@ -143,11 +143,11 @@ con_print_long_dec(uint64_t n)
}
size_t
con_printf(const CHAR16 *fmt, ...)
con_printf(const wchar_t *fmt, ...)
{
CHAR16 buffer[256];
const CHAR16 *r = fmt;
CHAR16 *w = buffer;
wchar_t buffer[256];
const wchar_t *r = fmt;
wchar_t *w = buffer;
va_list args;
size_t count = 0;
@@ -168,7 +168,7 @@ con_printf(const CHAR16 *fmt, ...)
switch (*r++) {
case L'%':
con_out->OutputString(con_out, L"%");
con_out->OutputString(con_out, const_cast<wchar_t*>(L"%"));
count++;
break;
@@ -183,7 +183,7 @@ con_printf(const CHAR16 *fmt, ...)
case L's':
{
CHAR16 *s = va_arg(args, CHAR16*);
wchar_t *s = va_arg(args, wchar_t*);
count += wstrlen(s);
con_out->OutputString(con_out, s);
}
@@ -218,37 +218,37 @@ con_printf(const CHAR16 *fmt, ...)
}
void
con_status_begin(const CHAR16 *message)
con_status_begin(const wchar_t *message)
{
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)message);
con_out->OutputString(con_out, (wchar_t *)message);
}
void
con_status_ok()
{
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L"[");
con_out->OutputString(con_out, (wchar_t *)L"[");
con_out->SetAttribute(con_out, EFI_GREEN);
con_out->OutputString(con_out, (CHAR16 *)L" ok ");
con_out->OutputString(con_out, (wchar_t *)L" ok ");
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L"]\r\n");
con_out->OutputString(con_out, (wchar_t *)L"]\r\n");
}
void
con_status_fail(const CHAR16 *error)
con_status_fail(const wchar_t *error)
{
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L"[");
con_out->OutputString(con_out, (wchar_t *)L"[");
con_out->SetAttribute(con_out, EFI_LIGHTRED);
con_out->OutputString(con_out, (CHAR16 *)L"failed");
con_out->OutputString(con_out, (wchar_t *)L"failed");
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L"]\r\n");
con_out->OutputString(con_out, (wchar_t *)L"]\r\n");
con_out->SetAttribute(con_out, EFI_RED);
con_out->OutputString(con_out, (CHAR16 *)error);
con_out->OutputString(con_out, (wchar_t *)error);
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
con_out->OutputString(con_out, (CHAR16 *)L"\r\n");
con_out->OutputString(con_out, (wchar_t *)L"\r\n");
}
EFI_STATUS

View File

@@ -2,11 +2,11 @@
#include <stddef.h>
#include <efi/efi.h>
EFI_STATUS con_initialize(EFI_SYSTEM_TABLE *system_table, const CHAR16 *version);
void con_status_begin(const CHAR16 *message);
EFI_STATUS con_initialize(EFI_SYSTEM_TABLE *system_table, const wchar_t *version);
void con_status_begin(const wchar_t *message);
void con_status_ok();
void con_status_fail(const CHAR16 *error);
size_t con_printf(const CHAR16 *fmt, ...);
void con_status_fail(const wchar_t *error);
size_t con_printf(const wchar_t *fmt, ...);
EFI_STATUS
con_get_framebuffer(

View File

@@ -6,8 +6,8 @@
#define PAGE_SIZE 0x1000
static CHAR16 kernel_name[] = KERNEL_FILENAME;
static CHAR16 initrd_name[] = INITRD_FILENAME;
static wchar_t kernel_name[] = KERNEL_FILENAME;
static wchar_t initrd_name[] = INITRD_FILENAME;
EFI_STATUS
loader_alloc_pages(
@@ -46,7 +46,7 @@ loader_load_initrd(
EFI_STATUS status;
EFI_FILE_PROTOCOL *file = NULL;
status = root->Open(root, &file, (CHAR16 *)initrd_name, EFI_FILE_MODE_READ,
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)
@@ -87,10 +87,10 @@ loader_load_elf(
{
EFI_STATUS status;
con_debug(L"Opening kernel file %s\r\n", (CHAR16 *)kernel_name);
con_debug(L"Opening kernel file %s\r\n", (wchar_t *)kernel_name);
EFI_FILE_PROTOCOL *file = NULL;
status = root->Open(root, &file, (CHAR16 *)kernel_name, EFI_FILE_MODE_READ,
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)

View File

@@ -13,15 +13,15 @@
#endif
#ifndef KERNEL_MEMTYPE
#define KERNEL_MEMTYPE 0x80000000
#define KERNEL_MEMTYPE static_cast<EFI_MEMORY_TYPE>(0x80000000)
#endif
#ifndef INITRD_MEMTYPE
#define INITRD_MEMTYPE 0x80000001
#define INITRD_MEMTYPE static_cast<EFI_MEMORY_TYPE>(0x80000001)
#endif
#ifndef KERNEL_DATA_MEMTYPE
#define KERNEL_DATA_MEMTYPE 0x80000002
#define KERNEL_DATA_MEMTYPE static_cast<EFI_MEMORY_TYPE>(0x80000002)
#endif
#ifndef KERNEL_FILENAME

View File

@@ -30,7 +30,9 @@ struct kernel_header {
};
#pragma pack(pop)
EFI_STATUS
using kernel_entry = void (*)(popcorn_data *);
extern "C" EFI_STATUS
efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
{
EFI_STATUS status;
@@ -65,8 +67,8 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
status = memory_get_map_length(bootsvc, &data_length);
CHECK_EFI_STATUS_OR_FAIL(status);
size_t header_size = sizeof(struct popcorn_data);
const size_t header_align = alignof(struct popcorn_data);
size_t header_size = sizeof(popcorn_data);
const size_t header_align = alignof(popcorn_data);
if (header_size % header_align)
header_size += header_align - (header_size % header_align);
@@ -97,7 +99,8 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
version->gitsha & 0xf0000000 ? "*" : "");
con_printf(L" Entrypoint 0x%x\r\n", load.kernel_entry);
void (*kernel_main)() = load.kernel_entry;
kernel_entry kernel_main =
reinterpret_cast<kernel_entry>(load.kernel_entry);
memory_mark_pointer_fixup((void **)&kernel_main);
// Set up the kernel data pages to pass to the kernel
@@ -148,8 +151,9 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
// Save the memory map and tell the firmware we're taking control.
//
struct memory_map map;
map.entries = data_header->memory_map;
map.length = (load.data_length - header_size);
map.entries =
reinterpret_cast<EFI_MEMORY_DESCRIPTOR *>(data_header->memory_map);
status = memory_get_map(bootsvc, &map);
CHECK_EFI_STATUS_OR_FAIL(status);

View File

@@ -10,7 +10,7 @@ size_t fixup_pointer_index = 0;
void **fixup_pointers[64];
uint64_t *new_pml4 = 0;
const CHAR16 *memory_type_names[] = {
const wchar_t *memory_type_names[] = {
L"EfiReservedMemoryType",
L"EfiLoaderCode",
L"EfiLoaderData",
@@ -28,10 +28,10 @@ const CHAR16 *memory_type_names[] = {
L"EfiPersistentMemory",
};
static const CHAR16 *
static const wchar_t *
memory_type_name(UINT32 value)
{
if (value >= (sizeof(memory_type_names) / sizeof(CHAR16 *))) {
if (value >= (sizeof(memory_type_names) / sizeof(wchar_t *))) {
if (value == KERNEL_DATA_MEMTYPE) return L"Kernel Data";
else if (value == KERNEL_MEMTYPE) return L"Kernel Image";
else return L"Bad Type Value";

View File

@@ -38,6 +38,7 @@
#include <efi/efi.h>
#include <elf.h>
extern "C"
EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
EFI_HANDLE image EFI_UNUSED,
EFI_SYSTEM_TABLE *systab EFI_UNUSED)

View File

@@ -2,7 +2,7 @@
struct error_code_desc {
EFI_STATUS code;
CHAR16 *name;
const wchar_t *name;
};
// Based off the gnu-efi table
@@ -47,7 +47,7 @@ struct error_code_desc error_table[] = {
{ 0, NULL }
};
const CHAR16 *
const wchar_t *
util_error_message(EFI_STATUS status)
{
int32_t i = -1;
@@ -62,7 +62,7 @@ util_error_message(EFI_STATUS status)
}
size_t
wstrlen(const CHAR16 *s)
wstrlen(const wchar_t *s)
{
size_t count = 0;
while (s && *s++) count++;

View File

@@ -5,8 +5,8 @@
#define UNUSED __attribute__((unused))
size_t wstrlen(const CHAR16 *s);
const CHAR16 *util_error_message(EFI_STATUS status);
size_t wstrlen(const wchar_t *s);
const wchar_t *util_error_message(EFI_STATUS status);
#define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \
if (EFI_ERROR((s))) { \

View File

@@ -20,9 +20,9 @@ Revision History
--*/
typedef UINT16 CHAR16;
typedef UINT8 CHAR8;
typedef UINT8 BOOLEAN;
typedef wchar_t CHAR16;
typedef char CHAR8;
typedef uint8_t BOOLEAN;
#ifndef CONST
#define CONST const
#endif

View File

@@ -38,12 +38,13 @@ init_console()
cons->puts(GIT_VERSION " booting...\n");
log::init(cons);
log::enable(logs::apic, log::level::debug);
log::enable(logs::device, log::level::info);
//log::enable(logs::apic, log::level::debug);
//log::enable(logs::device, log::level::info);
log::enable(logs::driver, log::level::debug);
log::enable(logs::memory, log::level::info);
log::enable(logs::fs, log::level::debug);
log::enable(logs::task, log::level::debug);
//log::enable(logs::boot, log::level::debug);
}
void
@@ -144,12 +145,10 @@ kernel_main(popcorn_data *header)
syscall_enable();
scheduler *sched = new (&scheduler::get()) scheduler(devices->get_lapic());
/*
for (auto &f : ird.files()) {
if (f.executable())
sched->create_process(f.name(), f.data(), f.size());
}
*/
sched->start();
}