Difference between revisions of "NPDM"
(→ACID) |
(Update MemoryMap bits and FsAccessControl structure) |
||
(40 intermediate revisions by 10 users not shown) | |||
Line 9: | Line 9: | ||
| 0x0 | | 0x0 | ||
| 0x80 | | 0x80 | ||
− | | META | + | | [[#META|META]] |
|- | |- | ||
| 0x80 | | 0x80 | ||
| <Varies> | | <Varies> | ||
− | | ACID | + | | [[#ACID|ACID]] |
|- | |- | ||
| <See META> | | <See META> | ||
| <See META> | | <See META> | ||
− | | ACI0 | + | | [[#ACI0|ACI0]] |
|} | |} | ||
Line 29: | Line 29: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magicnum "META" |
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | | + | | 0x4 |
− | | | + | | [9.0.0+] AcidSignatureKeyGeneration (0 or 1) |
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | | + | | 0x4 |
− | | | + | | Reserved |
|- | |- | ||
| 0xC | | 0xC | ||
| 0x1 | | 0x1 | ||
− | | Flags | + | | [[#Flags|Flags]] |
+ | |- | ||
+ | | 0xD | ||
+ | | 0x1 | ||
+ | | Reserved | ||
|- | |- | ||
| 0xE | | 0xE | ||
| 0x1 | | 0x1 | ||
− | | | + | | [[#MainThreadPriority|MainThreadPriority]] |
|- | |- | ||
| 0xF | | 0xF | ||
| 0x1 | | 0x1 | ||
− | | | + | | MainThreadCoreNumber |
|- | |- | ||
| 0x10 | | 0x10 | ||
− | | | + | | 0x4 |
− | | | + | | Reserved |
+ | |- | ||
+ | | 0x14 | ||
+ | | 0x4 | ||
+ | | [3.0.0+] [[#SystemResourceSize|SystemResourceSize]] | ||
|- | |- | ||
| 0x18 | | 0x18 | ||
| 0x4 | | 0x4 | ||
− | | | + | | [[#Version|Version]] |
|- | |- | ||
| 0x1C | | 0x1C | ||
| 0x4 | | 0x4 | ||
− | | | + | | [[#MainThreadStackSize|MainThreadStackSize]] |
|- | |- | ||
| 0x20 | | 0x20 | ||
− | | | + | | 0x10 |
− | | | + | | Name (usually/always "Application") |
+ | |- | ||
+ | | 0x30 | ||
+ | | 0x10 | ||
+ | | ProductCode (usually/always all zeroes) | ||
+ | |- | ||
+ | | 0x40 | ||
+ | | 0x30 | ||
+ | | Reserved | ||
|- | |- | ||
| 0x70 | | 0x70 | ||
| 0x4 | | 0x4 | ||
− | | [[#ACI0]] | + | | [[#ACI0|AciOffset]] |
|- | |- | ||
| 0x74 | | 0x74 | ||
| 0x4 | | 0x4 | ||
− | | [[#ACI0]] | + | | [[#ACI0|AciSize]] |
|- | |- | ||
| 0x78 | | 0x78 | ||
| 0x4 | | 0x4 | ||
− | | [[#ACID]] | + | | [[#ACID|AcidOffset]] |
|- | |- | ||
| 0x7C | | 0x7C | ||
| 0x4 | | 0x4 | ||
− | | [[#ACID]] | + | | [[#ACID|AcidSize]] |
+ | |} | ||
+ | |||
+ | == Flags == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | Is64BitInstruction | ||
+ | |- | ||
+ | | 1-3 | ||
+ | | ProcessAddressSpace (0x00 = AddressSpace32Bit, 0x01 = AddressSpace64BitOld, 0x02 = AddressSpace32BitNoReserved, 0x03 = AddressSpace64Bit) | ||
+ | |- | ||
+ | | 4 | ||
+ | | OptimizeMemoryAllocation | ||
|} | |} | ||
+ | |||
+ | == MainThreadPriority == | ||
+ | Ranges from 0 to 0x3F. | ||
+ | |||
+ | == SystemResourceSize == | ||
+ | This is the size of PersonalMmHeap. Maximum size as of 5.0.0 is 0x1FE00000. | ||
+ | |||
+ | == Version == | ||
+ | 0 for all titles. | ||
+ | |||
+ | [8.1.0+] Now set to 1 for certain titles. | ||
+ | |||
+ | [9.0.0+] Now set to a proper version field for all titles. | ||
+ | |||
+ | == MainThreadStackSize == | ||
+ | Must be aligned to 0x1000. | ||
+ | |||
+ | In non-nspwn scenarios, values of 0 can also rarely break in Horizon. This might be something auto-adapting or a security feature of some sort? | ||
= ACID = | = ACID = | ||
Line 93: | Line 143: | ||
| 0x0 | | 0x0 | ||
| 0x100 | | 0x100 | ||
− | | RSA-2048 signature | + | | RSA-2048 signature over the data starting at 0x100 with the size field from 0x204 |
|- | |- | ||
| 0x100 | | 0x100 | ||
| 0x100 | | 0x100 | ||
− | | RSA-2048 public key | + | | RSA-2048 public key for the second [[NCA_Format|NCA]] signature |
|- | |- | ||
| 0x200 | | 0x200 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magicnum "ACID" |
|- | |- | ||
| 0x204 | | 0x204 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Size |
|- | |- | ||
| 0x208 | | 0x208 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Reserved |
|- | |- | ||
| 0x20C | | 0x20C | ||
| 0x4 | | 0x4 | ||
− | | | + | | [[#Flags_2|Flags]] |
|- | |- | ||
| 0x210 | | 0x210 | ||
| 0x8 | | 0x8 | ||
− | | | + | | ProgramIdMin |
|- | |- | ||
| 0x218 | | 0x218 | ||
| 0x8 | | 0x8 | ||
− | | | + | | ProgramIdMax |
|- | |- | ||
| 0x220 | | 0x220 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#FsAccessControl|FsAccessControlOffset]] |
|- | |- | ||
| 0x224 | | 0x224 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#FsAccessControl|FsAccessControlSize]] |
|- | |- | ||
| 0x228 | | 0x228 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#SrvAccessControl|SrvAccessControlOffset]] |
|- | |- | ||
| 0x22C | | 0x22C | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#SrvAccessControl|SrvAccessControlSize]] |
|- | |- | ||
| 0x230 | | 0x230 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#KernelCapability|KernelCapabilityOffset]] |
|- | |- | ||
| 0x234 | | 0x234 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#KernelCapability|KernelCapabilitySize]] |
|- | |- | ||
| 0x238 | | 0x238 | ||
| 0x8 | | 0x8 | ||
− | | | + | | Reserved |
+ | |} | ||
+ | |||
+ | == Flags == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 0 | ||
+ | | ProductionFlag | ||
+ | |- | ||
+ | | 1 | ||
+ | | UnqualifiedApproval | ||
+ | |- | ||
+ | | 2-3 | ||
+ | | [5.0.0+ ] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) | ||
|} | |} | ||
+ | |||
+ | MemoryRegion is set to Application for "starter" and NonSecureSystem for "nvservices". | ||
= ACI0 = | = ACI0 = | ||
Line 161: | Line 229: | ||
| 0x0 | | 0x0 | ||
| 0x4 | | 0x4 | ||
− | | | + | | Magicnum "ACI0" |
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0xC | | 0xC | ||
− | | | + | | Reserved |
|- | |- | ||
| 0x10 | | 0x10 | ||
| 0x8 | | 0x8 | ||
− | | | + | | ProgramId |
|- | |- | ||
| 0x18 | | 0x18 | ||
| 0x8 | | 0x8 | ||
− | | | + | | Reserved |
|- | |- | ||
| 0x20 | | 0x20 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#FsAccessControl|FsAccessControlOffset]] |
|- | |- | ||
| 0x24 | | 0x24 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#FsAccessControl|FsAccessControlSize]] |
|- | |- | ||
| 0x28 | | 0x28 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#SrvAccessControl|SrvAccessControlOffset]] |
|- | |- | ||
| 0x2C | | 0x2C | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#SrvAccessControl|SrvAccessControlSize]] |
|- | |- | ||
| 0x30 | | 0x30 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#KernelCapability|KernelCapabilityOffset]] |
|- | |- | ||
| 0x34 | | 0x34 | ||
| 0x4 | | 0x4 | ||
− | | [[# | + | | [[#KernelCapability|KernelCapabilitySize]] |
|- | |- | ||
| 0x38 | | 0x38 | ||
| 0x8 | | 0x8 | ||
− | | | + | | Reserved |
|} | |} | ||
− | = | + | = FsAccessControl = |
− | + | For [[#ACID|ACID]] this is a simple descriptor as follows: | |
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 214: | Line 282: | ||
| 0x0 | | 0x0 | ||
| 0x1 | | 0x1 | ||
− | | Version | + | | Version (always 1, must be non-zero) |
|- | |- | ||
| 0x1 | | 0x1 | ||
+ | | 0x1 | ||
+ | | ContentOwnerIdCount | ||
+ | |- | ||
+ | | 0x2 | ||
+ | | 0x1 | ||
+ | | SaveDataOwnerIdCount | ||
+ | |- | ||
| 0x3 | | 0x3 | ||
+ | | 0x1 | ||
| Padding | | Padding | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
| 0x8 | | 0x8 | ||
− | | | + | | [[#FsAccessFlag|FsAccessFlag]] |
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | 0x8 |
− | | | + | | ContentOwnerIdMin |
+ | |- | ||
+ | | 0x14 | ||
+ | | 0x8 | ||
+ | | ContentOwnerIdMax | ||
|- | |- | ||
− | | | + | | 0x1C |
− | | | + | | 0x8 |
− | | | + | | SaveDataOwnerIdMin |
|- | |- | ||
− | | | + | | 0x24 |
− | | | + | | 0x8 |
− | | | + | | SaveDataOwnerIdMax |
|- | |- | ||
− | | | + | | 0x2C |
− | | | + | | 0x8 * ContentOwnerIdCount |
− | | | + | | ContentOwnerIds |
|- | |- | ||
+ | | Variable | ||
+ | | 0x8 * SaveDataOwnerIdCount | ||
+ | | SaveDataOwnerIds | ||
|} | |} | ||
− | + | For [[#ACI0|ACI0]] this embeds data as follows: | |
− | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 252: | Line 334: | ||
| 0x0 | | 0x0 | ||
| 0x1 | | 0x1 | ||
− | | Version | + | | Version (always 1, must be non-zero) |
|- | |- | ||
| 0x1 | | 0x1 | ||
Line 260: | Line 342: | ||
| 0x4 | | 0x4 | ||
| 0x8 | | 0x8 | ||
− | | | + | | [[#FsAccessFlag|FsAccessFlag]] |
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | 0x4 |
− | | | + | | ContentOwnerInfoOffset |
+ | |- | ||
+ | | 0x10 | ||
+ | | 0x4 | ||
+ | | ContentOwnerInfoSize | ||
+ | |- | ||
+ | | 0x14 | ||
+ | | 0x4 | ||
+ | | SaveDataOwnerInfoOffset | ||
+ | |- | ||
+ | | 0x18 | ||
+ | | 0x4 | ||
+ | | SaveDataOwnerInfoSize | ||
+ | |- | ||
+ | | 0x1C | ||
+ | | 0x4 | ||
+ | | (Optional) ContentOwnerIdCount | ||
+ | |- | ||
+ | | 0x1C | ||
+ | | 0x8 * ContentOwnerIdCount | ||
+ | | ContentOwnerIds | ||
+ | |- | ||
+ | | Variable | ||
+ | | 0x4 | ||
+ | | SaveDataOwnerIdCount | ||
+ | |- | ||
+ | | Variable | ||
+ | | 0x1 * SaveDataOwnerIdCount | ||
+ | | Accessibilities (1=Read, 2=Write, 3=ReadWrite) | ||
+ | |- | ||
+ | | Variable (padded to nearest 4 bytes) | ||
+ | | 0x8 * SaveDataOwnerIdCount | ||
+ | | SaveDataOwnerIds | ||
|} | |} | ||
− | + | == FsAccessFlag == | |
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
− | ! | + | ! Bits |
+ | ! Name | ||
! Description | ! Description | ||
|- | |- | ||
| 0 | | 0 | ||
+ | | ApplicationInfo | ||
| MountContent* is accessible when set. | | MountContent* is accessible when set. | ||
+ | |- | ||
+ | | 1 | ||
+ | | BootModeControl | ||
+ | | | ||
+ | |- | ||
+ | | 2 | ||
+ | | Calibration | ||
+ | | | ||
+ | |- | ||
+ | | 3 | ||
+ | | SystemSaveData | ||
+ | | | ||
+ | |- | ||
+ | | 4 | ||
+ | | GameCard | ||
+ | | | ||
+ | |- | ||
+ | | 5 | ||
+ | | SaveDataBackUp | ||
+ | | | ||
+ | |- | ||
+ | | 6 | ||
+ | | SaveDataManagement | ||
+ | | | ||
+ | |- | ||
+ | | 7 | ||
+ | | BisAllRaw | ||
+ | | | ||
+ | |- | ||
+ | | 8 | ||
+ | | GameCardRaw | ||
+ | | | ||
+ | |- | ||
+ | | 9 | ||
+ | | GameCardPrivate | ||
+ | | | ||
+ | |- | ||
+ | | 10 | ||
+ | | SetTime | ||
+ | | | ||
+ | |- | ||
+ | | 11 | ||
+ | | ContentManager | ||
+ | | | ||
+ | |- | ||
+ | | 12 | ||
+ | | ImageManager | ||
+ | | | ||
+ | |- | ||
+ | | 13 | ||
+ | | CreateSaveData | ||
+ | | | ||
+ | |- | ||
+ | | 14 | ||
+ | | SystemSaveDataManagement | ||
+ | | | ||
+ | |- | ||
+ | | 15 | ||
+ | | BisFileSystem | ||
+ | | | ||
+ | |- | ||
+ | | 16 | ||
+ | | SystemUpdate | ||
+ | | | ||
+ | |- | ||
+ | | 17 | ||
+ | | SaveDataMeta | ||
+ | | | ||
+ | |- | ||
+ | | 18 | ||
+ | | DeviceSaveData | ||
+ | | | ||
+ | |- | ||
+ | | 19 | ||
+ | | SettingsControl | ||
+ | | | ||
+ | |- | ||
+ | | 20 | ||
+ | | SystemData | ||
+ | | | ||
+ | |- | ||
+ | | 21 | ||
+ | | SdCard | ||
+ | | | ||
+ | |- | ||
+ | | 22 | ||
+ | | Host | ||
+ | | | ||
+ | |- | ||
+ | | 23 | ||
+ | | FillBis | ||
+ | | | ||
+ | |- | ||
+ | | 24 | ||
+ | | CorruptSaveData | ||
+ | | | ||
+ | |- | ||
+ | | 25 | ||
+ | | SaveDataForDebug | ||
+ | | | ||
+ | |- | ||
+ | | 26 | ||
+ | | FormatSdCard | ||
+ | | | ||
+ | |- | ||
+ | | 27 | ||
+ | | GetRightsId | ||
+ | | | ||
+ | |- | ||
+ | | 28 | ||
+ | | RegisterExternalKey | ||
+ | | | ||
+ | |- | ||
+ | | 29 | ||
+ | | RegisterUpdatePartition | ||
+ | | | ||
+ | |- | ||
+ | | 30 | ||
+ | | SaveDataTransfer | ||
+ | | | ||
+ | |- | ||
+ | | 31 | ||
+ | | DeviceDetection | ||
+ | | | ||
+ | |- | ||
+ | | 32 | ||
+ | | AccessFailureResolution | ||
+ | | | ||
+ | |- | ||
+ | | 33 | ||
+ | | SaveDataTransferVersion2 | ||
+ | | | ||
|- | |- | ||
| 34 | | 34 | ||
− | | | + | | RegisterProgramIndexMapInfo |
+ | | | ||
+ | |- | ||
+ | | 35 | ||
+ | | CreateOwnSaveData | ||
+ | | | ||
+ | |- | ||
+ | | 36-61 | ||
+ | | Reserved | ||
+ | | | ||
+ | |- | ||
+ | | 62 | ||
+ | | Debug | ||
+ | | See [[SPL_services#GetConfig|here]]. | ||
|- | |- | ||
| 63 | | 63 | ||
− | | Enables access to everything: all [[Filesystem_services#Permissions|permission | + | | FullPermission |
+ | | Enables access to everything: all [[Filesystem_services#Permissions|permission types]] which check a bitmask have this bit set. | ||
|} | |} | ||
− | + | Controls the [[Filesystem_services#Permissions|filesystem permissions]]. | |
Web-applets permissions: | Web-applets permissions: | ||
Line 290: | Line 552: | ||
= Service Access Control = | = Service Access Control = | ||
− | + | {| class="wikitable" border="1" | |
− | + | |- | |
− | + | ! Bits | |
+ | ! Description | ||
+ | |- | ||
+ | | 0-2 | ||
+ | | Size (length of the service-name without null-terminator minus 1) | ||
+ | |- | ||
+ | | 7 | ||
+ | | IsServer (service is allowed to be registered) | ||
+ | |- | ||
+ | | Variable | ||
+ | | Name | ||
+ | |} | ||
− | + | This is a list of [[Services_API|service]]-name strings which the title has access to. | |
− | + | The service name string starts after the first byte and supports the wildcard <code>*</code> character. | |
− | |||
− | The service string | ||
− | |||
− | |||
− | |||
+ | = KernelCapability = | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Pattern of lower bits | ! Pattern of lower bits | ||
! Lowest clear bitmask/bit | ! Lowest clear bitmask/bit | ||
− | ! | + | ! Description |
− | |||
|- | |- | ||
| <code>0bxxxxxxxxxxxx0111</code> | | <code>0bxxxxxxxxxxxx0111</code> | ||
| Bit3 | | Bit3 | ||
− | | | + | | [[#ThreadInfo]] |
− | |||
|- | |- | ||
| <code>0bxxxxxxxxxxx01111</code> | | <code>0bxxxxxxxxxxx01111</code> | ||
| Bit4 | | Bit4 | ||
− | | | + | | [[#EnableSystemCalls]] |
− | |||
|- | |- | ||
| <code>0bxxxxxxxxx0111111</code> | | <code>0bxxxxxxxxx0111111</code> | ||
| Bit6 | | Bit6 | ||
− | | | + | | [[#MemoryMap]] |
− | |||
|- | |- | ||
| <code>0bxxxxxxxx01111111</code> | | <code>0bxxxxxxxx01111111</code> | ||
| Bit7 | | Bit7 | ||
− | | | + | | [[#IoMemoryMap]] |
− | | | + | |- |
+ | | <code>0bxxxxx01111111111</code> | ||
+ | | Bit10 | ||
+ | | [8.0.0+] [[#MemoryRegionMap]] | ||
|- | |- | ||
| <code>0bxxxx011111111111</code> | | <code>0bxxxx011111111111</code> | ||
| Bit11 | | Bit11 | ||
− | | | + | | [[#EnableInterrupts]] |
− | |||
|- | |- | ||
| <code>0bxx01111111111111</code> | | <code>0bxx01111111111111</code> | ||
| Bit13 | | Bit13 | ||
− | | | + | | [[#MiscParams]] |
− | |||
|- | |- | ||
| <code>0bx011111111111111</code> | | <code>0bx011111111111111</code> | ||
| Bit14 | | Bit14 | ||
− | | | + | | [[#KernelVersion]] |
− | |||
|- | |- | ||
| <code>0b0111111111111111</code> | | <code>0b0111111111111111</code> | ||
| Bit15 | | Bit15 | ||
− | | HandleTableSize | + | | [[#HandleTableSize]] |
− | |||
|- | |- | ||
| <code>0b1111111111111111</code> | | <code>0b1111111111111111</code> | ||
| Bit16 | | Bit16 | ||
− | | | + | | [[#MiscFlags]] |
− | |||
|- | |- | ||
| All ones | | All ones | ||
| | | | ||
− | | | + | | Invalid |
− | | | + | |} |
+ | |||
+ | These descriptors are identified by pattern 01..11 in low bits. | ||
+ | |||
+ | == ThreadInfo == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 4-9 | ||
+ | | LowestPriority | ||
+ | |- | ||
+ | | 10-15 | ||
+ | | HighestPriority | ||
+ | |- | ||
+ | | 16-23 | ||
+ | | MinCoreNumber | ||
+ | |- | ||
+ | | 24-31 | ||
+ | | MaxCoreNumber | ||
+ | |} | ||
+ | |||
+ | == EnableSystemCalls == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 5-28 | ||
+ | | SystemCallId | ||
+ | |- | ||
+ | | 29-31 | ||
+ | | Index | ||
+ | |} | ||
+ | |||
+ | == MemoryMap == | ||
+ | MemoryMap entries are stored in pairs. The first pair will contain BeginAddress and PermissionType, while the second pair will contain Size and MappingType. | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 7-30 | ||
+ | | BeginAddress | ||
+ | |- | ||
+ | | 31 | ||
+ | | PermissionType (0=RW, 1=RO) | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 7-26 | ||
+ | | Size | ||
+ | |- | ||
+ | | 27-30 | ||
+ | | Reserved | ||
+ | |- | ||
+ | | 31 | ||
+ | | MappingType (0=Io, 1=Static) | ||
|} | |} | ||
− | == | + | === Restrictions === |
The physaddr range 0x80060000-0x2000000000 is not allowed to be mapped as IO. | The physaddr range 0x80060000-0x2000000000 is not allowed to be mapped as IO. | ||
The physaddr range 0x80000000-0x2000000000 is not allowed to be mapped as Normal. | The physaddr range 0x80000000-0x2000000000 is not allowed to be mapped as Normal. | ||
− | [2.0.0 | + | [2.0.0-4.1.0] The range for IO was changed into 0x80060000-0x81D3FFFF. |
− | [2.0.0 | + | [2.0.0-4.1.0] A blacklist was added for IO and Normal mappings: |
* 0x50040000-0x50060000 (ARM, Interrupt Controller) | * 0x50040000-0x50060000 (ARM, Interrupt Controller) | ||
* 0x6000F000 (Exception Vectors) | * 0x6000F000 (Exception Vectors) | ||
Line 376: | Line 701: | ||
* 0x7001D000 (MC1) | * 0x7001D000 (MC1) | ||
− | == | + | [5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied |
+ | |||
+ | == IoMemoryMap == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 8-31 | ||
+ | | BeginAddress | ||
+ | |} | ||
+ | |||
+ | == MemoryRegionMap == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 11-16 | ||
+ | | RegionType0 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) | ||
+ | |- | ||
+ | | 17 | ||
+ | | RegionIsReadOnly0 | ||
+ | |- | ||
+ | | 18-23 | ||
+ | | RegionType1 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) | ||
+ | |- | ||
+ | | 24 | ||
+ | | RegionIsReadOnly1 | ||
+ | |- | ||
+ | | 25-30 | ||
+ | | RegionType2 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) | ||
+ | |- | ||
+ | | 31 | ||
+ | | RegionIsReadOnly2 | ||
+ | |} | ||
+ | |||
+ | MemoryRegionMap is supported by the kernel but not by [[Loader_services|Loader]]. Thus, only initial processes may possess this capability. | ||
+ | |||
+ | == EnableInterrupts == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 12-21 | ||
+ | | InterruptNumber0 | ||
+ | |- | ||
+ | | 22-31 | ||
+ | | InterruptNumber1 | ||
+ | |} | ||
+ | |||
+ | 0x3FF means empty. | ||
+ | |||
+ | == MiscParams == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 14-16 | ||
+ | | ProgramType (0 = System, 1 = Application, 2 = Applet) | ||
+ | |} | ||
+ | |||
+ | ProgramType is parsed by [[Process Manager services]]. Defaults to 0 if descriptor doesn't exist. Can only run 1 application at a time. | ||
+ | |||
+ | == KernelVersion == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 15-18 | ||
+ | | MinorVersion | ||
+ | |- | ||
+ | | 19-31 | ||
+ | | MajorVersion | ||
+ | |} | ||
+ | |||
+ | This is compared with 0x80000, when less than an error is returned. This is equivalent to comparing the bits starting at bit15 with 0x10. This enforces a minimum required version, not a maximum. | ||
+ | |||
+ | === Versions === | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 388: | Line 794: | ||
|- | |- | ||
| 3.0.2 || 7.4.0 || 3.0.0 | | 3.0.2 || 7.4.0 || 3.0.0 | ||
+ | |- | ||
+ | | 5.0.0 || 9.3.0 || 3.0.0 | ||
+ | |} | ||
+ | |||
+ | == HandleTableSize == | ||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 16-25 | ||
+ | | HandleTableSize | ||
|} | |} | ||
− | + | == MiscFlags == | |
− | + | {| class="wikitable" border="1" | |
− | + | |- | |
+ | ! Bits | ||
+ | ! Description | ||
+ | |- | ||
+ | | 17 | ||
+ | | EnableDebug | ||
+ | |- | ||
+ | | 18 | ||
+ | | ForceDebug | ||
+ | |} |
Revision as of 13:55, 11 March 2020
This is the Switch equivalent of 3DS exheader. This is the file with extension ".npdm" in {Switch ExeFS}. The size of this file varies.
Offset | Size | Description |
---|---|---|
0x0 | 0x80 | META |
0x80 | <Varies> | ACID |
<See META> | <See META> | ACI0 |
META
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Magicnum "META" |
0x4 | 0x4 | [9.0.0+] AcidSignatureKeyGeneration (0 or 1) |
0x8 | 0x4 | Reserved |
0xC | 0x1 | Flags |
0xD | 0x1 | Reserved |
0xE | 0x1 | MainThreadPriority |
0xF | 0x1 | MainThreadCoreNumber |
0x10 | 0x4 | Reserved |
0x14 | 0x4 | [3.0.0+] SystemResourceSize |
0x18 | 0x4 | Version |
0x1C | 0x4 | MainThreadStackSize |
0x20 | 0x10 | Name (usually/always "Application") |
0x30 | 0x10 | ProductCode (usually/always all zeroes) |
0x40 | 0x30 | Reserved |
0x70 | 0x4 | AciOffset |
0x74 | 0x4 | AciSize |
0x78 | 0x4 | AcidOffset |
0x7C | 0x4 | AcidSize |
Flags
Bits | Description |
---|---|
0 | Is64BitInstruction |
1-3 | ProcessAddressSpace (0x00 = AddressSpace32Bit, 0x01 = AddressSpace64BitOld, 0x02 = AddressSpace32BitNoReserved, 0x03 = AddressSpace64Bit) |
4 | OptimizeMemoryAllocation |
MainThreadPriority
Ranges from 0 to 0x3F.
SystemResourceSize
This is the size of PersonalMmHeap. Maximum size as of 5.0.0 is 0x1FE00000.
Version
0 for all titles.
[8.1.0+] Now set to 1 for certain titles.
[9.0.0+] Now set to a proper version field for all titles.
MainThreadStackSize
Must be aligned to 0x1000.
In non-nspwn scenarios, values of 0 can also rarely break in Horizon. This might be something auto-adapting or a security feature of some sort?
ACID
Offset | Size | Description |
---|---|---|
0x0 | 0x100 | RSA-2048 signature over the data starting at 0x100 with the size field from 0x204 |
0x100 | 0x100 | RSA-2048 public key for the second NCA signature |
0x200 | 0x4 | Magicnum "ACID" |
0x204 | 0x4 | Size |
0x208 | 0x4 | Reserved |
0x20C | 0x4 | Flags |
0x210 | 0x8 | ProgramIdMin |
0x218 | 0x8 | ProgramIdMax |
0x220 | 0x4 | FsAccessControlOffset |
0x224 | 0x4 | FsAccessControlSize |
0x228 | 0x4 | SrvAccessControlOffset |
0x22C | 0x4 | SrvAccessControlSize |
0x230 | 0x4 | KernelCapabilityOffset |
0x234 | 0x4 | KernelCapabilitySize |
0x238 | 0x8 | Reserved |
Flags
Bits | Description |
---|---|
0 | ProductionFlag |
1 | UnqualifiedApproval |
2-3 | [5.0.0+ ] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) |
MemoryRegion is set to Application for "starter" and NonSecureSystem for "nvservices".
ACI0
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | Magicnum "ACI0" |
0x4 | 0xC | Reserved |
0x10 | 0x8 | ProgramId |
0x18 | 0x8 | Reserved |
0x20 | 0x4 | FsAccessControlOffset |
0x24 | 0x4 | FsAccessControlSize |
0x28 | 0x4 | SrvAccessControlOffset |
0x2C | 0x4 | SrvAccessControlSize |
0x30 | 0x4 | KernelCapabilityOffset |
0x34 | 0x4 | KernelCapabilitySize |
0x38 | 0x8 | Reserved |
FsAccessControl
For ACID this is a simple descriptor as follows:
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Version (always 1, must be non-zero) |
0x1 | 0x1 | ContentOwnerIdCount |
0x2 | 0x1 | SaveDataOwnerIdCount |
0x3 | 0x1 | Padding |
0x4 | 0x8 | FsAccessFlag |
0xC | 0x8 | ContentOwnerIdMin |
0x14 | 0x8 | ContentOwnerIdMax |
0x1C | 0x8 | SaveDataOwnerIdMin |
0x24 | 0x8 | SaveDataOwnerIdMax |
0x2C | 0x8 * ContentOwnerIdCount | ContentOwnerIds |
Variable | 0x8 * SaveDataOwnerIdCount | SaveDataOwnerIds |
For ACI0 this embeds data as follows:
Offset | Size | Description |
---|---|---|
0x0 | 0x1 | Version (always 1, must be non-zero) |
0x1 | 0x3 | Padding |
0x4 | 0x8 | FsAccessFlag |
0xC | 0x4 | ContentOwnerInfoOffset |
0x10 | 0x4 | ContentOwnerInfoSize |
0x14 | 0x4 | SaveDataOwnerInfoOffset |
0x18 | 0x4 | SaveDataOwnerInfoSize |
0x1C | 0x4 | (Optional) ContentOwnerIdCount |
0x1C | 0x8 * ContentOwnerIdCount | ContentOwnerIds |
Variable | 0x4 | SaveDataOwnerIdCount |
Variable | 0x1 * SaveDataOwnerIdCount | Accessibilities (1=Read, 2=Write, 3=ReadWrite) |
Variable (padded to nearest 4 bytes) | 0x8 * SaveDataOwnerIdCount | SaveDataOwnerIds |
FsAccessFlag
Bits | Name | Description |
---|---|---|
0 | ApplicationInfo | MountContent* is accessible when set. |
1 | BootModeControl | |
2 | Calibration | |
3 | SystemSaveData | |
4 | GameCard | |
5 | SaveDataBackUp | |
6 | SaveDataManagement | |
7 | BisAllRaw | |
8 | GameCardRaw | |
9 | GameCardPrivate | |
10 | SetTime | |
11 | ContentManager | |
12 | ImageManager | |
13 | CreateSaveData | |
14 | SystemSaveDataManagement | |
15 | BisFileSystem | |
16 | SystemUpdate | |
17 | SaveDataMeta | |
18 | DeviceSaveData | |
19 | SettingsControl | |
20 | SystemData | |
21 | SdCard | |
22 | Host | |
23 | FillBis | |
24 | CorruptSaveData | |
25 | SaveDataForDebug | |
26 | FormatSdCard | |
27 | GetRightsId | |
28 | RegisterExternalKey | |
29 | RegisterUpdatePartition | |
30 | SaveDataTransfer | |
31 | DeviceDetection | |
32 | AccessFailureResolution | |
33 | SaveDataTransferVersion2 | |
34 | RegisterProgramIndexMapInfo | |
35 | CreateOwnSaveData | |
36-61 | Reserved | |
62 | Debug | See here. |
63 | FullPermission | Enables access to everything: all permission types which check a bitmask have this bit set. |
Controls the filesystem permissions.
Web-applets permissions:
- "LibAppletWeb" and "LibAppletOff" have same access control: bit0 and bit3 set, and bit62 set.
- Rest of the web-applets: Same as above except bit0 isn't set.
Service Access Control
Bits | Description |
---|---|
0-2 | Size (length of the service-name without null-terminator minus 1) |
7 | IsServer (service is allowed to be registered) |
Variable | Name |
This is a list of service-name strings which the title has access to.
The service name string starts after the first byte and supports the wildcard *
character.
KernelCapability
Pattern of lower bits | Lowest clear bitmask/bit | Description |
---|---|---|
0bxxxxxxxxxxxx0111
|
Bit3 | #ThreadInfo |
0bxxxxxxxxxxx01111
|
Bit4 | #EnableSystemCalls |
0bxxxxxxxxx0111111
|
Bit6 | #MemoryMap |
0bxxxxxxxx01111111
|
Bit7 | #IoMemoryMap |
0bxxxxx01111111111
|
Bit10 | [8.0.0+] #MemoryRegionMap |
0bxxxx011111111111
|
Bit11 | #EnableInterrupts |
0bxx01111111111111
|
Bit13 | #MiscParams |
0bx011111111111111
|
Bit14 | #KernelVersion |
0b0111111111111111
|
Bit15 | #HandleTableSize |
0b1111111111111111
|
Bit16 | #MiscFlags |
All ones | Invalid |
These descriptors are identified by pattern 01..11 in low bits.
ThreadInfo
Bits | Description |
---|---|
4-9 | LowestPriority |
10-15 | HighestPriority |
16-23 | MinCoreNumber |
24-31 | MaxCoreNumber |
EnableSystemCalls
Bits | Description |
---|---|
5-28 | SystemCallId |
29-31 | Index |
MemoryMap
MemoryMap entries are stored in pairs. The first pair will contain BeginAddress and PermissionType, while the second pair will contain Size and MappingType.
Bits | Description |
---|---|
7-30 | BeginAddress |
31 | PermissionType (0=RW, 1=RO) |
Bits | Description |
---|---|
7-26 | Size |
27-30 | Reserved |
31 | MappingType (0=Io, 1=Static) |
Restrictions
The physaddr range 0x80060000-0x2000000000 is not allowed to be mapped as IO. The physaddr range 0x80000000-0x2000000000 is not allowed to be mapped as Normal.
[2.0.0-4.1.0] The range for IO was changed into 0x80060000-0x81D3FFFF.
[2.0.0-4.1.0] A blacklist was added for IO and Normal mappings:
- 0x50040000-0x50060000 (ARM, Interrupt Controller)
- 0x6000F000 (Exception Vectors)
- 0x6001DC00-0x6001E000 (IPATCH)
- 0x7000E000 (RTC/PMC)
- 0x70019000 (MC)
- 0x7001C000 (MC0)
- 0x7001D000 (MC1)
[5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied
IoMemoryMap
Bits | Description |
---|---|
8-31 | BeginAddress |
MemoryRegionMap
Bits | Description |
---|---|
11-16 | RegionType0 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
17 | RegionIsReadOnly0 |
18-23 | RegionType1 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
24 | RegionIsReadOnly1 |
25-30 | RegionType2 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB) |
31 | RegionIsReadOnly2 |
MemoryRegionMap is supported by the kernel but not by Loader. Thus, only initial processes may possess this capability.
EnableInterrupts
Bits | Description |
---|---|
12-21 | InterruptNumber0 |
22-31 | InterruptNumber1 |
0x3FF means empty.
MiscParams
Bits | Description |
---|---|
14-16 | ProgramType (0 = System, 1 = Application, 2 = Applet) |
ProgramType is parsed by Process Manager services. Defaults to 0 if descriptor doesn't exist. Can only run 1 application at a time.
KernelVersion
Bits | Description |
---|---|
15-18 | MinorVersion |
19-31 | MajorVersion |
This is compared with 0x80000, when less than an error is returned. This is equivalent to comparing the bits starting at bit15 with 0x10. This enforces a minimum required version, not a maximum.
Versions
Firmware | Kernel Version | Minimum Allowed |
---|---|---|
1.0.0 | 5.0.0 | 3.0.0 |
2.0.0 | 6.1.0 | 3.0.0 |
3.0.0 | 7.4.0 | 3.0.0 |
3.0.2 | 7.4.0 | 3.0.0 |
5.0.0 | 9.3.0 | 3.0.0 |
HandleTableSize
Bits | Description |
---|---|
16-25 | HandleTableSize |
MiscFlags
Bits | Description |
---|---|
17 | EnableDebug |
18 | ForceDebug |