Memory layout: Difference between revisions
No edit summary |
|||
Line 18: | Line 18: | ||
On version [[1.0.0]], the initial binaries loaded into memory by the kernel always have the upper 32-bits as all-zero, so there are 6 fewer bits of layout randomization. | On version [[1.0.0]], the initial binaries loaded into memory by the kernel always have the upper 32-bits as all-zero, so there are 6 fewer bits of layout randomization. | ||
= | == ASLR Implementation == | ||
== 1.0.0 == | === 1.0.0 === | ||
if (AddressSpaceType == 2) { | if (AddressSpaceType == 2) { | ||
Line 52: | Line 52: | ||
= Kernel = | = Kernel = | ||
For more details, see [[#Notes]]. Here comes a summary. | |||
PXN bit is set in the MMU descriptor for userland code pages. This means that userland code pages are not executable in kernel mode (equivalent to SMEP on x86). | |||
For userland pages, the kernel has same access as userland (either both are read-only or both are read-write). This rule has one exception: pages that are mapped unreadable in usermode are still forced readable from kernelmode. | |||
As of [[2.0.0]] KASLR is not used. | As of [[2.0.0]] KASLR is not used. | ||
== [[2.0.0]] == | == [[2.0.0]] == | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Cores | |||
! Virtual | ! Virtual | ||
! Physical | ! Physical | ||
Line 107: | Line 71: | ||
! Description | ! Description | ||
|- | |- | ||
| 0xFFFFFFF800000000-... || 0x80000000 || ... || ? || ? || Raw DRAM access | | All || 0xFFFFFFF800000000-... || 0x80000000 || ... || ? || ? || Raw DRAM access | ||
|- | |- | ||
| 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC62FFF || 0x800A0000 || 0x63000 || 0x78B || R-X || Kernel .text | | All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC62FFF || 0x800A0000 || 0x63000 || 0x78B || R-X || Kernel .text | ||
|- | |- | ||
| 0xFFFFFFF7FFC63000-0xFFFFFFF7FFC65FFF || 0x80103000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata | | All || 0xFFFFFFF7FFC63000-0xFFFFFFF7FFC65FFF || 0x80103000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata | ||
|- | |- | ||
| 0xFFFFFFF7FFC66000-0xFFFFFFF7FFC6EFFF || 0x80106000 || 0x9000 || 0x6000000000070B || RW- || Kernel .data+.bss | | All || 0xFFFFFFF7FFC66000-0xFFFFFFF7FFC6EFFF || 0x80106000 || 0x9000 || 0x6000000000070B || RW- || Kernel .data+.bss | ||
|- | |- | ||
| 0xFFFFFFF7FFDCA000-0xFFFFFFF7FFDCAFFF || 0x80060000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDCA000-0xFFFFFFF7FFDCAFFF || 0x80060000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDCB000-0xFFFFFFF7FFDCBFFF || 0x80061000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDCB000-0xFFFFFFF7FFDCBFFF || 0x80061000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDCE000-0xFFFFFFF7FFDCEFFF || 0x80068000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDCE000-0xFFFFFFF7FFDCEFFF || 0x80068000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDD4000-0xFFFFFFF7FFDD4FFF || 0x80062000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDD4000-0xFFFFFFF7FFDD4FFF || 0x80062000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDD5000-0xFFFFFFF7FFDD5FFF || 0x80063000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDD5000-0xFFFFFFF7FFDD5FFF || 0x80063000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDD8000-0xFFFFFFF7FFDD8FFF || 0x8006A000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDD8000-0xFFFFFFF7FFDD8FFF || 0x8006A000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDD9000-0xFFFFFFF7FFDD9FFF || 0x8006B000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDD9000-0xFFFFFFF7FFDD9FFF || 0x8006B000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDDE000-0xFFFFFFF7FFDDEFFF || 0x80064000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDDE000-0xFFFFFFF7FFDDEFFF || 0x80064000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDDF000-0xFFFFFFF7FFDDFFFF || 0x80065000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDDF000-0xFFFFFFF7FFDDFFFF || 0x80065000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDE2000-0xFFFFFFF7FFDE2FFF || 0x8006C000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDE2000-0xFFFFFFF7FFDE2FFF || 0x8006C000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDE3000-0xFFFFFFF7FFDE3FFF || 0x8006D000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDE3000-0xFFFFFFF7FFDE3FFF || 0x8006D000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDE8000-0xFFFFFFF7FFDE8FFF || 0x80066000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDE8000-0xFFFFFFF7FFDE8FFF || 0x80066000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDE9000-0xFFFFFFF7FFDE9FFF || 0x80067000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDE9000-0xFFFFFFF7FFDE9FFF || 0x80067000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDCF000-0xFFFFFFF7FFDCFFFF || 0x80069000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDCF000-0xFFFFFFF7FFDCFFFF || 0x80069000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDEC000-0xFFFFFFF7FFDECFFF || 0x8006E000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDEC000-0xFFFFFFF7FFDECFFF || 0x8006E000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDED000-0xFFFFFFF7FFDEDFFF || 0x8006F000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDED000-0xFFFFFFF7FFDEDFFF || 0x8006F000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDD2000-0xFFFFFFF7FFDD2FFF || 0x80070000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDD2000-0xFFFFFFF7FFDD2FFF || 0x80070000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDDC000-0xFFFFFFF7FFDDCFFF || 0x80071000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDDC000-0xFFFFFFF7FFDDCFFF || 0x80071000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDE6000-0xFFFFFFF7FFDE6FFF || 0x80072000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDE6000-0xFFFFFFF7FFDE6FFF || 0x80072000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDF0000-0xFFFFFFF7FFDF0FFF || 0x80073000 || 0x1000 || 0x6000000000070B || RW- || | | All || 0xFFFFFFF7FFDF0000-0xFFFFFFF7FFDF0FFF || 0x80073000 || 0x1000 || 0x6000000000070B || RW- || | ||
|- | |- | ||
| 0xFFFFFFF7FFDC6000-0xFFFFFFF7FFDC6FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC IO | | All || 0xFFFFFFF7FFDC6000-0xFFFFFFF7FFDC6FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDC4000-0xFFFFFFF7FFDC4FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0 IO | | All || 0xFFFFFFF7FFDC4000-0xFFFFFFF7FFDC4FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0 IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDC2000-0xFFFFFFF7FFDC2FFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1 IO | | All || 0xFFFFFFF7FFDC2000-0xFFFFFFF7FFDC2FFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1 IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDC0000-0xFFFFFFF7FFDC0FFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || CLK IO | | All || 0xFFFFFFF7FFDC0000-0xFFFFFFF7FFDC0FFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || CLK IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDC8000-0xFFFFFFF7FFDC8FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A IO | | All || 0xFFFFFFF7FFDC8000-0xFFFFFFF7FFDC8FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Distributor IO | | All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Distributor IO | ||
|- | |- | ||
| 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller IO | | All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller IO | ||
|} | |} | ||
Line 433: | Line 397: | ||
| TZRAM | | TZRAM | ||
|} | |} | ||
= Notes = | |||
== 2.0.0 == | |||
Granule size for TTBR0*_EL1 is 4KB. | |||
TTBR0_EL1 vmem starts at vaddr 0x0. | |||
vmem end-addr for TTBR1_EL1 is 0xffffffffffffffff. vmem start-addr for TTBR1_EL1 is 0xFFFFFFF000000000. | |||
T0SZ = 31. Hence, bit-size of the TTBR0*_EL1 vmem region is 33. (0x0000000200000000) | |||
T1SZ = 28. Hence, bit-size of the TTBR1*_EL1 vmem region is 36. (0x0000001000000000) | |||
Note: ARM config for TTBR0 is presumably configured for userland later. | |||
See arm-doc for "Table D4-25 Translation table entry addresses when using the 4KB translation granule". | |||
See arm-doc for "Overview of VMSAv8-64 address translation using the 4KB translation granule". | |||
See arm-doc for "Table D4-11 TCR.TnSZ values and IA ranges, 4K granule with no concatenation of tables". | |||
Both TTBR*_EL1 use "Initial lookup level" 1. Therefore, the TTBR*_EL1 tables are level1. | |||
Due to T*SZ, Stage1/Stage2 translation for the initial table(level1) are the same, except Stage2 uses hard-coded T0SZ. | |||
Basically, the table is accessed as: ((u64*)tablebase)[<IA[y:30]>], where y = (37-T*SZ)+26. That is, starting at bit "y" ending(inclusive) at bit30. For TTBR0*_EL1, y = 32, while for TTBR1_EL1 y = 35. | |||
Hence, for TTBR0, index=((vaddr>>30) & 0x7), and for TTBR1, index=((vaddr>>30) & 0x3f). | |||
"Vector Base Address Register (EL1)" = 0xfffffff7ffc50800. | |||
The table for TTBR0 only contains the following: | |||
* Vmem 0x80000000 is mapped to physmem 0x80000000, using a size loaded from a register. This is only done when: "endaddr = 0x7fffffff + size; if(endaddr >= 0x80000001){...}" | |||
** The size is loaded from: "(u32 *0x70019050 & 0x3fff) << 20;" | |||
** The value written to the MMU-table descriptor is: "physaddr | val | 0x709;". val is 1<<52 when "tmp>>34" is non-zero and when "if((physaddr & 0x3c0000000) == 0)", otherwise val=0. tmp=size at the start and increased by 0xffffffffc0000000 each loop iteration. physaddr is increased by 0x40000000 each loop iteration. | |||
TTBR1: | |||
* vmem 0xFFFFFFF800000000 is mapped to physmem 0x80000000. Similar to above, except tmp=0 due to wrap-around, etc. The chunksize used when increasing addr is 0xfffffff840000000, with another +=0x40000000 separate from the addr cmp for the loop. | |||
** "endaddr = 0x3fffffff + (<size from above> | 0xfffffff800000000); enaddr = (endaddr & 0xffffffffc0000000)-1; if(endaddr >= 0xfffffff800000001){<map mem>}" | |||
* Initializes level2 pagetable descriptor for vmem 0xFFFFFFF7C0000000. descriptor = 0x3 | physaddr. physaddr is core-specific. | |||
* Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFC00000. descriptor = 0x3 | physaddr. physaddr is core-specific. | |||
* The content of the pagetable for the following level3 mmutables are not initialized in the main mmutable-init func. descriptor = 0x8007c003(0x3 | <physaddr tablebase>). tablebase=0x8007c000. | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEE00000. physaddr = tablebase + (0x1<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF000000. physaddr = tablebase + (0x2<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF200000. physaddr = tablebase + (0x3<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FFA00000. physaddr = tablebase + (0x7<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FEC00000. physaddr = tablebase. | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF400000. physaddr = tablebase + (0x4<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF600000. physaddr = tablebase + (0x5<<12). | |||
** Initializes level3 pagetable descriptor for vmem 0xFFFFFFF7FF800000. physaddr = tablebase + (0x6<<12). |