How can you map more than 256 TiB in long mode.
Posted: Sun Sep 05, 2021 1:31 pm
I'm switching to BOOTBOOT. For a long time I developed my bottom half kernel but now I want to try a higher half kernel.
The problem is that it's code segment for example is mapped to 0xFFFFFFFFFFE02000. However, using 4-level paging you can only map up to 256 TiB (max. range 0x1000000000000) of memory!
For now I use this function to get physical address of some page:
I was able to successfully get address of first 2GiB (or more if available) of memory which are identity mapped in BOOTBOOT protocol. However, obviously this method did not work with higher addresses. I wonder how they were even mapped.
The problem is that it's code segment for example is mapped to 0xFFFFFFFFFFE02000. However, using 4-level paging you can only map up to 256 TiB (max. range 0x1000000000000) of memory!
For now I use this function to get physical address of some page:
Code: Select all
intptr_t vm_get_physaddr(struct vm_space *vm_space, void *virtualaddr)
{
uint64_t pml4 = vm_space->pml4;
uint64_t ptindex = (uint64_t) virtualaddr / 0x1000 % 512;
uint64_t pdindex = ((uint64_t) virtualaddr / 0x200000) % 512;
uint64_t pdpindex = ((uint64_t) virtualaddr / 0x40000000) % 512;
uint64_t pml4index = ((uint64_t) virtualaddr / 0x8000000000);
uint64_t *entry = (uint64_t*) pml4;
if (!(entry[pml4index] & 1))
return -1;
entry = (uint64_t*) (entry[pml4index] & ~0xFFF);
if (!(entry[pdpindex] & 1))
return -1;
entry = (uint64_t*) (entry[pdpindex] & ~0xFFF);
if (!(entry[pdindex] & 1))
return -1;
entry = (uint64_t*) (entry[pdindex] & ~0xFFF);
if (!(entry[ptindex] & 1))
return -1;
entry = (uint64_t*) (entry[ptindex] & ~0xFFF);
return entry;
}