AMD64, virtual memory and canonical addresses
Posted: Tue Aug 29, 2006 6:09 am
After reading the Intel and AMD manuals for IA-32e/AMD64, I'm starting to think that you can't do a simple higher half kernel in AMD64. Why? Because you can't statically (at compile/link time) know where is that higher half!
In other words:
All IA-32 processors support 32 bit virtual addresses, and either 16 (386 SX) or 32 bit (all other IA-32) physical addresses. In those processors, higher half is thus 0x80000000-0xFFFFFFFF virtual for any IA-32 processor.
However, while the AMD64 architecture supports UP TO 64 bit virtual addresses and UP TO 52 bit physical ones, processors are not required to implement all that: just a minimum of 48 bit virtual and 40 bit physical. All addresses must be "canonical", that is, non implemented bits (63-48) must be copies op the last implemented one (that is, sign extension).
Thus, the address space is (not taking into account possible 52 and 60 bit implementations):
48 bit: 256 TiB
56 bit: 64 PiB (65 536 TiB)
64 bit: 16 EiB (16 777 216 TiB)
Lower half:
48 bit: 0x0000000000000000-0x00007FFFFFFFFFFF
56 bit: 0x0000000000000000-0x007FFFFFFFFFFFFF
64 bit: 0x0000000000000000-0x7FFFFFFFFFFFFFFF
Higher half:
48 bit: 0xFFFF800000000000-0xFFFFFFFFFFFFFFFF
56 bit: 0xFF80000000000000-0xFFFFFFFFFFFFFFFF
64 bit: 0x8000000000000000-0xFFFFFFFFFFFFFFFF
I reckon this is an intelligent implementation: the "higher half" is always at the very top of the address space, expanding down with more available bits, while the lower half does just the opposite. Seamlessly scalable. However, how can I link my kernel to always use the widest possible address space? I don't think it's possible. Being sincere, as I'm writing this I'm realising that even the 48-bit higher half is 128 TiB, so that should suffice: if I can't fit my microkernel in that space, I'm in trouble ;D
I'm also thinking that, because of the architecture, the OS must not "be nice" to applications and let them get part of the higher half just as my 32 bit design does (I have 3.5GiB/0.5GiB instead of the more common 2/2), because they could get really confused by the "hole" in the memory that will appear in <64bit implementations. So, if the OS gets the higher half and the apps the lower one, nobody notices the hole and everyone is happy. Only in true 64 bit processors can the scheme be adjusted, i.e., with 12EiB/4EiB, or even 15/1. An OS whose KERNEL uses 1 exbibyte, that is 1,048,576 gibibytes looks monstruous to me, but I'm starting to think Windows 2015 will require that
But, continuing with my strange mindstorm... How will current OSs manage processors with >48 bits vaddrs? AFAIK, AMD and Intel have only defined the paging mechanisms up to the PML4, so that only covers up to 48 bits. That probably means that 1) neither one has plans to deliver AMD64>48 bit processors in the near future (maybe some years), and 2) all "64 bit" OSes now are really "48 bit", and if run ten years into the future on a true 64 bit processor they could only map 256TiB of memory (48 bits) with their PML4 because they don't know how the paging scheme for the remaining 16 bits will look like! So, those of you running WinXP Pro x64, or Linux x86_64, you're really running WinXP Pro x48 / Linux x86_48 By the way, I think they could even crash if run on a processor >48bit if Intel & AMD don't devise a clever way for the processor to recognize if the OS is setting CR3 to a PML4 instead of the PML5, PML6 or whatever used in those future processors, maybe through a setting in a new CRx. Of course, these OSes could also crash for not supporting other hardware of that time, maybe EFI2, Super Hiper Mega PCI-Express3, DDR7++, etc.
Well, enough of this. I'm returning to my cell in the mental sanatorium. Just asking for your thoughts on the matter...
In other words:
All IA-32 processors support 32 bit virtual addresses, and either 16 (386 SX) or 32 bit (all other IA-32) physical addresses. In those processors, higher half is thus 0x80000000-0xFFFFFFFF virtual for any IA-32 processor.
However, while the AMD64 architecture supports UP TO 64 bit virtual addresses and UP TO 52 bit physical ones, processors are not required to implement all that: just a minimum of 48 bit virtual and 40 bit physical. All addresses must be "canonical", that is, non implemented bits (63-48) must be copies op the last implemented one (that is, sign extension).
Thus, the address space is (not taking into account possible 52 and 60 bit implementations):
48 bit: 256 TiB
56 bit: 64 PiB (65 536 TiB)
64 bit: 16 EiB (16 777 216 TiB)
Lower half:
48 bit: 0x0000000000000000-0x00007FFFFFFFFFFF
56 bit: 0x0000000000000000-0x007FFFFFFFFFFFFF
64 bit: 0x0000000000000000-0x7FFFFFFFFFFFFFFF
Higher half:
48 bit: 0xFFFF800000000000-0xFFFFFFFFFFFFFFFF
56 bit: 0xFF80000000000000-0xFFFFFFFFFFFFFFFF
64 bit: 0x8000000000000000-0xFFFFFFFFFFFFFFFF
I reckon this is an intelligent implementation: the "higher half" is always at the very top of the address space, expanding down with more available bits, while the lower half does just the opposite. Seamlessly scalable. However, how can I link my kernel to always use the widest possible address space? I don't think it's possible. Being sincere, as I'm writing this I'm realising that even the 48-bit higher half is 128 TiB, so that should suffice: if I can't fit my microkernel in that space, I'm in trouble ;D
I'm also thinking that, because of the architecture, the OS must not "be nice" to applications and let them get part of the higher half just as my 32 bit design does (I have 3.5GiB/0.5GiB instead of the more common 2/2), because they could get really confused by the "hole" in the memory that will appear in <64bit implementations. So, if the OS gets the higher half and the apps the lower one, nobody notices the hole and everyone is happy. Only in true 64 bit processors can the scheme be adjusted, i.e., with 12EiB/4EiB, or even 15/1. An OS whose KERNEL uses 1 exbibyte, that is 1,048,576 gibibytes looks monstruous to me, but I'm starting to think Windows 2015 will require that
But, continuing with my strange mindstorm... How will current OSs manage processors with >48 bits vaddrs? AFAIK, AMD and Intel have only defined the paging mechanisms up to the PML4, so that only covers up to 48 bits. That probably means that 1) neither one has plans to deliver AMD64>48 bit processors in the near future (maybe some years), and 2) all "64 bit" OSes now are really "48 bit", and if run ten years into the future on a true 64 bit processor they could only map 256TiB of memory (48 bits) with their PML4 because they don't know how the paging scheme for the remaining 16 bits will look like! So, those of you running WinXP Pro x64, or Linux x86_64, you're really running WinXP Pro x48 / Linux x86_48 By the way, I think they could even crash if run on a processor >48bit if Intel & AMD don't devise a clever way for the processor to recognize if the OS is setting CR3 to a PML4 instead of the PML5, PML6 or whatever used in those future processors, maybe through a setting in a new CRx. Of course, these OSes could also crash for not supporting other hardware of that time, maybe EFI2, Super Hiper Mega PCI-Express3, DDR7++, etc.
Well, enough of this. I'm returning to my cell in the mental sanatorium. Just asking for your thoughts on the matter...