crunch wrote:
I'm aware of that, but using mcmodel=kernel necessitates that you can't put the recursive mapping in the last entry. I just haven't been able to successfully implement recursive mapping at a different location, but then again, I haven't put too much effort into it yet
You mean that putting your kernel on address -2gb results in not being able to recursive map your last entry. This however is no issue, just use another entry for recursive mapping (I used index 256). This gives me the following memory map:
Code:
| Start | End | Usage |
| ---------------- | ---------------- | --------------------------- |
| ffff800000000000 | ffff808000000000 | Recursive pagetable mapping |
| ffff808000000000 | _kernelBegin | Large static allocations |
| _kernelBegin | _kernelEnd | Kernel image |
| _kernelEnd | ffffffffffffffff | Kernel heap |
In which obviously the usage is just a convention I'm using for my kernel. _kernelBegin is located at ffffffff80000000.
Calculating the address to acces a certain entry with the recursive mapping at a different entry can be done with:
Code:
void* entriesToAddress(uint64_t pml4, uint64_t pdp, uint64_t pd, uint64_t pt) {
uint64_t address = (pml4 << 39);
if((address & (1ll << 47)) > 0) {
//We need to sign extend
address |= 0xFFFF000000000000UL;
}
address |= pdp << 30;
address |= pd << 21;
address |= pt << 12;
return (void*)address;
}
//Querying the different pagetable levels:
PageMapLevel4* pml4 = (PageMapLevel4*)entriesToAddress(RECURSIVE_ENTRY, RECURSIVE_ENTRY, RECURSIVE_ENTRY, RECURSIVE_ENTRY);
PageDirectoryPointer* pdp = (PageDirectoryPointer*)entriesToAddress(RECURSIVE_ENTRY, RECURSIVE_ENTRY, RECURSIVE_ENTRY, pml4Entry);
PageDirectory* pd = (PageDirectory*)entriesToAddress(RECURSIVE_ENTRY, RECURSIVE_ENTRY, pml4Entry, pdpEntry);
PageTable* pt = (PageTable*)entriesToAddress(RECURSIVE_ENTRY, pml4Entry, pdpEntry, pdEntry);