extern "C" os::tss TSS;
extern "C" char interrupt_stack_top;
extern "C" os::paging::PML4T old_PML4T;
+char _kernel_phys_start;
+char _kernel_phys_rw_start;
+char _kernel_phys_end;
-os::paging::page<0> bootstrap_pages_for_memory[32]; // 32 pages = 128 KiB
+os::paging::page<0> bootstrap_pages_for_memory[256]; // 256 pages = 1MiB
extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_start> info) {
+ if (!os::init_serial_port()) {
+ while (true) {
+ os::hlt();
+ }
+ }
os::assert(magic == 0x36D76289, "Incorrect magic number: wasn't booted with multiboot2.");
os::paging::page_allocator.deallocate({
});
os::assert(os::cpu_has_msr(), "MSRs aren't supported.");
- // TODO: Initialise new PML4T
- os::paging::global_PML4T = old_PML4T;
- // /TODO
- os::paging::load_pml4t(os::phys_ptr<os::paging::PML4T>{std::uintptr_t(&os::paging::global_PML4T) - 0xFFFF'FFFF'8000'0000});
- os::print("Begin MMAP print.\n");
- os::paging::on_all_pages(os::paging::global_PML4T, []<std::size_t depth>(os::paging::page<depth>* vaddr, os::phys_ptr<os::paging::page<depth>> paddr) {
- os::print("{} -> {} ({})\n", vaddr, (void*)paddr.get_phys_addr(), depth);
- });
- os::print("End MMAP print.\n");
-
- if (!os::init_serial_port()) {
- while (true) {
- os::hlt();
+ // Initialise kernel map.
+ os::assert(std::size_t(&_kernel_phys_start) % 4096 == 0, "Kernel isn't page aligned !");
+ os::assert(std::size_t(&_kernel_phys_rw_start) % 4096 == 0, "Kernel isn't page aligned !");
+ os::assert(std::size_t(&_kernel_phys_end) % 4096 == 0, "Kernel isn't page aligned !");
+ for (std::size_t i = std::size_t(&_kernel_phys_start); i < std::size_t(&_kernel_phys_rw_start); ) {
+ if (i % (1024 * 1024 * 1024) == 0 && i + 1024 * 1024 * 1024 < std::size_t(&_kernel_phys_rw_start)) {
+ os::paging::map_page<2, 3>(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<2>>(i),
+ { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .AVL_or_MPK = 0, .NX = 0 });
+ i += 1024 * 1024 * 1024;
+ } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) {
+ os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<1>>(i),
+ { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 0 });
+ i += 1024 * 1024 * 2;
+ } else {
+ os::paging::map_page<0, 3>(os::paging::global_PML4T, (os::paging::page<0>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<0>>(i),
+ { .R_W = 0, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 0 });
+ i += 1024 * 4;
}
}
+ for (std::size_t i = std::size_t(&_kernel_phys_rw_start); i < std::size_t(&_kernel_phys_end); ) {
+ if (i % (1024 * 1024 * 1024) == 0 && i + 1024 * 1024 * 1024 < std::size_t(&_kernel_phys_rw_start)) {
+ os::paging::map_page<2, 3>(os::paging::global_PML4T, (os::paging::page<2>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<2>>(i),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .AVL_or_MPK = 0, .NX = 1 });
+ i += 1024 * 1024 * 1024;
+ } else if (i % (1024 * 1024 * 2) == 0 && i + 1024 * 1024 * 2 < std::size_t(&_kernel_phys_rw_start)) {
+ os::paging::map_page<1, 3>(os::paging::global_PML4T, (os::paging::page<1>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<1>>(i),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+ i += 1024 * 1024 * 2;
+ } else {
+ os::paging::map_page<0, 3>(os::paging::global_PML4T, (os::paging::page<0>*)(0xFFFF'FFFF'8000'0000 + i), os::phys_ptr<os::paging::page<0>>(i),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
+ i += 1024 * 4;
+ }
+ }
+ // Initialise physical memory map.
+ for (auto it = multiboot2::next(info); it->type != multiboot2::info::type_t::end; it = multiboot2::next(it)) {
+ switch (it->type) {
+ case multiboot2::info::type_t::memory_map:
+ os::print("RAM:\n");
+ for (std::size_t i = 0; i < multiboot2::memory_map_number_of_entries(it); i++) {
+ std::size_t const s = multiboot2::memory_map_base_addr(it, i);
+ std::size_t const e = s + multiboot2::memory_map_length(it, i);
+ os::print("{} -> {} : {}\n", (void*)s, (void*)e, multiboot2::memory_map_type(it, i));
+ if (multiboot2::memory_map_type(it, i) != 1) {
+ continue;
+ }
+ if (e <= 1024 * 1024) { // I'll ignore lower memory for now.
+ continue;
+ }
+ os::assert(s % 0x1000 == 0, "Memory map unaligned on page boundaries.");
+ os::assert(e % 0x1000 == 0, "Memory map unaligned on page boundaries.");
+ for (std::size_t j = s; j < e; ) {
+ if (j % (1024 * 1024 * 1024) == 0 && j + 1024 * 1024 * 1024 < e) {
+ os::paging::map_page<2, 3>(
+ os::paging::global_PML4T,
+ (os::paging::page<2>*)(0xFFFF'8000'0000'0000 + j),
+ os::phys_ptr<os::paging::page<2>>(j),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .AVL_or_MPK = 0, .NX = 1 });
+ j += 1024 * 1024 * 1024;
+ } else if (j % (1024 * 1024 * 2) == 0 && j + 1024 * 1024 * 2 < e) {
+ os::paging::map_page<1, 3>(os::paging::global_PML4T,
+ (os::paging::page<1>*)(0xFFFF'8000'0000'0000 + j),
+ os::phys_ptr<os::paging::page<1>>(j),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .G = 1, .PAT = 0, .base_address = 0, .NX = 1 });
+ j += 1024 * 1024 * 2;
+ } else {
+ os::paging::map_page<0, 3>(os::paging::global_PML4T,
+ (os::paging::page<0>*)(0xFFFF'8000'0000'0000 + j),
+ os::phys_ptr<os::paging::page<0>>(j),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 0, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
+ j += 1024 * 4;
+ }
+ }
+ }
+ os::print("RAM END\n");
+ break;
+ default: break;
+ }
+ }
+ // /TODO
+ os::paging::load_pml4t(os::phys_ptr<os::paging::PML4T>{std::uintptr_t(&os::paging::global_PML4T) - 0xFFFF'FFFF'8000'0000});
{ // Enable interrupts really early so I don't have to manually manage memory... Will make better later, when I make utils.hpp/incrementing_int64_map better.
os::isr_info isr_info[32];
asm ("movq $handler_0x1d,%0" : "=ri"(isr_info[0x1d].addr) : );
asm ("movq $handler_0x1e,%0" : "=ri"(isr_info[0x1e].addr) : );
asm ("movq $handler_0x1f,%0" : "=ri"(isr_info[0x1f].addr) : );
+ // Map local APIC in.
+ os::paging::map_page<0, 3>(os::paging::global_PML4T,
+ (os::paging::page<0>*)(0xFFFF'8000'fee0'0000),
+ os::phys_ptr<os::paging::page<0>>(0x0000'0000'fee0'0000),
+ { .R_W = 1, .U_S = 0, .PWT = 0, .PCD = 1, .PAT = 0, .G = 1, .base_address = 0, .NX = 1 });
os::enable_interrupts(isr_info, idt);
}
);
break;
case multiboot2::info::type_t::memory_map:
- os::print("RAM:\n");
for (std::size_t i = 0; i < multiboot2::memory_map_number_of_entries(it); i++) {
- if (multiboot2::memory_map_type(it, i) == 1) {
- // Rounded up, to avoid including non-ram.
- const os::phys_ptr<os::paging::page<0>>
- s{(multiboot2::memory_map_base_addr(it, i) + 0x1000 - 1) / 0x1000 * 0x1000};
- // Rounded down, to avoid including non-ram.
- const os::phys_ptr<os::paging::page<0>>
- e{(multiboot2::memory_map_base_addr(it, i) + multiboot2::memory_map_length(it, i)) / 0x1000 * 0x1000 - 0x1000};
- if (s <= e) { // In the case where no full page is included in the ram section, don't add it.
- os::assert(available_ram_length < 50, "Too much available RAM sections to initialise correctly. Will fix eventually, probably.");
- available_ram[available_ram_length++] = {.start_address = s, .end_address = e};
- os::print("{} -> {} ({})\n", s, e + 1, (unsigned long)(e + 1 - s));
- }
+ if (multiboot2::memory_map_type(it, i) != 1) {
+ continue;
+ }
+ const os::phys_ptr<os::paging::page<0>> s{multiboot2::memory_map_base_addr(it, i)};
+ const os::phys_ptr<os::paging::page<0>> e{s + multiboot2::memory_map_length(it, i) / 0x1000};
+ if (e.get_phys_addr() <= 1024 * 1024) { // I'll ignore lower memory for now.
+ continue;
}
+ os::assert(available_ram_length < 50, "Too much available RAM sections to initialise correctly. Will fix eventually, probably.");
+ available_ram[available_ram_length++] = {.start_address = s, .end_address = e};
}
- os::print("RAM END\n");
break;
case multiboot2::info::type_t::modules:
os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it), multiboot2::modules_mod_end(it), multiboot2::modules_string(it));
os::assert(module_specified, "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<0>> kernel_s = ([]() {
- os::phys_ptr<os::paging::page<0>> ptr = nullptr;
- asm("mov $_kernel_phys_start,%0" : "=ri"(ptr));
- return ptr;
- })();
- const os::phys_ptr<os::paging::page<0>> kernel_e = ([]() {
- os::phys_ptr<os::paging::page<0>> ptr = nullptr;
- asm("mov $_kernel_phys_end,%0" : "=ri"(ptr));
- return ptr - 1; // [s, e], not [s, e[
- })();
+ const os::phys_ptr<os::paging::page<0>> kernel_s{std::size_t(&_kernel_phys_start)};
+ const os::phys_ptr<os::paging::page<0>> kernel_e{std::size_t(&_kernel_phys_end)};
// Remove kernel from available RAM:
for (std::size_t i = 0; i < available_ram_length; i++) {