I'm writing a (64-bit mode) page table manipulation module. The interface is very simple:
Code:
uint64_t mmu_create_table();
void mmu_free_table(uint64_t cr3);
uint64_t mmu_translate(uint64_t cr3, uint64_t va, uint64_t *attrs);
void mmu_map(uint64_t cr3, uint64_t va, uint64_t va_end, uint64_t pa, uint64_t attrs);
void mmu_unmap(uint64_t cr3, uint64_t va, uint64_t va_end);
But I find the implementation is more difficult than I thought. There are many details and caveats.
mmu_map can overwrite existing mapping.
I use 2M and 1G pages when possible, in order to use less memory. When remapping (a sub region of) a 2M large page, what's left out have to be remapped (using 4K pages).
If 512 continuous 4K pages also map to continuous physical pages, and have same attributes, then they can be replaced with a single 2M entry.
That makes code very complex, I have to write map/unmap functions for each level of page table.
I want to support demand paging, growable stack/heap, dynamic linking, etc. So page table manipulation is required.
Is that the right way to paging? Am I making it too bloated?
Thanks