Line 3: |
Line 3: |
| | | |
| There are two regions randomized and enforced by the kernel, each one with upper bits random and 2MB-aligned: | | There are two regions randomized and enforced by the kernel, each one with upper bits random and 2MB-aligned: |
− | * Heap region, available from [[SVC#svcGetInfo]]. | + | * ReservedHeapRegion, available from [[SVC#svcGetInfo]]. |
− | * Stack mapping region, available from [[SVC#svcGetInfo]]. | + | * ReservedMapRegion, available from [[SVC#svcGetInfo]]. |
| + | * [2.0.0+] NewReservedMapRegion, available from [[SVC#svcGetInfo]]. |
| + | * [2.0.0+] TlsIoRegion, not available to userspace. |
| | | |
| The main binary is placed at an address that is provided to the kernel by Loader via [[SVC#svcCreateProcess]]. | | The main binary is placed at an address that is provided to the kernel by Loader via [[SVC#svcCreateProcess]]. |
Line 17: |
Line 19: |
| | | |
| 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. |
| + | |
| + | Binaries loaded within the main-binary-region are loaded into memory in the following order, immediately after each other, for the binaries which exist in [[ExeFS]]: |
| + | * rtld |
| + | * main |
| + | * subsdk* |
| + | * sdk |
| | | |
| == ASLR Implementation == | | == ASLR Implementation == |
− | | + | The kernel uses a MT19937 random number generator, seeded by a [[SMC#GetRandomBytes|smcGetRandomBytes]] |
| === 1.0.0 === | | === 1.0.0 === |
| | | |
Line 58: |
Line 66: |
| For userland pages, the kernel has same access as userland (either both are read-only or both are read-write). It does not have SMAP. The previous rule has one exception: pages that are mapped unreadable in usermode are still forced readable from kernelmode. | | For userland pages, the kernel has same access as userland (either both are read-only or both are read-write). It does not have SMAP. The previous 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.
| + | KASLR is being used since [[5.0.0]], but not before, with the following pseudocode (might contains some errors): |
| + | |
| + | <code><pre> |
| + | DRAM crt0 mapping (ttbr1): offsets DRAM with (rand64ViaSmc() % 0x3FFF0 << 21), allocates exactly (end - _start) + 1GB. |
| + | This is a "linear" mapping. Permissions are set properly. |
| + | |
| + | KERN_ADDRSPACE := [VA(_start) : min(0xFFFFFFFFFFE00000 - VA(_start), 0x40000000)] |
| + | DRAM_FROM_SECTION1 := DRAM[0x808cd000:] // 0x808cd000 corresponds to start of section1 (loaded INI1) data, reused later |
| + | |
| + | /* Global Randomize range: 0xFFFFFF8000000000 to 0xFFFFFFFFFFE00000. */ |
| + | /* |
| + | Randomize picks a random integer in ranges, clears as many low bits required, |
| + | then checks if the address is acceptable, if not it attempts to iterate through page table entries. |
| + | |
| + | If it doesn't find anything, it picks another integer. In case of general failure, the whole operation |
| + | may be done from the start again (maybe ?). |
| + | */ |
| + | |
| + | /* Core0 executes this big KASLR function, then powers on the other CPUs (?). */ |
| + | MapPartially(RandomizeL1Boundary(DRAM, sizeof(DRAM)) -> DRAM_FROM_SECTION1: offsetof DRAM_FROM_SECTION1, |
| + | |
| + | /* Randomize */ |
| + | KERN_ADDRSPACE { |
| + | Randomize(IOAndInitialStacks, 0x2000000) { |
| + | Map(Randomize(UartA, 0x1000)) -> UartA, |
| + | GuardPage, |
| + | Map(Randomize(Gicd, 0x1000)) -> Gicd, |
| + | GuardPage, |
| + | Map(Randomize(Gicc, 0x1000)) -> Gicc, |
| + | ForEachCore { |
| + | GuardPage, |
| + | Map(Randomize(EntryThreadStack, 0x1000)) -> NextFreePage(), |
| + | GuardPage, |
| + | Map(Randomize(IdleSchedulerThreadStack, 0x1000)) -> NextFreePage(), |
| + | GuardPage, |
| + | Map(Randomize(EL1AbortStack, 0x1000)) -> NextFreePage(), |
| + | } |
| + | }, |
| + | |
| + | Randomize(KernelStacks, 0xE00000), |
| + | Map(Randomize(SlabHeaps, 0x7E9000, AFTER(VA(_end)) -> PA(_end)), |
| + | Randomize(Kip1DecompressionBuffer, 0x8000000), /* 128 MB VA range */ |
| + | }, |
| + | |
| + | Map(RandomizePageBoundary(GuardPage + KCoreContext * 4)) -> NextFreePages(4) |
| + | </pre></code> |
| | | |
| == 1.0.0 == | | == 1.0.0 == |
Line 181: |
Line 234: |
| | All || 0xFFFFFFF800000000-... || 0x80000000 || ... || 0x60000000000709 || RW- || Raw DRAM access | | | All || 0xFFFFFFF800000000-... || 0x80000000 || ... || 0x60000000000709 || RW- || Raw DRAM access |
| |} | | |} |
| + | |
| + | == 3.0.0 == |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Cores || Virtual || Physical || Size || Attributes || Permissions || Description |
| + | |- |
| + | | All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC4AFFF || 0x800A0000 || 0x4B000 || 0x78B || R-X || Kernel .text |
| + | |- |
| + | | All || 0xFFFFFFF7FFC4B000-0xFFFFFFF7FFC4DFFF || 0x800EB000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata |
| + | |- |
| + | | All || 0xFFFFFFF7FFC4E000-0xFFFFFFF7FFC5AFFF || 0x800EE000 || 0xD000 || 0x6000000000070B || RW- || Kernel .data+.bss |
| + | |- |
| + | | All || 0xFFFFFFF7FFDAC000-0xFFFFFFF7FFDACFFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and Reset |
| + | |- |
| + | | All || 0xFFFFFFF7FFDAE000-0xFFFFFFF7FFDAEFFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1 |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB0000-0xFFFFFFF7FFDB0FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0 |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB2000-0xFFFFFFF7FFDB2FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB4000-0xFFFFFFF7FFDB4FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A |
| + | |- |
| + | | All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor |
| + | |- |
| + | | All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface |
| + | |} |
| + | |
| + | == 4.0.0 == |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Cores || Virtual || Physical || Size || Attributes || Permissions || Description |
| + | |- |
| + | | All || 0xFFFFFFF7FFC00000-0xFFFFFFF7FFC50FFF || 0x800A0000 || 0x51000 || 0x4000000000078B || R-X || Kernel .text |
| + | |- |
| + | | All || 0xFFFFFFF7FFC51000-0xFFFFFFF7FFC53FFF || 0x800F1000 || 0x3000 || 0x6000000000078B || R-- || Kernel .rodata |
| + | |- |
| + | | All || 0xFFFFFFF7FFC54000-0xFFFFFFF7FFC61FFF || 0x800F4000 || 0xE000 || 0x6000000000070B || RW- || Kernel .data+.bss |
| + | |- |
| + | | All || 0xFFFFFFF7FFDAC000-0xFFFFFFF7FFDACFFF || 0x60006000 || 0x1000 || 0x60000000000607 || RW- || Clock and Reset |
| + | |- |
| + | | All || 0xFFFFFFF7FFDAE000-0xFFFFFFF7FFDAEFFF || 0x7001D000 || 0x1000 || 0x60000000000607 || RW- || MC1 |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB0000-0xFFFFFFF7FFDB0FFF || 0x7001C000 || 0x1000 || 0x60000000000607 || RW- || MC0 |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB2000-0xFFFFFFF7FFDB2FFF || 0x70019000 || 0x1000 || 0x60000000000607 || RW- || MC |
| + | |- |
| + | | All || 0xFFFFFFF7FFDB4000-0xFFFFFFF7FFDB4FFF || 0x70006000 || 0x1000 || 0x60000000000607 || RW- || UART-A |
| + | |- |
| + | | All || 0xFFFFFFF7FFDFB000-0xFFFFFFF7FFDFBFFF || 0x50041000 || 0x1000 || 0x60000000000607 || RW- || ARM Interrupt Distributor |
| + | |- |
| + | | All || 0xFFFFFFF7FFDFD000-0xFFFFFFF7FFDFDFFF || 0x50042000 || 0x1000 || 0x60000000000607 || RW- || Interrupt Controller Physical CPU interface |
| + | |} |
| + | |
| | | |
| The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B. | | The rest are are mapped to core-specific physaddrs, each one is 0x1000-bytes. Descriptor ORR-value = 0x6000000000070B. |
Line 209: |
Line 315: |
| | | |
| = Secure Monitor = | | = Secure Monitor = |
| + | |
| + | Unless otherwise mentionned, block descriptors (in our case, the one uses for the DRAM identity mapping) are all ORRed by 0x401 and page descriptors by 0x403. |
| + | |
| + | == [[1.0.0]] == |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Vmem |
| + | ! Physmem |
| + | ! Size |
| + | ! Descriptor ORR-value |
| + | ! Permissions |
| + | ! Description |
| + | |- |
| + | | 0x1F0000000 |
| + | | 0x50041000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | |
| + | | ARM Interrupt Distributor |
| + | |- |
| + | | 0x1F0002000 |
| + | | 0x50042000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | |
| + | | Interrupt Controller Physical CPU Interface |
| + | |- |
| + | | 0x1F0005000 |
| + | | 0x70006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | |
| + | | UART-A |
| + | |- |
| + | | 0x1F0007000 |
| + | | 0x60006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | |
| + | | Clock and Reset |
| + | |- |
| + | | 0x1F0009000 |
| + | | 0x7000E000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | PMC |
| + | |- |
| + | | 0x1F000B000 |
| + | | 0x60005000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | TMR |
| + | |- |
| + | | 0x1F000D000 |
| + | | 0x6000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | System Registers |
| + | |- |
| + | | 0x1F000F000 |
| + | | 0x70012000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | |
| + | | SE |
| + | |- |
| + | | 0x1F0012000 |
| + | | 0x700F0000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | SYSCTR0 |
| + | |- |
| + | | 0x1F0014000 |
| + | | 0x70019000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | MC |
| + | |- |
| + | | 0x1F0016000 |
| + | | 0x7000F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | FUSE |
| + | |- |
| + | | 0x1F0018000 |
| + | | 0x70000000 |
| + | | 0x4000 |
| + | | 0x40000000000304 |
| + | | |
| + | | MISC |
| + | |- |
| + | | 0x1F001D000 |
| + | | 0x60007000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | Flow controller |
| + | |- |
| + | | 0x1F001F000 |
| + | | 0x40002000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | IRAM |
| + | |- |
| + | | 0x1F0021000 |
| + | | 0x7000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | I2C-5 |
| + | |- |
| + | | 0x1F0023000 |
| + | | 0x6000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | GPIO-1 |
| + | |- |
| + | | 0x1F0025000 |
| + | | 0x7000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | I2C |
| + | |- |
| + | | 0x1F0180000 |
| + | | 0x40020000 |
| + | | 0x10000 |
| + | | 0x40000000000324 |
| + | | |
| + | | IRAM |
| + | |- |
| + | | 0x1F01A0000 |
| + | | 0x7C010000 |
| + | | 0x10000 |
| + | | 0x40000000000384 |
| + | | |
| + | | TZRAM |
| + | |- |
| + | | 0x1F01C3000 |
| + | | 0x80010000 |
| + | | 0x10000 |
| + | | 0x40000000000324 |
| + | | |
| + | | EMEM |
| + | |- |
| + | | 0x1F01C2000 |
| + | | 0x8000F000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | |
| + | | EMEM |
| + | |- |
| + | | 0x1F01E0000 |
| + | | 0x7C013000 |
| + | | 0xB000 |
| + | | 0x304 |
| + | | |
| + | | TZRAM (Secure Monitor) |
| + | |- |
| + | | 0x1F01F0000 |
| + | | 0x7C01E000 |
| + | | 0x2000 |
| + | | 0x304 |
| + | | |
| + | | TZRAM (Secure Monitor and ARMv8 init) |
| + | |- |
| + | | 0x1F01F6000 |
| + | | 0x7C01E000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | TZRAM |
| + | |- |
| + | | 0x1F01F8000 |
| + | | 0x7C01F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | TZRAM |
| + | |- |
| + | | 0x1F01FA000 |
| + | | 0x7C010000 |
| + | | 0x1000 |
| + | | 0x304 |
| + | | |
| + | | TZRAM (Secure Monitor exception vectors) |
| + | |- |
| + | | 0x1F01FC000 |
| + | | 0x7C011000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | TZRAM |
| + | |- |
| + | | 0x1F01FE000 |
| + | | 0x7C012000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | |
| + | | TZRAM |
| + | |} |
| | | |
| == [[2.0.0]] == | | == [[2.0.0]] == |
Line 268: |
Line 584: |
| | 0x40000000000304 | | | 0x40000000000304 |
| | | | | |
− | | RTC | + | | PMC |
| |- | | |- |
| | 0x1F008B000 | | | 0x1F008B000 |
Line 408: |
Line 724: |
| | 0x300 | | | 0x300 |
| | | | | |
− | | TZRAM (Secure Monitor init) | + | | TZRAM (Secure Monitor and ARMv8 init) |
| + | |- |
| + | | 0x1F01F4000 |
| + | | <varies> |
| + | | 0x1000 |
| + | | 0x40000000000320 |
| + | | |
| + | | DRAM (SPL .bss buffer visible to the Security Engine) |
| |- | | |- |
| | 0x1F01F6000 | | | 0x1F01F6000 |
Line 444: |
Line 767: |
| | | | | |
| | TZRAM | | | TZRAM |
| + | |} |
| + | |
| + | == [[5.0.0]] == |
| + | 5.0.0 modified the address map to have separate .text, .rodata, and .rwdata segments, instead of a single RWX segment. |
| + | |
| + | However, the .rodata and .rwdata segments are both (mistakenly?) mapped R-W. |
| + | |
| + | Because the same L3 page is shared for all mappings, this required modifying segment layout significantly to prevent clashes. |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Vmem |
| + | ! Physmem |
| + | ! Size |
| + | ! Descriptor ORR-value |
| + | ! Description |
| + | |- |
| + | | 0x7C010000 |
| + | | 0x7C010000 |
| + | | 0x10000 |
| + | | 0x300 |
| + | | TZRAM Identity RWX (for init) |
| + | |- |
| + | | 0x40020000 |
| + | | 0x40020000 |
| + | | 0x20000 |
| + | | 0x300 |
| + | | IRAM Identity RWX (for init) |
| + | |- |
| + | | 0x1F0080000 |
| + | | 0x50041000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | ARM Interrupt Distributor |
| + | |- |
| + | | 0x1F0082000 |
| + | | 0x50042000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Interrupt Controller Physical CPU |
| + | |- |
| + | | 0x1F0085000 |
| + | | 0x70006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | UART-A |
| + | |- |
| + | | 0x1F0087000 |
| + | | 0x60006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | Clock and Reset |
| + | |- |
| + | | 0x1F0089000 |
| + | | 0x7000E000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | PMC |
| + | |- |
| + | | 0x1F008B000 |
| + | | 0x60005000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Timers |
| + | |- |
| + | | 0x1F008D000 |
| + | | 0x6000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | System Registers |
| + | |- |
| + | | 0x1F008F000 |
| + | | 0x70012000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Security Engine |
| + | |- |
| + | | 0x1F00AD000 |
| + | | 0x70412000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Undocumented/Not Present (Security Engine for Mariko?) |
| + | |- |
| + | | 0x1F0092000 |
| + | | 0x700F0000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | SYSCTR0 |
| + | |- |
| + | | 0x1F0094000 |
| + | | 0x70019000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Memory Controller |
| + | |- |
| + | | 0x1F0096000 |
| + | | 0x7000F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Fuse Registers |
| + | |- |
| + | | 0x1F0098000 |
| + | | 0x70000000 |
| + | | 0x4000 |
| + | | 0x40000000000304 |
| + | | MISC Registers |
| + | |- |
| + | | 0x1F009D000 |
| + | | 0x60007000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Flow Controller |
| + | |- |
| + | | 0x1F009F000 |
| + | | 0x40002000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | IRAM |
| + | |- |
| + | | 0x1F00A1000 |
| + | | 0x7000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | I2C-5 |
| + | |- |
| + | | 0x1F00A3000 |
| + | | 0x6000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | GPIO-1 |
| + | |- |
| + | | 0x1F00A5000 |
| + | | 0x7000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | I2C |
| + | |- |
| + | | 0x1F00A7000 |
| + | | 0x6000F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | BPMP Exception Vectors |
| + | |- |
| + | | 0x1F00A9000 |
| + | | 0x7001C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | MC0 |
| + | |- |
| + | | 0x1F00AB000 |
| + | | 0x7001D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | MC1 |
| + | |- |
| + | | 0x1F0100000 |
| + | | 0x7C010000 |
| + | | 0x10000 |
| + | | 0x40000000000380 |
| + | | TZRAM (R-- for context save) |
| + | |- |
| + | | 0x1F0140000 |
| + | | 0x7C012000 |
| + | | 0x9000 |
| + | | 0x300 |
| + | | TZRAM (R-X .text) |
| + | |- |
| + | | 0x1F0149000 |
| + | | 0x7C01B000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (RW- .rodata) |
| + | |- |
| + | | 0x1F014A000 |
| + | | 0x7C01C000 |
| + | | 0x2000 |
| + | | 0x40000000000300 |
| + | | TZRAM (RW- .rwdata) |
| + | |- |
| + | | 0x1F01A0000 |
| + | | 0x40020000 |
| + | | 0x10000 |
| + | | 0x40000000000324 |
| + | | IRAM (RW- for context save) |
| + | |- |
| + | | 0x1F01B0000 |
| + | | 0x40003000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | IRAM (BPMP firmware destination) |
| + | |- |
| + | | 0x1F01C7000 |
| + | | 0x8000F000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | DRAM (SE Context Save destination) |
| + | |- |
| + | | 0x1F01E0000 |
| + | | 0x7C010000 |
| + | | 0x2000 |
| + | | 0x300 |
| + | | TZRAM (RWX pk2ldr for init) |
| + | |- |
| + | | 0x1F01F4000 |
| + | | X |
| + | | 0x1000 |
| + | | 0x40000000000723 |
| + | | DRAM (SPL .bss buffer visible to the Security Engine) |
| + | |- |
| + | | 0x1F01F6000 |
| + | | 0x7C010000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks) |
| + | |- |
| + | | 0x1F01F8000 |
| + | | 0x7C011000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks) |
| + | |- |
| + | | 0x1F01FA000 |
| + | | 0x7C01D000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks, warmboot crt0) |
| + | |- |
| + | | 0x1F01FC000 |
| + | | 0x7C01E000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (L2 Page Table) |
| + | |- |
| + | | 0x1F01FE000 |
| + | | 0x7C01F000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (L3 Page Table) |
| + | |- |
| + | |} |
| + | |
| + | == [[6.0.0]] == |
| + | 6.0.0 reduced the .rwdata segment to one page (previously 2). |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Vmem |
| + | ! Physmem |
| + | ! Size |
| + | ! Descriptor ORR-value |
| + | ! Description |
| + | |- |
| + | | 0x7C010000 |
| + | | 0x7C010000 |
| + | | 0x10000 |
| + | | 0x300 |
| + | | TZRAM Identity RWX (for init) |
| + | |- |
| + | | 0x40020000 |
| + | | 0x40020000 |
| + | | 0x20000 |
| + | | 0x300 |
| + | | IRAM Identity RWX (for init) |
| + | |- |
| + | | 0x1F0080000 |
| + | | 0x50041000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | ARM Interrupt Distributor |
| + | |- |
| + | | 0x1F0082000 |
| + | | 0x50042000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Interrupt Controller Physical CPU |
| + | |- |
| + | | 0x1F0085000 |
| + | | 0x70006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | UART-A |
| + | |- |
| + | | 0x1F0087000 |
| + | | 0x60006000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | Clock and Reset |
| + | |- |
| + | | 0x1F0089000 |
| + | | 0x7000E000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | PMC |
| + | |- |
| + | | 0x1F008B000 |
| + | | 0x60005000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Timers |
| + | |- |
| + | | 0x1F008D000 |
| + | | 0x6000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | System Registers |
| + | |- |
| + | | 0x1F008F000 |
| + | | 0x70012000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Security Engine |
| + | |- |
| + | | 0x1F00AD000 |
| + | | 0x70412000 |
| + | | 0x2000 |
| + | | 0x40000000000304 |
| + | | Undocumented/Not Present (Security Engine for Mariko?) |
| + | |- |
| + | | 0x1F0092000 |
| + | | 0x700F0000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | SYSCTR0 |
| + | |- |
| + | | 0x1F0094000 |
| + | | 0x70019000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Memory Controller |
| + | |- |
| + | | 0x1F0096000 |
| + | | 0x7000F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Fuse Registers |
| + | |- |
| + | | 0x1F0098000 |
| + | | 0x70000000 |
| + | | 0x4000 |
| + | | 0x40000000000304 |
| + | | MISC Registers |
| + | |- |
| + | | 0x1F009D000 |
| + | | 0x60007000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | Flow Controller |
| + | |- |
| + | | 0x1F009F000 |
| + | | 0x40002000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | IRAM |
| + | |- |
| + | | 0x1F00A1000 |
| + | | 0x7000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | I2C-5 |
| + | |- |
| + | | 0x1F00A3000 |
| + | | 0x6000D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | GPIO-1 |
| + | |- |
| + | | 0x1F00A5000 |
| + | | 0x7000C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | I2C |
| + | |- |
| + | | 0x1F00A7000 |
| + | | 0x6000F000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | BPMP Exception Vectors |
| + | |- |
| + | | 0x1F00A9000 |
| + | | 0x7001C000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | MC0 |
| + | |- |
| + | | 0x1F00AB000 |
| + | | 0x7001D000 |
| + | | 0x1000 |
| + | | 0x40000000000304 |
| + | | MC1 |
| + | |- |
| + | | 0x1F0100000 |
| + | | 0x7C010000 |
| + | | 0x10000 |
| + | | 0x40000000000380 |
| + | | TZRAM (R-- for context save) |
| + | |- |
| + | | 0x1F0140000 |
| + | | 0x7C012000 |
| + | | 0x9000 |
| + | | 0x300 |
| + | | TZRAM (R-X .text) |
| + | |- |
| + | | 0x1F0149000 |
| + | | 0x7C01B000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (RW- .rodata) |
| + | |- |
| + | | 0x1F014A000 |
| + | | 0x7C01C000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (RW- .rwdata) |
| + | |- |
| + | | 0x1F01A0000 |
| + | | 0x40020000 |
| + | | 0x10000 |
| + | | 0x40000000000324 |
| + | | IRAM (RW- for context save) |
| + | |- |
| + | | 0x1F01B0000 |
| + | | 0x40003000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | IRAM (BPMP firmware destination) |
| + | |- |
| + | | 0x1F01C7000 |
| + | | 0x8000F000 |
| + | | 0x1000 |
| + | | 0x40000000000324 |
| + | | DRAM (SE Context Save destination) |
| + | |- |
| + | | 0x1F01E0000 |
| + | | 0x7C010000 |
| + | | 0x2000 |
| + | | 0x300 |
| + | | TZRAM (RWX pk2ldr for init) |
| + | |- |
| + | | 0x1F01F4000 |
| + | | X |
| + | | 0x1000 |
| + | | 0x40000000000723 |
| + | | DRAM (SPL .bss buffer visible to the Security Engine) |
| + | |- |
| + | | 0x1F01F6000 |
| + | | 0x7C010000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks) |
| + | |- |
| + | | 0x1F01F8000 |
| + | | 0x7C011000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks) |
| + | |- |
| + | | 0x1F01FA000 |
| + | | 0x7C01D000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (stacks, warmboot crt0) |
| + | |- |
| + | | 0x1F01FC000 |
| + | | 0x7C01E000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (L2 Page Table) |
| + | |- |
| + | | 0x1F01FE000 |
| + | | 0x7C01F000 |
| + | | 0x1000 |
| + | | 0x40000000000300 |
| + | | TZRAM (L3 Page Table) |
| + | |- |
| + | |} |
| + | |
| + | = IRAM = |
| + | == BIT == |
| + | During boot, the BootROM saves the BCT in IRAM at address 0x40000100. The preceding 0x100 bytes (IRAM memory range from 0x40000000 to 0x40000100) contain a structure called BIT (Boot Info Table) which encapsulates the BCT in IRAM and is initialized by the BootROM as follows: |
| + | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Offset |
| + | ! Size |
| + | ! Field |
| + | ! Description |
| + | |- |
| + | | 0x00 |
| + | | 0x04 |
| + | | br_version |
| + | | Set to 0x00210001 (BOOTDATA_VERSION_T210). |
| + | |- |
| + | | 0x04 |
| + | | 0x04 |
| + | | bd_version |
| + | | Set to 0x00210001 (BOOTDATA_VERSION_T210). |
| + | |- |
| + | | 0x08 |
| + | | 0x04 |
| + | | rcm_version |
| + | | Set to 0x00210001 (BOOTDATA_VERSION_T210). |
| + | |- |
| + | | 0x0C |
| + | | 0x04 |
| + | | boot_type |
| + | | |
| + | BOOT_TYPE_COLD = 1 |
| + | BOOT_TYPE_RECOVERY = 2 |
| + | BOOT_TYPE_UART = 3 |
| + | BOOT_TYPE_EXIT_RCM = 4 |
| + | |- |
| + | | 0x10 |
| + | | 0x04 |
| + | | unk0 |
| + | | Set to 0x05 on coldboot. |
| + | |- |
| + | | 0x14 |
| + | | 0x04 |
| + | | boot_device_type |
| + | | |
| + | |- |
| + | | 0x18 |
| + | | 0x04 |
| + | | boot_start_time |
| + | | Value from TIMERUS_CNTR_1US when the BootROM enters its main function. |
| + | |- |
| + | | 0x1C |
| + | | 0x04 |
| + | | bootrom_lockdown_value |
| + | | This is the value that gets written into SB_CSR before nvboot. (0x10) |
| + | |- |
| + | | 0x20 |
| + | | 0x04 |
| + | | boot_read_bct_time |
| + | | Time spent reading the BCT. |
| + | |- |
| + | | 0x24 |
| + | | 0x04 |
| + | | boot_parse_bootloader_time |
| + | | Time spent parsing the bootloader info from the BCT. |
| + | |- |
| + | | 0x28 |
| + | | 0x04 |
| + | | osc_freq |
| + | | Value from CLK_RST_CONTROLLER_OSC_CTRL. |
| + | |- |
| + | | 0x2C |
| + | | 0x01 |
| + | | is_boot_device_loaded |
| + | | Set to 1 after the boot device is initialized. |
| + | |- |
| + | | 0x2D |
| + | | 0x01 |
| + | | is_sdram_configured |
| + | | Set to 1 after the SDRAM parameters are parsed. |
| + | |- |
| + | | 0x2E |
| + | | 0x01 |
| + | | is_forced_rcm_pmc |
| + | | Set to 1 if bit 2 was set in APBDEV_PMC_SCRATCH0. |
| + | |- |
| + | | 0x2F |
| + | | 0x01 |
| + | | is_enable_fail_back_pmc |
| + | | Set to 1 if bit 4 was set in APBDEV_PMC_SCRATCH0. |
| + | |- |
| + | | 0x30 |
| + | | 0x02 |
| + | | is_bootloader_version_mismatch |
| + | | Set to 1 if the bootloaders have different versions in the BCT. |
| + | |- |
| + | | 0x32 |
| + | | 0x02 |
| + | | is_bct_valid |
| + | | Set to 1 if the BCT was parsed successfully. |
| + | |- |
| + | | 0x34 |
| + | | 0x04 |
| + | | unk2 |
| + | | |
| + | |- |
| + | | 0x38 |
| + | | 0x04 |
| + | | unk3 |
| + | | |
| + | |- |
| + | | 0x3C |
| + | | 0x04 |
| + | | active_bootloader_idx |
| + | | Value from 0 to 3 that represents which bootloader is active. |
| + | |- |
| + | | 0x40 |
| + | | 0x04 |
| + | | bct_start_block |
| + | | Block number where the BCT was found. |
| + | |- |
| + | | 0x44 |
| + | | 0x04 |
| + | | bct_start_page |
| + | | Page number where the BCT was found. |
| + | |- |
| + | | 0x48 |
| + | | 0x04 |
| + | | bct_size |
| + | | Size of the BCT in IRAM (0x2800). |
| + | |- |
| + | | 0x4C |
| + | | 0x04 |
| + | | bct_ptr |
| + | | Pointer to the BCT in IRAM (0x40000100). |
| + | |- |
| + | | 0x50 |
| + | | 0x18*4 |
| + | | bootloader_headers[4] |
| + | | |
| + | {| class="wikitable" border="1" |
| + | |- |
| + | ! Offset |
| + | ! Size |
| + | ! Field |
| + | |- |
| + | | 0x00 |
| + | | 0x04 |
| + | | is_active |
| + | |- |
| + | | 0x04 |
| + | | 0x04 |
| + | | bootloader_start_block |
| + | |- |
| + | | 0x08 |
| + | | 0x04 |
| + | | bootloader_start_page |
| + | |- |
| + | | 0x0C |
| + | | 0x04 |
| + | | bootloader_length |
| + | |- |
| + | | 0x10 |
| + | | 0x04 |
| + | | bootloader_signed_start |
| + | |- |
| + | | 0x14 |
| + | | 0x04 |
| + | | bootloader_signature |
| + | |} |
| + | |- |
| + | | 0xB0 |
| + | | 0x40 |
| + | | boot_device_info |
| + | | Structure to hold boot device parameters. |
| + | |- |
| + | | 0xF0 |
| + | | 0x04 |
| + | | bct_end_ptr |
| + | | Pointer to the end of the BCT in IRAM (0x40002900). |
| + | |- |
| + | | 0xF4 |
| + | | 0x0C |
| + | | padding |
| + | | Must be empty. |
| |} | | |} |
| | | |
Line 475: |
Line 1,458: |
| | | |
| TTBR1: | | 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. | + | * vmem 0xFFFFFFF800000000 is mapped to physmem 0x80000000. Similar to above, except tmp=0 due to wrap-around, etc. This also has usermode/kernel XN enabled in the descriptor ORR-value. 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>}" | | ** "endaddr = 0x3fffffff + (<size from above> | 0xfffffff800000000); enaddr = (endaddr & 0xffffffffc0000000)-1; if(endaddr >= 0xfffffff800000001){<map mem>}" |
| | | |