#include "vmm.h" #include typedef void (*constructor)(); extern "C" { /* .text */ uint32_t begin_text; uint32_t end_text; /* .rodata */ uint32_t begin_rodata; uint32_t end_rodata; /* .data */ uint32_t begin_constinit; uint32_t end_constinit; constructor begin_ctors; constructor end_ctors; uint32_t begin_data; uint32_t end_data; /* .bss */ uint32_t begin_bss; uint32_t end_bss; void kernel_constructors() { for (constructor* i = &begin_ctors; i != &end_ctors; ++i) (*i)(); } void dump_address() { printk("text begin: ", uhex{reinterpret_cast(&begin_text)}, " end: ", uhex{reinterpret_cast(&end_text)}, '\n'); printk("rodata begin: ", uhex{reinterpret_cast(&begin_rodata)}, " end: ", uhex{reinterpret_cast(&end_rodata)}, '\n'); printk("constinit begin: ", uhex{reinterpret_cast(&begin_constinit)}, " end: ", uhex{reinterpret_cast(&end_constinit)}, '\n'); printk("ctors begin: ", uhex{reinterpret_cast(&begin_ctors)}, " end: ", uhex{reinterpret_cast(&end_ctors)}, '\n'); printk("data begin: ", uhex{reinterpret_cast(&begin_data)}, " end: ", uhex{reinterpret_cast(&end_data)}, '\n'); printk("bss begin: ", uhex{reinterpret_cast(&begin_bss)}, " end: ", uhex{reinterpret_cast(&end_bss)}, '\n'); } } // extern "C" /* boot.S page directory and kernel page table */ extern uint32_t kernel_pagedir; extern uint32_t kernel_ptable0; constexpr uint32_t to_vma(uint32_t page_dir_address) { page_dir_address &= 0xfffff000; page_dir_address += 0xc0000000; page_dir_address -= 0x00400000; return page_dir_address; } vmm::vmm(uint32_t* addr) : directory{(addr == nullptr) ? &kernel_pagedir : addr} { printk("page directory is at ", uhex{reinterpret_cast(directory)}, '\n'); printk("page table 768 ", uhex{reinterpret_cast(directory[768])}, '\n'); printk("page table 768 vma ", uhex{to_vma(reinterpret_cast(directory[768]))}, '\n'); printk("kernel_ptable0 is at ", uhex{reinterpret_cast(&kernel_ptable0)}, '\n'); uint32_t* page = reinterpret_cast(&kernel_ptable0); for (size_t i = 0; i < 32; ++i) { printk(uhex{page[i] & 0xfffff000}, ' '); if (i % 4 == 3) printk('\n'); } } uint32_t vmm::map(uint32_t phys_addr, uint32_t dest) { const auto phys_offset = phys_addr % 4096; const auto phys_page = phys_addr - phys_offset; const auto table = table_id(dest); const auto page = page_id(dest - table * 4 * 1024 * 1024); printk("phys_addr page: ", uhex{phys_page}, '\n'); printk(" offset: ", uhex{phys_offset}, '\n'); printk(" table: ", table, '\n'); printk(" page: ", page, '\n'); if (directory[table] == 0) return 0; uint32_t* page_table = reinterpret_cast(to_vma(reinterpret_cast(directory[table]))); if (page_table[page] != 0) return 0; page_table[page] = phys_page | 0x003; uint32_t cr0; asm volatile("mov %%cr0, %0" : "=r"(cr0)); asm volatile("mov %0, %%cr0" : : "r"(cr0)); return table * 4 * 1024 * 1024 + page * 4 * 1024 + phys_offset; }