mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 00:14:32 -08:00
Turning console into a class
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
@@ -9,16 +8,55 @@
|
|||||||
size_t ROWS = 0;
|
size_t ROWS = 0;
|
||||||
size_t COLS = 0;
|
size_t COLS = 0;
|
||||||
|
|
||||||
static EFI_SIMPLE_TEXT_OUT_PROTOCOL *con_out = 0;
|
static EFI_SIMPLE_TEXT_OUT_PROTOCOL *m_out = 0;
|
||||||
|
|
||||||
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'};
|
static 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'};
|
||||||
|
|
||||||
|
console::console(EFI_SYSTEM_TABLE *system_table) :
|
||||||
|
m_rows(0),
|
||||||
|
m_cols(0),
|
||||||
|
m_out(nullptr)
|
||||||
|
{
|
||||||
|
s_console = this;
|
||||||
|
m_boot = system_table->BootServices;
|
||||||
|
m_out = system_table->ConOut;
|
||||||
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
con_pick_mode(EFI_BOOT_SERVICES *bootsvc)
|
console::initialize(const wchar_t *version)
|
||||||
|
{
|
||||||
|
EFI_STATUS status;
|
||||||
|
|
||||||
|
// Might not find a video device at all, so ignore not found errors
|
||||||
|
status = pick_mode();
|
||||||
|
if (status != EFI_NOT_FOUND)
|
||||||
|
CHECK_EFI_STATUS_OR_FAIL(status);
|
||||||
|
|
||||||
|
status = m_out->QueryMode(m_out, m_out->Mode->Mode, &m_cols, &m_rows);
|
||||||
|
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
|
||||||
|
|
||||||
|
status = m_out->ClearScreen(m_out);
|
||||||
|
CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen");
|
||||||
|
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTCYAN);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L"Popcorn loader ");
|
||||||
|
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTMAGENTA);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)version);
|
||||||
|
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L" booting...\r\n\n");
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
console::pick_mode()
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto;
|
||||||
status = bootsvc->LocateProtocol(&guid_gfx_out, NULL, (void **)&gfx_out_proto);
|
status = m_boot->LocateProtocol(&guid_gfx_out, NULL, (void **)&gfx_out_proto);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
|
CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx");
|
||||||
|
|
||||||
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
|
const uint32_t modes = gfx_out_proto->Mode->MaxMode;
|
||||||
@@ -53,39 +91,8 @@ con_pick_mode(EFI_BOOT_SERVICES *bootsvc)
|
|||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
|
||||||
con_initialize(EFI_SYSTEM_TABLE *system_table, const wchar_t *version)
|
|
||||||
{
|
|
||||||
EFI_STATUS status;
|
|
||||||
|
|
||||||
EFI_BOOT_SERVICES *bootsvc = system_table->BootServices;
|
|
||||||
con_out = system_table->ConOut;
|
|
||||||
|
|
||||||
// Might not find a video device at all, so ignore not found errors
|
|
||||||
status = con_pick_mode(bootsvc);
|
|
||||||
if (status != EFI_NOT_FOUND)
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, "con_pick_mode");
|
|
||||||
|
|
||||||
status = con_out->QueryMode(con_out, con_out->Mode->Mode, &COLS, &ROWS);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode");
|
|
||||||
|
|
||||||
status = con_out->ClearScreen(con_out);
|
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen");
|
|
||||||
|
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTCYAN);
|
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"Popcorn loader ");
|
|
||||||
|
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTMAGENTA);
|
|
||||||
con_out->OutputString(con_out, (wchar_t *)version);
|
|
||||||
|
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
|
||||||
con_out->OutputString(con_out, (wchar_t *)L" booting...\r\n\n");
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
con_print_hex(uint32_t n)
|
console::print_hex(uint32_t n) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[9];
|
wchar_t buffer[9];
|
||||||
wchar_t *p = buffer;
|
wchar_t *p = buffer;
|
||||||
@@ -94,12 +101,12 @@ con_print_hex(uint32_t n)
|
|||||||
*p++ = digits[nibble];
|
*p++ = digits[nibble];
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
con_out->OutputString(con_out, buffer);
|
m_out->OutputString(m_out, buffer);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
con_print_long_hex(uint64_t n)
|
console::print_long_hex(uint64_t n) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[17];
|
wchar_t buffer[17];
|
||||||
wchar_t *p = buffer;
|
wchar_t *p = buffer;
|
||||||
@@ -108,12 +115,12 @@ con_print_long_hex(uint64_t n)
|
|||||||
*p++ = digits[nibble];
|
*p++ = digits[nibble];
|
||||||
}
|
}
|
||||||
*p = 0;
|
*p = 0;
|
||||||
con_out->OutputString(con_out, buffer);
|
m_out->OutputString(m_out, buffer);
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
con_print_dec(uint32_t n)
|
console::print_dec(uint32_t n) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[11];
|
wchar_t buffer[11];
|
||||||
wchar_t *p = buffer + 10;
|
wchar_t *p = buffer + 10;
|
||||||
@@ -123,12 +130,12 @@ con_print_dec(uint32_t n)
|
|||||||
n /= 10;
|
n /= 10;
|
||||||
} while (n != 0);
|
} while (n != 0);
|
||||||
|
|
||||||
con_out->OutputString(con_out, ++p);
|
m_out->OutputString(m_out, ++p);
|
||||||
return 10 - (p - buffer);
|
return 10 - (p - buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
con_print_long_dec(uint64_t n)
|
console::print_long_dec(uint64_t n) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[21];
|
wchar_t buffer[21];
|
||||||
wchar_t *p = buffer + 20;
|
wchar_t *p = buffer + 20;
|
||||||
@@ -138,21 +145,18 @@ con_print_long_dec(uint64_t n)
|
|||||||
n /= 10;
|
n /= 10;
|
||||||
} while (n != 0);
|
} while (n != 0);
|
||||||
|
|
||||||
con_out->OutputString(con_out, ++p);
|
m_out->OutputString(m_out, ++p);
|
||||||
return 20 - (p - buffer);
|
return 20 - (p - buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
con_printf(const wchar_t *fmt, ...)
|
console::vprintf(const wchar_t *fmt, va_list args) const
|
||||||
{
|
{
|
||||||
wchar_t buffer[256];
|
wchar_t buffer[256];
|
||||||
const wchar_t *r = fmt;
|
const wchar_t *r = fmt;
|
||||||
wchar_t *w = buffer;
|
wchar_t *w = buffer;
|
||||||
va_list args;
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
|
|
||||||
while (r && *r) {
|
while (r && *r) {
|
||||||
if (*r != L'%') {
|
if (*r != L'%') {
|
||||||
count++;
|
count++;
|
||||||
@@ -161,43 +165,43 @@ con_printf(const wchar_t *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*w = 0;
|
*w = 0;
|
||||||
con_out->OutputString(con_out, buffer);
|
m_out->OutputString(m_out, buffer);
|
||||||
w = buffer;
|
w = buffer;
|
||||||
|
|
||||||
r++; // chomp the %
|
r++; // chomp the %
|
||||||
|
|
||||||
switch (*r++) {
|
switch (*r++) {
|
||||||
case L'%':
|
case L'%':
|
||||||
con_out->OutputString(con_out, const_cast<wchar_t*>(L"%"));
|
m_out->OutputString(m_out, const_cast<wchar_t*>(L"%"));
|
||||||
count++;
|
count++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L'x':
|
case L'x':
|
||||||
count += con_print_hex(va_arg(args, uint32_t));
|
count += print_hex(va_arg(args, uint32_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L'd':
|
case L'd':
|
||||||
case L'u':
|
case L'u':
|
||||||
count += con_print_dec(va_arg(args, uint32_t));
|
count += print_dec(va_arg(args, uint32_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L's':
|
case L's':
|
||||||
{
|
{
|
||||||
wchar_t *s = va_arg(args, wchar_t*);
|
wchar_t *s = va_arg(args, wchar_t*);
|
||||||
count += wstrlen(s);
|
count += wstrlen(s);
|
||||||
con_out->OutputString(con_out, s);
|
m_out->OutputString(m_out, s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L'l':
|
case L'l':
|
||||||
switch (*r++) {
|
switch (*r++) {
|
||||||
case L'x':
|
case L'x':
|
||||||
count += con_print_long_hex(va_arg(args, uint64_t));
|
count += print_long_hex(va_arg(args, uint64_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L'd':
|
case L'd':
|
||||||
case L'u':
|
case L'u':
|
||||||
count += con_print_long_dec(va_arg(args, uint64_t));
|
count += print_long_dec(va_arg(args, uint64_t));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -211,44 +215,66 @@ con_printf(const wchar_t *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*w = 0;
|
*w = 0;
|
||||||
con_out->OutputString(con_out, buffer);
|
m_out->OutputString(m_out, buffer);
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
size_t
|
||||||
con_status_begin(const wchar_t *message)
|
console::printf(const wchar_t *fmt, ...) const
|
||||||
{
|
{
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
va_list args;
|
||||||
con_out->OutputString(con_out, (wchar_t *)message);
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
size_t result = vprintf(fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
console::print(const wchar_t *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
size_t result = get().vprintf(fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
con_status_ok()
|
console::status_begin(const wchar_t *message) const
|
||||||
{
|
{
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"[");
|
m_out->OutputString(m_out, (wchar_t *)message);
|
||||||
con_out->SetAttribute(con_out, EFI_GREEN);
|
|
||||||
con_out->OutputString(con_out, (wchar_t *)L" ok ");
|
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"]\r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
con_status_fail(const wchar_t *error)
|
console::status_ok() const
|
||||||
{
|
{
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"[");
|
m_out->OutputString(m_out, (wchar_t *)L"[");
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTRED);
|
m_out->SetAttribute(m_out, EFI_GREEN);
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"failed");
|
m_out->OutputString(m_out, (wchar_t *)L" ok ");
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"]\r\n");
|
m_out->OutputString(m_out, (wchar_t *)L"]\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
con_out->SetAttribute(con_out, EFI_RED);
|
void
|
||||||
con_out->OutputString(con_out, (wchar_t *)error);
|
console::status_fail(const wchar_t *error) const
|
||||||
con_out->SetAttribute(con_out, EFI_LIGHTGRAY);
|
{
|
||||||
con_out->OutputString(con_out, (wchar_t *)L"\r\n");
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L"[");
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTRED);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L"failed");
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L"]\r\n");
|
||||||
|
|
||||||
|
m_out->SetAttribute(m_out, EFI_RED);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)error);
|
||||||
|
m_out->SetAttribute(m_out, EFI_LIGHTGRAY);
|
||||||
|
m_out->OutputString(m_out, (wchar_t *)L"\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
|
|||||||
@@ -1,12 +1,38 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <efi/efi.h>
|
#include <efi/efi.h>
|
||||||
|
|
||||||
EFI_STATUS con_initialize(EFI_SYSTEM_TABLE *system_table, const wchar_t *version);
|
class console
|
||||||
void con_status_begin(const wchar_t *message);
|
{
|
||||||
void con_status_ok();
|
public:
|
||||||
void con_status_fail(const wchar_t *error);
|
console(EFI_SYSTEM_TABLE *system_table);
|
||||||
size_t con_printf(const wchar_t *fmt, ...);
|
|
||||||
|
EFI_STATUS initialize(const wchar_t *version);
|
||||||
|
|
||||||
|
void status_begin(const wchar_t *message) const;
|
||||||
|
void status_fail(const wchar_t *error) const;
|
||||||
|
void status_ok() const;
|
||||||
|
|
||||||
|
size_t print_hex(uint32_t n) const;
|
||||||
|
size_t print_dec(uint32_t n) const;
|
||||||
|
size_t print_long_hex(uint64_t n) const;
|
||||||
|
size_t print_long_dec(uint64_t n) const;
|
||||||
|
size_t printf(const wchar_t *fmt, ...) const;
|
||||||
|
|
||||||
|
static const console & get() { return *s_console; }
|
||||||
|
static size_t print(const wchar_t *fmt, ...);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EFI_STATUS pick_mode();
|
||||||
|
size_t vprintf(const wchar_t *fmt, va_list args) const;
|
||||||
|
|
||||||
|
size_t m_rows, m_cols;
|
||||||
|
EFI_BOOT_SERVICES *m_boot;
|
||||||
|
EFI_SIMPLE_TEXT_OUT_PROTOCOL *m_out;
|
||||||
|
|
||||||
|
static console *s_console;
|
||||||
|
};
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
con_get_framebuffer(
|
con_get_framebuffer(
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ loader_load_elf(
|
|||||||
|
|
||||||
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) {
|
||||||
con_debug(L"Reading ELF program header %d\r\n", i);
|
|
||||||
|
|
||||||
status = file->SetPosition(file, header.ph_offset + i * header.ph_entsize);
|
status = file->SetPosition(file, header.ph_offset + i * header.ph_entsize);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
||||||
@@ -161,11 +160,10 @@ loader_load_elf(
|
|||||||
data->kernel = addr;
|
data->kernel = addr;
|
||||||
data->kernel_length = (uint64_t)addr + length - (uint64_t)data->kernel;
|
data->kernel_length = (uint64_t)addr + length - (uint64_t)data->kernel;
|
||||||
}
|
}
|
||||||
|
con_debug(L"Read %d ELF program headers\r\n", header.ph_num);
|
||||||
|
|
||||||
struct elf_section_header sec_header;
|
struct elf_section_header sec_header;
|
||||||
for (int i = 0; i < header.sh_num; ++i) {
|
for (int i = 0; i < header.sh_num; ++i) {
|
||||||
con_debug(L"Reading ELF section header %d ", i);
|
|
||||||
|
|
||||||
status = file->SetPosition(file, header.sh_offset + i * header.sh_entsize);
|
status = file->SetPosition(file, header.sh_offset + i * header.sh_entsize);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
||||||
|
|
||||||
@@ -174,14 +172,12 @@ loader_load_elf(
|
|||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading ELF section header");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading ELF section header");
|
||||||
|
|
||||||
if ((sec_header.flags & ELF_SHF_ALLOC) == 0) {
|
if ((sec_header.flags & ELF_SHF_ALLOC) == 0) {
|
||||||
con_debug(L"SHF_ALLOC section\r\n");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *addr = (void *)(sec_header.addr - KERNEL_VIRT_ADDRESS);
|
void *addr = (void *)(sec_header.addr - KERNEL_VIRT_ADDRESS);
|
||||||
|
|
||||||
if (sec_header.type == ELF_ST_PROGBITS) {
|
if (sec_header.type == ELF_ST_PROGBITS) {
|
||||||
con_debug(L"PROGBITS section\r\n");
|
|
||||||
status = file->SetPosition(file, sec_header.offset);
|
status = file->SetPosition(file, sec_header.offset);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Setting ELF file position");
|
||||||
|
|
||||||
@@ -189,12 +185,10 @@ loader_load_elf(
|
|||||||
status = file->Read(file, &length, addr);
|
status = file->Read(file, &length, addr);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading file");
|
CHECK_EFI_STATUS_OR_RETURN(status, L"Reading file");
|
||||||
} else if (sec_header.type == ELF_ST_NOBITS) {
|
} else if (sec_header.type == ELF_ST_NOBITS) {
|
||||||
con_debug(L"NOBITS section\r\n");
|
|
||||||
bootsvc->SetMem(addr, sec_header.size, 0);
|
bootsvc->SetMem(addr, sec_header.size, 0);
|
||||||
} else {
|
|
||||||
con_debug(L"other section\r\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
con_debug(L"Read %d ELF section headers\r\n", header.ph_num);
|
||||||
|
|
||||||
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");
|
||||||
|
|||||||
@@ -39,10 +39,12 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
|
|||||||
EFI_BOOT_SERVICES *bootsvc = system_table->BootServices;
|
EFI_BOOT_SERVICES *bootsvc = system_table->BootServices;
|
||||||
EFI_RUNTIME_SERVICES *runsvc = system_table->RuntimeServices;
|
EFI_RUNTIME_SERVICES *runsvc = system_table->RuntimeServices;
|
||||||
|
|
||||||
|
console con(system_table);
|
||||||
|
|
||||||
// When checking console initialization, use CHECK_EFI_STATUS_OR_RETURN
|
// When checking console initialization, use CHECK_EFI_STATUS_OR_RETURN
|
||||||
// because we can't be sure if the console was fully set up
|
// because we can't be sure if the console was fully set up
|
||||||
status = con_initialize(system_table, GIT_VERSION_WIDE);
|
status = con.initialize(GIT_VERSION_WIDE);
|
||||||
CHECK_EFI_STATUS_OR_RETURN(status, "con_initialize");
|
CHECK_EFI_STATUS_OR_RETURN(status, "console::initialize");
|
||||||
// From here on out, we can use CHECK_EFI_STATUS_OR_FAIL instead
|
// From here on out, we can use CHECK_EFI_STATUS_OR_FAIL instead
|
||||||
|
|
||||||
memory_init_pointer_fixup(bootsvc, runsvc);
|
memory_init_pointer_fixup(bootsvc, runsvc);
|
||||||
@@ -77,27 +79,27 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
|
|||||||
|
|
||||||
// Load the kernel image from disk and check it
|
// Load the kernel image from disk and check it
|
||||||
//
|
//
|
||||||
con_printf(L"Loading kernel into memory...\r\n");
|
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;
|
||||||
status = loader_load_kernel(bootsvc, &load);
|
status = loader_load_kernel(bootsvc, &load);
|
||||||
CHECK_EFI_STATUS_OR_FAIL(status);
|
CHECK_EFI_STATUS_OR_FAIL(status);
|
||||||
|
|
||||||
con_printf(L" %u image bytes at 0x%x\r\n", load.kernel_length, load.kernel);
|
console::print(L" %u image bytes at 0x%x\r\n", load.kernel_length, load.kernel);
|
||||||
con_printf(L" %u initrd bytes at 0x%x\r\n", load.initrd_length, load.initrd);
|
console::print(L" %u initrd bytes at 0x%x\r\n", load.initrd_length, load.initrd);
|
||||||
con_printf(L" %u data bytes at 0x%x\r\n", load.data_length, load.data);
|
console::print(L" %u data bytes at 0x%x\r\n", load.data_length, load.data);
|
||||||
|
|
||||||
struct kernel_header *version = (struct kernel_header *)load.kernel;
|
struct kernel_header *version = (struct kernel_header *)load.kernel;
|
||||||
if (version->magic != KERNEL_HEADER_MAGIC) {
|
if (version->magic != KERNEL_HEADER_MAGIC) {
|
||||||
con_printf(L" bad magic %x\r\n", version->magic);
|
console::print(L" bad magic %x\r\n", version->magic);
|
||||||
CHECK_EFI_STATUS_OR_FAIL(EFI_CRC_ERROR);
|
CHECK_EFI_STATUS_OR_FAIL(EFI_CRC_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
con_printf(L" Kernel version %d.%d.%d %x%s\r\n",
|
console::print(L" Kernel version %d.%d.%d %x%s\r\n",
|
||||||
version->major, version->minor, version->patch, version->gitsha & 0x0fffffff,
|
version->major, version->minor, version->patch, version->gitsha & 0x0fffffff,
|
||||||
version->gitsha & 0xf0000000 ? "*" : "");
|
version->gitsha & 0xf0000000 ? "*" : "");
|
||||||
con_printf(L" Entrypoint 0x%x\r\n", load.kernel_entry);
|
console::print(L" Entrypoint 0x%x\r\n", load.kernel_entry);
|
||||||
|
|
||||||
kernel_entry kernel_main =
|
kernel_entry kernel_main =
|
||||||
reinterpret_cast<kernel_entry>(load.kernel_entry);
|
reinterpret_cast<kernel_entry>(load.kernel_entry);
|
||||||
|
|||||||
@@ -139,19 +139,19 @@ memory_dump_map(struct memory_map *map)
|
|||||||
|
|
||||||
const size_t count = map->length / map->size;
|
const size_t count = map->length / map->size;
|
||||||
|
|
||||||
con_printf(L"Memory map:\n");
|
console::print(L"Memory map:\n");
|
||||||
con_printf(L"\t Descriptor Count: %d (%d bytes)\n", count, map->length);
|
console::print(L"\t Descriptor Count: %d (%d bytes)\n", count, map->length);
|
||||||
con_printf(L"\t Descriptor Size: %d bytes\n", map->size);
|
console::print(L"\t Descriptor Size: %d bytes\n", map->size);
|
||||||
con_printf(L"\t Type offset: %d\n\n", offsetof(EFI_MEMORY_DESCRIPTOR, Type));
|
console::print(L"\t Type offset: %d\n\n", offsetof(EFI_MEMORY_DESCRIPTOR, Type));
|
||||||
|
|
||||||
EFI_MEMORY_DESCRIPTOR *end = INCREMENT_DESC(map->entries, map->length);
|
EFI_MEMORY_DESCRIPTOR *end = INCREMENT_DESC(map->entries, map->length);
|
||||||
EFI_MEMORY_DESCRIPTOR *d = map->entries;
|
EFI_MEMORY_DESCRIPTOR *d = map->entries;
|
||||||
while (d < end) {
|
while (d < end) {
|
||||||
int runtime = (d->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME;
|
int runtime = (d->Attribute & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME;
|
||||||
con_printf(L"%s%s ", memory_type_name(d->Type), runtime ? L"*" : L" ");
|
console::print(L"%s%s ", memory_type_name(d->Type), runtime ? L"*" : L" ");
|
||||||
con_printf(L"%lx ", d->PhysicalStart);
|
console::print(L"%lx ", d->PhysicalStart);
|
||||||
con_printf(L"%lx ", d->VirtualStart);
|
console::print(L"%lx ", d->VirtualStart);
|
||||||
con_printf(L"[%4d]\n", d->NumberOfPages);
|
console::print(L"[%4d]\n", d->NumberOfPages);
|
||||||
|
|
||||||
d = INCREMENT_DESC(d, map->size);
|
d = INCREMENT_DESC(d, map->size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ const wchar_t *util_error_message(EFI_STATUS status);
|
|||||||
|
|
||||||
#define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \
|
#define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \
|
||||||
if (EFI_ERROR((s))) { \
|
if (EFI_ERROR((s))) { \
|
||||||
con_printf(L"ERROR: " msg L": %s\r\n", ##__VA_ARGS__, util_error_message(s)); \
|
console::print(L"ERROR: " msg L": %s\r\n", ##__VA_ARGS__, util_error_message(s)); \
|
||||||
return (s); \
|
return (s); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_EFI_STATUS_OR_FAIL(s) \
|
#define CHECK_EFI_STATUS_OR_FAIL(s) \
|
||||||
if (EFI_ERROR((s))) { \
|
if (EFI_ERROR((s))) { \
|
||||||
con_status_fail(util_error_message(s)); \
|
console::get().status_fail(util_error_message(s)); \
|
||||||
while (1) __asm__("hlt"); \
|
while (1) __asm__("hlt"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ const wchar_t *util_error_message(EFI_STATUS status);
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOTLOADER_DEBUG
|
#ifdef BOOTLOADER_DEBUG
|
||||||
#define con_debug(...) con_printf(L"DEBUG: " __VA_ARGS__)
|
#define con_debug(...) console::print(L"DEBUG: " __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define con_debug(...)
|
#define con_debug(...)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user