mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
Update kernel args to be module-based
- The old kernel_args structure is now mostly represented as a series of 'modules' or memory ranges, tagged with a type. An arbitrary number can be passed to the kernel - Update bootloader to allocate space for the args header and 10 module descriptors
This commit is contained in:
@@ -10,9 +10,10 @@
|
||||
#include "console.h"
|
||||
#include "error.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "kernel_args.h"
|
||||
/*
|
||||
#include "guids.h"
|
||||
#include "kernel_args.h"
|
||||
#include "loader.h"
|
||||
#include "utility.h"
|
||||
|
||||
@@ -40,14 +41,9 @@ using kernel_entry = void (*)(kernel_args *);
|
||||
|
||||
namespace boot {
|
||||
|
||||
constexpr int max_modules = 10; // Max modules to allocate room for
|
||||
|
||||
/*
|
||||
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) {
|
||||
@@ -87,6 +83,29 @@ detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) {
|
||||
}
|
||||
*/
|
||||
|
||||
uintptr_t
|
||||
find_acpi_table(uefi::system_table *st)
|
||||
{
|
||||
// Find ACPI tables. Ignore ACPI 1.0 if a 2.0 table is found.
|
||||
uintptr_t acpi1_table = 0;
|
||||
|
||||
for (size_t i = 0; i < st->number_of_table_entries; ++i) {
|
||||
uefi::configuration_table *table = &st->configuration_table[i];
|
||||
|
||||
// If we find an ACPI 2.0 table, return it immediately
|
||||
if (table->vendor_guid == uefi::vendor_guids::acpi2)
|
||||
return reinterpret_cast<uintptr_t>(table->vendor_table);
|
||||
|
||||
if (table->vendor_guid == uefi::vendor_guids::acpi1) {
|
||||
// Mark a v1 table with the LSB high
|
||||
acpi1_table = reinterpret_cast<uintptr_t>(table->vendor_table);
|
||||
acpi1_table |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return acpi1_table;
|
||||
}
|
||||
|
||||
uefi::status
|
||||
bootloader_main_uefi(uefi::system_table *st, console &con)
|
||||
{
|
||||
@@ -95,40 +114,12 @@ bootloader_main_uefi(uefi::system_table *st, console &con)
|
||||
uefi::boot_services *bs = st->boot_services;
|
||||
uefi::runtime_services *rs = st->runtime_services;
|
||||
|
||||
/*
|
||||
con.status_begin(L"Trying to do a harder thing...");
|
||||
con.status_warn(L"First warning");
|
||||
con.status_warn(L"Second warning");
|
||||
|
||||
con.status_begin(L"Trying to do the impossible...");
|
||||
con.status_warn(L"we're not going to make it");
|
||||
|
||||
error::raise(uefi::status::unsupported, L"OH NO");
|
||||
*/
|
||||
|
||||
con.status_begin(L"Initializing pointer fixup for virtualization");
|
||||
memory::init_pointer_fixup(bs, rs);
|
||||
con.status_end();
|
||||
|
||||
// Find ACPI tables. Ignore ACPI 1.0 if a 2.0 table is found.
|
||||
//
|
||||
con.status_begin(L"Searching for ACPI table");
|
||||
uintptr_t acpi_table = 0;
|
||||
for (size_t i = 0; i < st->number_of_table_entries; ++i) {
|
||||
uefi::configuration_table *table = &st->configuration_table[i];
|
||||
|
||||
if (table->vendor_guid == uefi::vendor_guids::acpi2) {
|
||||
acpi_table = reinterpret_cast<uintptr_t>(table->vendor_table);
|
||||
break;
|
||||
}
|
||||
|
||||
if (table->vendor_guid == uefi::vendor_guids::acpi1) {
|
||||
// Mark a v1 table with the LSB high
|
||||
acpi_table = reinterpret_cast<uintptr_t>(table->vendor_table);
|
||||
acpi_table |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
uintptr_t acpi_table = find_acpi_table(st);
|
||||
if (!acpi_table) {
|
||||
error::raise(uefi::status::not_found, L"Could not find ACPI table");
|
||||
} else if (acpi_table & 1) {
|
||||
@@ -136,11 +127,44 @@ bootloader_main_uefi(uefi::system_table *st, console &con)
|
||||
}
|
||||
con.status_end();
|
||||
|
||||
con.status_begin(L"Setting up kernel args memory");
|
||||
kernel::args::header *args = nullptr;
|
||||
|
||||
size_t args_size =
|
||||
sizeof(kernel::args::header) + // The header itself
|
||||
max_modules * sizeof(kernel::args::module); // The module structures
|
||||
|
||||
try_or_raise(
|
||||
bs->allocate_pool(
|
||||
uefi::memory_type::loader_data,
|
||||
args_size,
|
||||
reinterpret_cast<void**>(&args)),
|
||||
L"Could not allocate argument memory");
|
||||
|
||||
kernel::args::module *modules =
|
||||
reinterpret_cast<kernel::args::module*>(args + 1);
|
||||
|
||||
args->magic = kernel::args::magic;
|
||||
args->version = kernel::args::version;
|
||||
args->runtime_services = rs;
|
||||
args->acpi_table = reinterpret_cast<void*>(acpi_table);
|
||||
args->modules = modules;
|
||||
args->num_modules = 0;
|
||||
|
||||
con.status_end();
|
||||
|
||||
con.status_begin(L"Loading initrd into memory");
|
||||
kernel::args::module &initrd = modules[args->num_modules++];
|
||||
initrd.type = kernel::args::type::initrd;
|
||||
con.status_end();
|
||||
|
||||
|
||||
|
||||
while(1);
|
||||
return uefi::status::success;
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
// Compute necessary number of data pages
|
||||
//
|
||||
size_t data_length = 0;
|
||||
|
||||
@@ -4,44 +4,59 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DATA_HEADER_MAGIC 0x600dda7a
|
||||
#define DATA_HEADER_VERSION 1
|
||||
namespace kernel {
|
||||
namespace args {
|
||||
|
||||
#define JSIX_FLAG_DEBUG 0x00000001
|
||||
constexpr uint32_t magic = 0x600dda7a;
|
||||
constexpr uint16_t version = 1;
|
||||
|
||||
enum class flags : uint32_t
|
||||
{
|
||||
debug = 0x00000001
|
||||
};
|
||||
|
||||
enum class type : uint32_t {
|
||||
unknown,
|
||||
|
||||
kernel,
|
||||
initrd,
|
||||
|
||||
memory_map,
|
||||
framebuffer,
|
||||
|
||||
max
|
||||
};
|
||||
|
||||
enum class mode : uint8_t {
|
||||
normal,
|
||||
debug
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct kernel_args {
|
||||
struct module {
|
||||
void *location;
|
||||
size_t size;
|
||||
type type;
|
||||
flags flags;
|
||||
};
|
||||
|
||||
struct header {
|
||||
uint32_t magic;
|
||||
uint16_t version;
|
||||
uint16_t length;
|
||||
|
||||
uint16_t _reserved0;
|
||||
uint16_t scratch_pages;
|
||||
uint32_t flags;
|
||||
mode mode;
|
||||
|
||||
void *initrd;
|
||||
size_t initrd_length;
|
||||
uint8_t _reserved0;
|
||||
|
||||
void *data;
|
||||
size_t data_length;
|
||||
|
||||
void *memory_map;
|
||||
size_t memory_map_length;
|
||||
size_t memory_map_desc_size;
|
||||
|
||||
void *runtime;
|
||||
|
||||
void *acpi_table;
|
||||
|
||||
void *frame_buffer;
|
||||
size_t frame_buffer_length;
|
||||
uint32_t hres;
|
||||
uint32_t vres;
|
||||
uint32_t rmask;
|
||||
uint32_t gmask;
|
||||
uint32_t bmask;
|
||||
uint32_t _reserved1;
|
||||
uint32_t num_modules;
|
||||
module *modules;
|
||||
|
||||
void *runtime_services;
|
||||
void *acpi_table;
|
||||
}
|
||||
__attribute__((aligned(alignof(max_align_t))));
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace args
|
||||
} // namespace kernel
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "syscall.h"
|
||||
|
||||
extern "C" {
|
||||
void kernel_main(kernel_args *header);
|
||||
void kernel_main(kernel::args::header *header);
|
||||
void *__bss_start, *__bss_end;
|
||||
}
|
||||
|
||||
@@ -69,9 +69,9 @@ init_console()
|
||||
}
|
||||
|
||||
void
|
||||
kernel_main(kernel_args *header)
|
||||
kernel_main(kernel::args::header *header)
|
||||
{
|
||||
bool waiting = header && (header->flags && JSIX_FLAG_DEBUG);
|
||||
bool waiting = header && (header->mode == kernel::args::mode::debug);
|
||||
while (waiting);
|
||||
|
||||
kutil::assert_set_callback(__kernel_assert);
|
||||
@@ -79,6 +79,7 @@ kernel_main(kernel_args *header)
|
||||
gdt_init();
|
||||
interrupts_init();
|
||||
|
||||
/*
|
||||
memory_initialize(
|
||||
header->scratch_pages,
|
||||
header->memory_map,
|
||||
@@ -110,16 +111,19 @@ kernel_main(kernel_args *header)
|
||||
for (auto &f : ird.files())
|
||||
log::info(logs::boot, " %s%s (%d bytes).", f.executable() ? "*" : "", f.name(), f.size());
|
||||
|
||||
*/
|
||||
/*
|
||||
page_manager::get()->dump_pml4(nullptr, 0);
|
||||
page_manager::get()->dump_blocks(true);
|
||||
*/
|
||||
/*
|
||||
|
||||
device_manager *devices =
|
||||
new (&device_manager::get()) device_manager(header->acpi_table, heap);
|
||||
|
||||
interrupts_enable();
|
||||
|
||||
*/
|
||||
/*
|
||||
auto r = cpu.get(0x15);
|
||||
log::info(logs::boot, "CPU Crystal: %dHz", r.ecx);
|
||||
@@ -128,9 +132,11 @@ kernel_main(kernel_args *header)
|
||||
__asm__ __volatile__ ( "mov %%cr4, %0" : "=r" (cr4) );
|
||||
log::info(logs::boot, "cr4: %016x", cr4);
|
||||
*/
|
||||
/*
|
||||
|
||||
devices->init_drivers();
|
||||
|
||||
*/
|
||||
/*
|
||||
block_device *disk = devices->get_block_device(0);
|
||||
if (disk) {
|
||||
@@ -154,6 +160,7 @@ kernel_main(kernel_args *header)
|
||||
log::warn(logs::boot, "No block devices present.");
|
||||
}
|
||||
*/
|
||||
/*
|
||||
|
||||
devices->get_lapic()->calibrate_timer();
|
||||
|
||||
@@ -183,4 +190,5 @@ kernel_main(kernel_args *header)
|
||||
}
|
||||
|
||||
sched->start();
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user