extern "C" char interrupt_stack_top;
extern "C" os::paging::PML4T PML4T;
+os::paging::page bootstrap_pages_for_memory[32]; // 32 pages = 128 KiB
+
extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_start> info) {
os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2.");
os::assert(os::cpu_has_msr(), "MSRs aren't supported.");
}
}
- struct {
- std::uint64_t start_address = 0;
- std::uint64_t end_address = 0;
- } test_module;
+ os::paging::page_allocator.deallocate({
+ .ptr = os::phys_ptr<os::paging::page>(reinterpret_cast<uintptr_t>(bootstrap_pages_for_memory) - 0xFFFF'FFFF'8000'0000),
+ .size = sizeof(bootstrap_pages_for_memory) / sizeof(bootstrap_pages_for_memory[0])
+ });
+
+ // Allocate this page so that I only ever need to update the mapping once when I create a new process or port.
+ {
+ const auto index = os::paging::calc_page_table_indices((void*)0xFFFF'C000'0000'0000).pml4e;
+ PML4T.contents[index] = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
+ const auto PDPT_alloc = os::paging::page_allocator.allocate(1);
+ set_base_address(PML4T.contents[index], os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr()));
+ }
+
+ os::process test_module_process = { nullptr, 0, 0 };
{
struct {
os::phys_ptr<os::paging::page> start_address = nullptr;
break;
case multiboot2::info::type_t::modules:
os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it) / 0x1000 * 0x1000, multiboot2::modules_mod_end(it) / 0x1000 * 0x1000, multiboot2::modules_string(it));
- test_module.start_address = multiboot2::modules_mod_start(it);
- test_module.end_address = multiboot2::modules_mod_end(it);
+ os::assert(test_module_process.PML4T == nullptr, "Multiple modules specified in the multiboot. This is unsupported.");
+ test_module_process =
+ os::elf::load_elf(&*os::phys_ptr<std::byte>(multiboot2::modules_mod_start(it)),
+ multiboot2::modules_mod_end(it) - multiboot2::modules_mod_start(it),
+ PML4T);
break;
default: break;
}
}
+ os::assert(test_module_process.PML4T != nullptr, "No modules specified in the multiboot. This is unsupported.");
+
// kernel_start and kernel_end are aligned to 4K by the linker script.
const os::phys_ptr<os::paging::page> kernel_s = ([]() {
os::phys_ptr<os::paging::page> ptr = nullptr;
available_ram_length++;
}
}
- struct {
- os::phys_ptr<os::paging::page> start_address;
- os::phys_ptr<os::paging::page> end_address;
- } test_module_block{
- os::phys_ptr<os::paging::page>(test_module.start_address / 0x1000 * 0x1000),
- os::phys_ptr<os::paging::page>(test_module.end_address / 0x1000 * 0x1000)
- };
- // Remove module from available RAM:
- for (std::size_t i = 0; i < available_ram_length; i++) {
- if (test_module_block.end_address < available_ram[i].start_address || available_ram[i].end_address < test_module_block.start_address) {
- continue;
- }
- if (test_module_block.start_address <= available_ram[i].start_address && available_ram[i].end_address <= test_module_block.end_address) {
- available_ram[i] = available_ram[--available_ram_length];
- i--;
- } else if (test_module_block.start_address <= available_ram[i].start_address) {
- available_ram[i].start_address = test_module_block.end_address + 1; // Since e < end_address, new start_address <= end_address.
- } else if (available_ram[i].end_address <= test_module_block.end_address) {
- available_ram[i].end_address = test_module_block.start_address - 1; // Since start_address < s, start_address <= new end_address.
- } else {
- os::assert(available_ram_length < 50, "Too much available RAM sections to initialise correctly. Will fix eventually, probably.");
- available_ram[available_ram_length] = available_ram[i];
- available_ram[i].end_address = test_module_block.start_address - 1;
- available_ram[available_ram_length].start_address = test_module_block.end_address + 1;
- available_ram_length++;
- }
- }
- // Add available RAM to the page allocator (warning: overrides the multiboot info structure):
+ // Add available RAM to the page allocator (warning: overrides the multiboot info structure and the multiboot modules):
for (std::size_t i = 0; i < available_ram_length; i++) {
os::paging::page_allocator.deallocate({
.ptr = available_ram[i].start_address,
os::paging::page_allocator.deallocate({.ptr = os::phys_ptr<os::paging::page>(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1});
os::invlpg((void*)0x0);
- // Allocate this page so that I only ever need to update the mapping once when I create a new process or port.
- {
- const auto index = os::paging::calc_page_table_indices((void*)0xFFFF'C000'0000'0000).pml4e;
- PML4T.contents[index] = {.P = 1, .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
- const auto PDPT_alloc = os::paging::page_allocator.allocate(1);
- set_base_address(PML4T.contents[index], os::phys_ptr<os::paging::PDPT>(PDPT_alloc.ptr.get_phys_addr()));
- }
-
- auto test_module_process =
- os::elf::load_elf(&*os::phys_ptr<std::byte>(test_module.start_address), test_module.end_address - test_module.start_address, PML4T);
-
os::print("Loading ring 3 interrupts stack.\n");
os::set_ring0_stack(TSS, std::uint64_t(&interrupt_stack_top));
os::print("Loading TSS.\n");