diff --git a/src/boot/main.cpp b/src/boot/main.cpp index 79f9bbd..f3a4c4d 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -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(reinterpret_cast(&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(table->vendor_table); + + if (table->vendor_guid == uefi::vendor_guids::acpi1) { + // Mark a v1 table with the LSB high + acpi1_table = reinterpret_cast(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(table->vendor_table); - break; - } - - if (table->vendor_guid == uefi::vendor_guids::acpi1) { - // Mark a v1 table with the LSB high - acpi_table = reinterpret_cast(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(&args)), + L"Could not allocate argument memory"); + + kernel::args::module *modules = + reinterpret_cast(args + 1); + + args->magic = kernel::args::magic; + args->version = kernel::args::version; + args->runtime_services = rs; + args->acpi_table = reinterpret_cast(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; diff --git a/src/include/kernel_args.h b/src/include/kernel_args.h index 959b2b1..541288d 100644 --- a/src/include/kernel_args.h +++ b/src/include/kernel_args.h @@ -4,44 +4,59 @@ #include #include -#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 diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 574a41c..9fddd55 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -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(); + */ }