Changes

Jump to navigation Jump to search
16,993 bytes added ,  23:59, 9 September 2018
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>}"
  
7

edits

Navigation menu