Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
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 48-bit address is sign extended into 64-bits, so bits 63-48 are supposed to have the same value as bit 47, which turns 0x800000000000 into 0xFFFF800000000000, and so on. If you try accessing an address where bits 63-48 don't have the same value as bit 47, you'll get a general protection fault with error code 0.
Bit 47 is 1. This is not extended to bits 48 - 63, which are all 0, so the address is not canonical, and raises an error when you attempt to access it.
If you want to map 256-Tbytes, check for five-level paging and then set CR4.LA57. Then set up your PML5 table and fill it with 512 PML5Es.Then canonicalize your addresses by sign-extending bit 56 to bits 57-64 (if memory serves).
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.
You need to walk the page tables, just like the MMU does, to translate a virtual address to a physical address.
antoni wrote: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!
You can map 256 TiB total, but it's split into two 128 TiB pieces. The lower 128TiB is addresses from 0 to 0x00007FFFFFFFFFFF, and the upper 128 TiB is addresses from 0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFF. Your example address 0xFFFFFFFFFFE02000 is in the upper 128 TiB.
With 4-level paging, you can't map anything from 0x0000800000000000 to 0xFFFF7FFFFFFFFFFF. Addresses in that range will always be invalid.