Allow debug option to be communicated at boot

This commit is contained in:
Justin C. Miller
2019-03-11 03:04:57 -07:00
parent 74a5c301f8
commit 870ca1db45
20 changed files with 128 additions and 68 deletions

View File

@@ -6,4 +6,6 @@ GUID(0x964e5b22,0x6459,0x11d2,0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b, guid_simp
GUID(0x09576e91,0x6d3f,0x11d2,0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b, guid_device_path);
GUID(0x8b843e20,0x8132,0x4852,0x90,0xcc,0x55,0x1a,0x4e,0x4a,0x7f,0x1c, guid_device_path_to_text);
GUID(0x10d0669c,0x9ec6,0x4268,0xbc,0x48,0xff,0x74,0x75,0x21,0xfe,0x07, guid_popcorn_vendor);
// vim: ft=c

View File

@@ -143,7 +143,7 @@ loader_load_elf(
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 %lu\r\n", header.entrypoint);
con_debug(L"ELF is valid, entrypoint %lx\r\n", header.entrypoint);
data->kernel_entry = (void *)header.entrypoint;

View File

@@ -5,7 +5,7 @@
#include "console.h"
#include "guids.h"
#include "kernel_data.h"
#include "kernel_args.h"
#include "loader.h"
#include "memory.h"
#include "utility.h"
@@ -34,7 +34,51 @@ struct kernel_header {
};
#pragma pack(pop)
using kernel_entry = void (*)(popcorn_data *);
using kernel_entry = void (*)(kernel_args *);
static void
type_to_wchar(wchar_t *into, uint32_t type)
{
for (int j=0; j<4; ++j)
into[j] = static_cast<wchar_t>(reinterpret_cast<char *>(&type)[j]);
}
EFI_STATUS
detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) {
wchar_t var_name[] = L"debug";
EFI_STATUS status;
uint8_t debug = 0;
UINTN var_size = sizeof(debug);
#ifdef __POPCORN_SET_DEBUG_UEFI_VAR__
debug = __POPCORN_SET_DEBUG_UEFI_VAR__;
uint32_t attrs =
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS;
status = run->SetVariable(
var_name,
&guid_popcorn_vendor,
attrs,
var_size,
&debug);
CHECK_EFI_STATUS_OR_RETURN(status, "detect_debug_mode::SetVariable");
#endif
status = run->GetVariable(
var_name,
&guid_popcorn_vendor,
nullptr,
&var_size,
&debug);
CHECK_EFI_STATUS_OR_RETURN(status, "detect_debug_mode::GetVariable");
if (debug)
header->flags |= POPCORN_FLAG_DEBUG;
return EFI_SUCCESS;
}
extern "C" EFI_STATUS
efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
@@ -73,14 +117,13 @@ 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(popcorn_data);
const size_t header_align = alignof(popcorn_data);
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");
@@ -111,12 +154,12 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
// Set up the kernel data pages to pass to the kernel
//
struct popcorn_data *data_header = (struct popcorn_data *)load.data;
struct kernel_args *data_header = (struct kernel_args *)load.data;
memory_mark_pointer_fixup((void **)&data_header);
data_header->magic = DATA_HEADER_MAGIC;
data_header->version = DATA_HEADER_VERSION;
data_header->length = sizeof(struct popcorn_data);
data_header->length = sizeof(struct kernel_args);
data_header->scratch_pages = SCRATCH_PAGES;
data_header->flags = 0;
@@ -168,6 +211,8 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
data_header->memory_map_length = map.length;
data_header->memory_map_desc_size = map.size;
detect_debug_mode(runsvc, data_header);
// bootsvc->Stall(5000000);
status = bootsvc->ExitBootServices(image_handle, map.key);

View File

@@ -7,8 +7,10 @@
#define DATA_HEADER_MAGIC 0x600dda7a
#define DATA_HEADER_VERSION 1
#define POPCORN_FLAG_DEBUG 0x00000001
#pragma pack(push, 1)
struct popcorn_data {
struct kernel_args {
uint32_t magic;
uint16_t version;
uint16_t length;

View File

@@ -18,9 +18,3 @@ __kernel_assert(const char *file, unsigned line, const char *message)
__asm__ ( "int $0e7h" );
while (1) __asm__ ("hlt");
}
extern "C" [[noreturn]] void
__assert_fail(const char *message, const char *file, unsigned int line, const char *function)
{
__kernel_assert(file, line, message);
}

View File

@@ -11,7 +11,7 @@
#include "gdt.h"
#include "interrupts.h"
#include "io.h"
#include "kernel_data.h"
#include "kernel_args.h"
#include "log.h"
#include "page_manager.h"
#include "scheduler.h"
@@ -20,7 +20,7 @@
#include "syscall.h"
extern "C" {
void kernel_main(popcorn_data *header);
void kernel_main(kernel_args *header);
void *__bss_start, *__bss_end;
}
@@ -39,28 +39,21 @@ init_console()
log::init(cons);
log::enable(logs::apic, log::level::info);
log::enable(logs::device, log::level::info);
log::enable(logs::device, log::level::debug);
log::enable(logs::paging, log::level::info);
log::enable(logs::driver, log::level::debug);
log::enable(logs::memory, log::level::debug);
log::enable(logs::fs, log::level::debug);
log::enable(logs::task, log::level::debug);
log::enable(logs::boot, log::level::debug);
log::enable(logs::paging, log::level::debug);
}
void
kernel_main(popcorn_data *header)
kernel_main(kernel_args *header)
{
#ifdef DEBUG
// Run `waf configure --debug` to enable compiling with DEBUG turned on.
// Then attach to QEMU's gdb server and `set waiting = false` to start
// the kernel. This compensates for GDB's poor handling of QEMU going
// through the x86 PC startup and switching to 64 bit mode when you
// attach to qemu with the -S option.
bool waiting = true;
bool waiting = header && (header->flags && POPCORN_FLAG_DEBUG);
while (waiting);
#endif
kutil::assert_set_callback(__kernel_assert);

View File

@@ -1,5 +1,3 @@
#include <algorithm>
#include "kutil/frame_allocator.h"
namespace kutil {
@@ -81,7 +79,7 @@ frame_allocator::allocate(size_t count, uintptr_t *address)
auto *first = m_free.front();
unsigned n = std::min(count, static_cast<size_t>(first->count));
unsigned n = count < first->count ? count : first->count;
*address = first->address;
if (count >= first->count) {