}
}
+ struct {
+ os::phys_ptr<os::paging::page> start_address = nullptr;
+ os::phys_ptr<os::paging::page> end_address = nullptr;
+ } test_module;
{
struct {
os::phys_ptr<os::paging::page> start_address = nullptr;
}
}
break;
+ case multiboot2::info::type_t::modules:
+ os::print(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000);
+ os::print("->");
+ os::print(multiboot2::modules_mod_end(it) / 0x1000 * 0x1000);
+ os::print(": ");
+ os::print(multiboot2::modules_string(it));
+ os::printc('\n');
+ test_module.start_address = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000);
+ test_module.end_address = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_end(it) / 0x1000 * 0x1000); // [s,e], not [s,e[
+ break;
default: break;
}
}
// kernel_start and kernel_end are aligned to 4K by the linker script.
- const os::phys_ptr<os::paging::page> s = ([]() {
+ const os::phys_ptr<os::paging::page> kernel_s = ([]() {
os::phys_ptr<os::paging::page> ptr = nullptr;
asm("mov $_kernel_phys_start,%0" : "=ri"(ptr));
return ptr;
})();
- const os::phys_ptr<os::paging::page> e = ([]() {
+ const os::phys_ptr<os::paging::page> kernel_e = ([]() {
os::phys_ptr<os::paging::page> ptr = nullptr;
asm("mov $_kernel_phys_end,%0" : "=ri"(ptr));
return ptr - 1; // [s, e], not [s, e[
// Remove kernel from available RAM:
for (std::size_t i = 0; i < available_ram_length; i++) {
- if (e < available_ram[i].start_address || available_ram[i].end_address < s) {
+ if (kernel_e < available_ram[i].start_address || available_ram[i].end_address < kernel_s) {
continue;
}
- if (s <= available_ram[i].start_address && available_ram[i].end_address <= e) {
+ if (kernel_s <= available_ram[i].start_address && available_ram[i].end_address <= kernel_e) {
available_ram[i] = available_ram[--available_ram_length];
- } else if (s <= available_ram[i].start_address) {
- available_ram[i].start_address = e + 1; // Since e < end_address, new start_address <= end_address.
- } else if (available_ram[i].end_address <= e) {
- available_ram[i].end_address = s - 1; // Since start_address < s, start_address <= new end_address.
+ i--;
+ } else if (kernel_s <= available_ram[i].start_address) {
+ available_ram[i].start_address = kernel_e + 1; // Since e < end_address, new start_address <= end_address.
+ } else if (available_ram[i].end_address <= kernel_e) {
+ available_ram[i].end_address = kernel_s - 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 = s - 1;
- available_ram[available_ram_length].start_address = e + 1;
+ available_ram[i].end_address = kernel_s - 1;
+ available_ram[available_ram_length].start_address = kernel_e + 1;
+ available_ram_length++;
+ }
+ }
+ // Remove module from available RAM:
+ for (std::size_t i = 0; i < available_ram_length; i++) {
+ if (test_module.end_address < available_ram[i].start_address || available_ram[i].end_address < test_module.start_address) {
+ continue;
+ }
+ if (test_module.start_address <= available_ram[i].start_address && available_ram[i].end_address <= test_module.end_address) {
+ available_ram[i] = available_ram[--available_ram_length];
+ i--;
+ } else if (test_module.start_address <= available_ram[i].start_address) {
+ available_ram[i].start_address = test_module.end_address + 1; // Since e < end_address, new start_address <= end_address.
+ } else if (available_ram[i].end_address <= test_module.end_address) {
+ available_ram[i].end_address = test_module.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.start_address - 1;
+ available_ram[available_ram_length].start_address = test_module.end_address + 1;
available_ram_length++;
}
}
os::enable_interrupts(isr_info, idt);
}
- get_base_address(PML4T.contents[0])->contents[0].page.P = false;
- get_base_address(PML4T.contents[0])->contents[1].page.P = false;
+ // Unmap low RAM, and free corresponding page.
PML4T.contents[0].P = false;
+ os::paging::page_allocator.deallocate({.ptr = os::phys_ptr<os::paging::page>(get_base_address(PML4T.contents[0]).get_phys_addr()), .size = 1});
+ os::paging::page_allocator.print_all();
+ // Map test_module to virtual address 0x0000'0000'0000'1000.
+ {
+ os::phys_ptr<os::paging::PT> PT {os::paging::page_allocator.allocate(1).ptr.get_phys_addr()};
+ os::phys_ptr<os::paging::PDT> PDT {os::paging::page_allocator.allocate(1).ptr.get_phys_addr()};
+ os::phys_ptr<os::paging::PDPT> PDPT{os::paging::page_allocator.allocate(1).ptr.get_phys_addr()};
+ PML4T.contents[0] = { .P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0};
+ PDPT->contents[0] = {.non_page = {.P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
+ PDT->contents[0] = {.non_page = {.P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .base_address = 0, .NX = 0}};
+ PT->contents[1] = { .P = 1, .R_W = 0, .U_S = 1, .PWT = 0, .PCD = 0, .PAT = 0, .G = 0, .base_address = 0, .NX = 0};
+ set_base_address(PML4T.contents[0], PDPT);
+ set_base_address(PDPT->contents[0], PDT);
+ set_base_address(PDT->contents[0], PT);
+ set_page_base_address(PT->contents[1], test_module.start_address);
+ }
+ asm volatile("invlpg (%0)" ::"r" (0x1000) : "memory");
+
+ os::paging::on_all_pages(PML4T, [](os::paging::page* virt, os::phys_ptr<os::paging::page> phys, std::size_t size) {
+ if (std::uint64_t(virt) >= 0xFFFF'8000'0000'0000) {
+ return;
+ }
+ os::print(std::uint64_t(virt));
+ os::print("->");
+ os::print(std::uint64_t(phys.get_phys_addr()));
+ os::print(" (");
+ os::print(size);
+ os::print(")\n");
+ });
// Allow userspaaaaaaaaace in ring 3. Otherwise, we just immediately page fault.
// Will make it a module soon-ish.
os::print("Trying move to ring 3:\n");
os::ftl_to_userspace();
}
-
-extern "C" std::uint64_t syscall(std::uint64_t in1);
-
-extern "C" void userspaaaaaaaaace() {
- syscall('a');
- syscall('b');
- syscall('c');
- syscall('\n');
- while (true) { asm volatile("nop"); }
-}