NPDM
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 | MoveCacheStorage | |
37-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 |