Changes

4,267 bytes added ,  22:54, 6 May 2017
Undo revision 18301 by Neobrain (talk)
This page documents the format of the '''NCCH Extended Header''' (, or '''exheader''' for short).
The exheader, has two sections: * The actual exheader data, containing System Control Info (SCI) and Access Control Info,(ACI);* And a A signed copy of NCCH HDR public key, and exheader Access Control InfoACI. (This version of the Access Control Info ACI is used as limitation to the actual Access Control Info)ACI.
== Main Structure ==
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x200</code>| System Control InfoSCI
|-
| <code>0x200</code>| <code>0x200</code>| Access Control InfoACI
|-
| <code>0x400</code>| <code>0x100</code>| <code>AccessDesc Signature </code> signature (RSA-2048-SHA256)
|-
| <code>0x500</code>| <code>0x100</code>| NCCH Hdr HDR RSA-2048 Public Keypublic key
|-
| <code>0x600</code>| <code>0x200</code>| Access Control Info ACI (For for limitation of first Access Control InfoACI)
|}
The <code>AccessDesc Signature </code> signature covers the ''NCCH Hdr Public Key'' HDR public key and second ''Access Control Info''ACI. The <code>AccessDesc </code> public key is initialised by the bootromboot ROM.
When loading the exheader, [[FIRM|Process9]] compares the exheader data with the data in the accessdesc<code>AccessDesc</code> (note that not everything is compared here). When these don't match, an error is returned. The Process9 code handling this validation was updated with [[6.0.0-11|v6.0]](; the only change in this function seems to be the check for the "Ideal Processorprocessor" field).
== System Control Info ==
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x8</code>| Application Titletitle (default is "CtrApp")
|-
| <code>0x8</code>| <code>0x5</code>| Reserved
|-
| <code>0xD</code>| <code>0x1</code>| Flag (Bit0bit 0: <code>CompressExefsCode</code>, Bit1bit 1: <code>SDApplication</code>)
|-
| <code>0xE</code>| <code>0x2</code>| Remaster Versionversion
|-
| <code>0x10</code>| <code>0xC</code>| Text Code Set Infocode set info
|-
| <code>0x1C</code>| <code>0x4</code>| Stack Sizesize
|-
| <code>0x20</code>| <code>0xC</code>| ReadOnly Code Set InfoRead-only code set info
|-
| <code>0x2C</code>| <code>0x4</code>| Reserved
|-
| <code>0x30</code>| <code>0xC</code>| Data Code Set Infocode set info
|-
| <code>0x3C</code>| <code>0x4</code>| BSS Sizesize
|-
| <code>0x40</code>| <code>0x180 </code> (<code>48*8</code>)| Dependency Module [[Title list#00040130 - System Modules|module]] (Program program ID) Listlist
|-
| <code>0x1C0</code>| <code>0x40</code>| <code>SystemInfo</code>
|}
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| 0x4<code>4</code>| Address
|-
| <code>0x4</code>| 0x4<code>4</code>| Physical region size (in page-multiples)
|-
| <code>0x8</code>| 0x4<code>4</code>| Size (in bytes)
|}
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x8</code>| <code>SaveData </code> Size
|-
| <code>0x8</code>| <code>0x8</code>| Jump ID
|-
| <code>0x10</code>| <code>0x30</code>| Reserved
|}
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x170</code>| [[#ARM11 Local System Capabilities|ARM11 Local System Capabilitieslocal system capabilities]]
|-
| <code>0x170</code>| <code>0x80</code>| [[#ARM11 Kernel Capabilities|ARM11 Kernel Capabilitieskernel capabilities]]
|-
| <code>0x1F0</code>| <code>0x10</code>| [[#ARM9 Access Control|ARM9 Access Controlaccess control]]
|}
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x8</code>| Program ID
|-
| <code>0x8</code>| <code>0x4</code>| Core Version version (The Title ID low of the required [[FIRM]])
|-
| <code>0xC</code>| <code>0x2</code>| [[#Flag1|Flag1]] and [[#Flag2|Flag2]] (both implemented starting from [[8.0.0-18]]).
|-
| <code>0xE</code>| <code>0x1</code>| [[#Flag0|Flag0]]
|-
| <code>0xF</code>| <code>0x1</code>| Priority
|-
| <code>0x10</code>| <code>0x20 </code> (<code>16*2</code>)| Resource Limit Descriptorslimit descriptors. The first byte here controls the maximum allowed [[PMApp:SetAppResourceLimit|<code>CpuTime</code>]].
|-
| <code>0x30</code>| <code>0x20</code>| [[#Storage Info|Storage Infoinfo]]
|-
| <code>0x50</code>| <code>0x100 </code> (<code>32*8</code>)| [[#Service Access Control|Service Access Controlaccess control]]
|-
| <code>0x150</code>| <code>0x10 </code> (<code>2*8</code>)| Extended Service Access Controlservice access control, support for this was implemented with [[9.3.0-21|9.3.0-X]].
|-
| <code>0x160</code>| <code>0xF</code>| Reserved
|-
| <code>0x16F</code>| <code>0x1</code>| Resource Limit Categorylimit category. (0 = <code>APPLICATION</code>, 1 = <code>SYS_APPLET</code>, 2 = <code>LIB_APPLET</code>, 3 = <code>OTHER</code> (sysmodules running under the BASE memregion))
|}
{| class="wikitable" border="1"
|-
! Bits! Description
|-
| <code>0-1</code>| Ideal Processorprocessor
|-
| <code>2-3</code>| Affinity Maskmask
|-
| <code>4-7</code>| System ModeOld3DS system mode
|}
===== Old3DS System Mode ====={| class="wikitable" border="1"|-! Value! Description|-| <code>0</code>| <code>Prod</code> (64MB of usable application memory)|-| <code>1</code>| <code>Undefined</code> (unusable)|-| <code>2</code>| <code>Dev1</code> (96MB of usable application memory)|-| <code>3</code>| <code>Dev2</code> (80MB of usable application memory)|-| <code>4</code>| <code>Dev3</code> (72MB of usable application memory)|-| <code>5</code>| <code>Dev4</code> (32MB of usable application memory)|-| <code>6-7</code>| <code>Undefined</code> Same as <code>Prod</code>?|} In the exheader data, the IdealProcessor ideal processor field is a bit-index, while in the accessdesc <code>AccessDesc</code> the IdealProcessor ideal processor field is a bitmask. When the bit specified by the exheader field is not set in the accessdesc <code>AccessDesc</code> field, an error is returned. " <pre>if((1<<exheaderval) & accessdescval == 0)return error"</pre>
During a FIRM-launch when a titleinfo <code>TitleInfo</code> structure was specified, the field at offset [[FIRM#FIRM_Launch_Parameters|0x400]] in the FIRM-launch parameters is set to the SystemMode of the specified title(, however in some cases other values are written there). With [[8.0.0-18]] NS will now check the output of [[PTM|PTMSYSM]] command <code>0x040A0000</code>, when the output is non-zero and a certain NS state field is value-zero, the following is executed otherwise this is skipped. With that check passed on [[8.0.0-18]], NS will then check (<code>Flag2 & 0xf0xF</code>). When that's is <code>value2</code>, the output value(used for the FIRM-launcher parameter field mentioned above) is set to <code>value7</code>. Otherwise, when that value is non-zero, the output value is set to 6.
==== Flag1 ====
{| class="wikitable" border="1"
|-
! Bits! Description
|-
| <code>0</code>| "<code>EnableL2Cache" </code> (Unknown what this actually does, New3DS-only presumably)
|-
| <code>1</code>| "<code>cpuspeed_804MHz" </code> (Default "cpuspeed" when not set)
|-
| <code>2-7</code>
| Unused
|}
In order for the exheader to have any of the above new bits set, the accessdesc <code>AccessDesc</code> must have the corresponding bit set, otherwise the invalid-exheader error is returned.
Homebrew which runs under a title which has the above <code>cpuspeed </code> flag set, runs much faster on New3DS. It's unknown how exactly the system handles these flags.
When launching titles / perhaps other things with [[APT]], [[NS]] uses [[PTMSYSM:ConfigureNew3DSCPU]] with data which originally came from these flags(; NS does this regardless of what the running 3DS system is). However, due to a bug(?) in NS the value sent to that command is always either 0x0 or 0x3. When calculating that value, the code only ever uses the cpuspeed field, not the cache field: code to actually load and check the value of the cache field appears to be missing.
==== Flag2 ====
{| class="wikitable" border="1"
|-
! Bit! Description
|-
| <code>0-3</code>| ?New3DS system mode
|-
| <code>4-7</code>
| Unused
|}
===== New3DS System Mode ====={| class="wikitable" border="1"|-! Value! Description|-| <code>0</code>| <code>Legacy</code> (use Old3DS system mode)|-| <code>1</code>| <code>Prod</code> (124MB of usable application memory)|-| <code>2</code>| <code>Dev1</code> (178MB of usable application memory)|-| <code>3</code>| <code>Dev2</code> (124MB of usable application memory)|-| <code>4-7</code>| <code>Undefined</code> Same as <code>Prod</code>?|} When in <code>Legacy</code> mode, the actual memory layout is the same as in <code>New3DS Prod</code>, except the available application memory as reported to the application is reduced to the Old3DS size. The exheader value for the above 4-bit New3DS system mode value must be <= to the accessdesc <code>AccessDesc</code> value, otherwise the invalid-exheader error is returned.
==== Storage Info ====
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| 0x8<code>8</code>| Extdata ID
|-
| <code>0x8</code>| 0x8<code>8</code>| System Save Data Idssavedata IDs
|-
| <code>0x10</code>| 0x8<code>8</code>| Storage Accessable Unique Idsaccessible unique IDs
|-
| <code>0x18</code>| 0x7<code>7</code>| File System Access InfoFilesystem access info
|-
| <code>0x1F</code>| 0x1<code>1</code>| Other Attributesattributes
|}
{| class="wikitable" border="1"
|-
! Bit and bitmask! Description
|-
| <code>0</code>, <code>0x1</code>| Category System Applicationsystem application
|-
| <code>1</code>, <code>0x2</code>| Category Hardware Checkhardware check
|-
| <code>2</code>, <code>0x4</code>| Category File System Toolfilesystem tool
|-
| <code>3</code>, <code>0x8</code>| Debug
|-
| <code>4</code>, <code>0x10</code>| TWL Card Backupcard backup
|-
| <code>5</code>, <code>0x20</code>| TWL Nand DataNAND data
|-
| <code>6</code>, <code>0x40</code>| BOSS
|-
| <code>7</code>, <code>0x80</code>| [[FS:OpenArchive|<code>sdmc:/</code>]]
|-
| <code>8</code>, <code>0x100</code>| Core
|-
| <code>9</code>, <code>0x200</code>| [[Flash Filesystem|<code>nand:/ro/</code>]] (Read Only)
|-
| <code>10</code>, <code>0x400</code>| [[Flash Filesystem|<code>nand:/rw/</code>]]
|-
| <code>11</code>, <code>0x800</code>| [[Flash Filesystem|<code>nand:/ro/</code>]] (Write Access)
|-
| <code>12</code>, <code>0x1000</code>| Category System Settingssystem settings
|-
| <code>13</code>, <code>0x2000</code>| Card BoardCardboard
|-
| <code>14</code>, <code>0x4000</code>| Export /Import IVS
|-
| <code>15</code>, <code>0x8000</code>| [[FS:OpenArchive|<code>sdmc:/</code>]] (Write-only)
|-
| <code>16</code>, <code>0x10000</code>| Switch Cleanup cleanup (Introduced in [[3.0.0-5|3.0.0]]?)
|-
| <code>17</code>, <code>0x20000</code>| Save Data Move Savedata move (Introduced in [[5.0.0-11|5.0.0]])
|-
| <code>18</code>, <code>0x40000</code>| Shop (Introduced in [[5.0.0-11|5.0.0]])
|-
| <code>19</code>, <code>0x80000</code>| Shell (Introduced in [[5.0.0-11|5.0.0]])
|-
| <code>20</code>, <code>0x100000</code>| Category HomeMenu home menu (Introduced in [[6.0.0-11|6.0.0]])
|-
| <code>21</code>, <code>0x200000</code>| Seed DB. Introduced in [[9.6.0-24|9.6.0-X]] [[FIRM]]. [[Home Menu]] has this bit set starting with [[9.6.0-24|9.6.0-X]].
|}
====Other Attributes:==== 
{| class="wikitable" border="1"
|-
! Bit! Description
|-
| <code>0</code>| Not use RomFSROMFS
|-
| <code>1</code>| Use Extended Save Data Access. When this is set, the ''Extdata ID'' and ''Storage Accessable Unique Ids'' regions are used to store a total of 6 ''Accessible Save Ids''. Introduced in [[6.0.0-11|6.0.0]]savedata access.
|}
 
When Bit1 is set, the "Extdata ID" and "Storage Accessable Unique IDs" regions are used to store a total of 6 "Accessible Save IDs". Introduced in [[6.0.0-11|6.0.0]].
==== Service Access Control ====
This is the list of [[Services_API|services]] which the process is allowed to access, this is registered with the [[Services|services]] manager. Each service listed in the exheader must be listed in the accessdesc<code>AccessDesc</code>, otherwise the invalid exheader error is returned. The order of the services for exheader/accessdesc <code>AccessDesc</code> doesn't matter. The accessdesc <code>AccessDesc</code> can list services which are not in the exheader, but normally the service-access-control data for exheader/accessdesc <code>AccessDesc</code> are exactly the same.
This list is submitted to [[SRVPM:RegisterProcess]].
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| <code>0x70 </code> (<code>28*4</code>)| Descriptors
|-
| <code>0x70</code>| <code>0x10</code>| Reserved
|}
There are different descriptor types, determined by the number of leading "1"s ones in the binary value representation of bits 20-31. The different types are laid out as follows:
{| class="wikitable" border="1"
|-
! Pattern of bits 20-31! Type! Fields
|-
| <code>0b1110xxxxxxxx</code>| Interrupt info
|
|-
| <code>0b11110xxxxxxx</code>| System call mask| Bits 24-26: System call mask table index; Bits 0-23: mask
|-
| <code>0b1111110xxxxx</code>| Kernel release version| Bits 8-15: Major version; Bits 0-7: Minor version
|-
| <code>0b11111110xxxx</code>| Handle table size| Bits 0-18: size
|-
| <code>0b111111110xxx</code>| [[#ARM11_Kernel_Flags|Kernel flags]]| See below
|-
| <code>0b11111111100x</code>| Mapping static Map addressrange|Describes a memory mapping like the 0b111111111110 descriptor, but an entire range rather than a single page is mapped. Another 0b11111111100x descriptor must follow this one to denote the (exclusive) end of the address range to map.
|-
| <code>0b111111111110</code>| Mapping IO addressMap memory page| Bits 0-19: IO page index to map(virtual address >> 12; the physical address is determined per-page according to [[Memory layout]]); Bit 20: Map read-only (otherwise read-write)
|}
{| class="wikitable" border="1"
|-
! Bit! Description
|-
| <code>0</code>| Allow debug
|-
| <code>1</code>| Force debug
|-
| <code>2</code>| Allow non-alphanum
|-
| <code>3</code>| Shared page writing
|-
| <code>4</code>| Privilege priority
|-
| <code>5</code>| Allow <code>main() </code> args
|-
| <code>6</code>| Shared device memmemory
|-
| <code>7</code>| Runnable on sleep
|-
| <code>8-11</code>| Memory type (1: application, 2: system, 3: base)
|-
| <code>12</code>| [[Memory_layout#NATIVE_FIRM.2FSAFE_MODE_FIRM_Userland_Memory|Special memory]]
|-
| <code>13</code>| Process has access to CPU core 2 (New3DS only)
|}
{| class="wikitable" border="1"
|-
! Offset! Size! Description
|-
| <code>0x0</code>| 0xF<code>15</code>| Descriptors
|-
| <code>0xF</code>| 0x1<code>1</code>| ARM9 Descriptor Version. Originally this value had to be >=2. Starting with [[9.3.0-21|9.3.0-X]] this value has to be either value 2 or value 3.
|}
{| class="wikitable" border="1"
|-
! Bit! Description
|-
| <code>0</code>| Mount [[Flash Filesystem|<code>nand:/</code>]]
|-
| <code>1</code>| Mount [[Flash Filesystem|<code>nand:/ro/</code>]] (Write Access)
|-
| <code>2</code>| Mount [[Flash Filesystem|<code>twln:/</code>]]
|-
| <code>3</code>| Mount [[Flash Filesystem|<code>wnand:/</code>]]
|-
| <code>4</code>| Mount Card card SPI
|-
| <code>5</code>| Use SDIF3
|-
| <code>6</code>| Create Seedseed
|-
| <code>7</code>| Use Card card SPI
|-
| <code>8</code>| SD Application application (Not checked)
|-
| <code>9</code>| Mount [[SD Filesystem|sdmc:/]] (Write Access)
|}
110

edits