NPDM: Difference between revisions

Access descriptors...this is basically 3ds, but with type at bottom instead of top
 
(123 intermediate revisions by 19 users not shown)
Line 1: Line 1:
This is the Switch equivalent of 3DS exheader. This is the file with extension ".npdm" in {Switch ExeFS}. The size of this file varies.
This is the Switch equivalent of 3DS [https://www.3dbrew.org/wiki/NCCH/Extended_Header exheader]. This is the file with extension ".npdm" in {Switch ExeFS}. The size of this file varies.


{| class="wikitable" border="1"
{| class="wikitable" border="1"
Line 9: Line 9:
| 0x0
| 0x0
| 0x80
| 0x80
| META
| [[#META|META]]
|-
|-
| 0x80
| 0x80
| 0x200
| RSA-2048 signature, followed a RSA-2048 modulus for [[NCA]] header (like 3DS)
|-
| 0x280
| <Varies>
| <Varies>
| ACID
| [[#ACID|ACID]]
|-
|-
| <See META>
| <See META>
| <See META>
| <See META>
| ACI0
| [[#ACI0|ACI0]]
|}
|}


=META=
= META =
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 33: Line 29:
| 0x0
| 0x0
| 0x4
| 0x4
| Magicnum "META".
| Magic ("META")
|-
| 0x4
| 0x4
| [9.0.0+] SignatureKeyGeneration
|-
| 0x8
| 0x4
| Reserved
|-
| 0xC
| 0x1
| [[#Flags|Flags]]
|-
| 0xD
| 0x1
| Reserved
|-
| 0xE
| 0x1
| [[#MainThreadPriority|MainThreadPriority]]
|-
| 0xF
| 0x1
| MainThreadCoreNumber
|-
| 0x10
| 0x4
| Reserved
|-
| 0x14
| 0x4
| [3.0.0+] [[#SystemResourceSize|SystemResourceSize]]
|-
| 0x18
| 0x4
| [[#Version|Version]]
|-
| 0x1C
| 0x4
| [[#MainThreadStackSize|MainThreadStackSize]]
|-
|-
| 0x20
| 0x20
| ?
| 0x10
| Name string
| Name (usually/always "Application")
|-
| 0x30
| 0x10
| ProductCode (usually/always all zeroes)
|-
| 0x40
| 0x30
| Reserved
|-
|-
| 0x70
| 0x70
| 0x4
| 0x4
| Absolute offset for ACI0.
| [[#ACI0|AciOffset]]
|-
|-
| 0x74
| 0x74
| 0x4
| 0x4
| Size of ACI0.
| [[#ACI0|AciSize]]
|-
|-
| 0x78
| 0x78
| 0x4
| 0x4
| Absolute offset of the RSA signature.
| [[#ACID|AcidOffset]]
|-
|-
| 0x7C
| 0x7C
| 0x4
| 0x4
| Size used with the above offset. Offset+size is normally ACI0_start-8.
| [[#ACID|AcidSize]]
|}
 
== Flags ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 0
| Is64BitInstruction
|-
| 1-3
| ProcessAddressSpace (0x00 = AddressSpace32Bit, 0x01 = AddressSpace64BitOld, 0x02 = AddressSpace32BitNoReserved, 0x03 = AddressSpace64Bit)
|-
| 4
| [7.0.0+] OptimizeMemoryAllocation
|-
| 5
| [11.0.0+] DisableDeviceAddressSpaceMerge
|-
| 6
| [18.0.0+] EnableAliasRegionExtraSize
|-
| 7
| [19.0.0+] PreventCodeReads
|}
 
== MainThreadPriority ==
Ranges from 0 to 0x3F.
 
== SystemResourceSize ==
When this is non-zero, the kernel reserves this amount of memory and dynamically uses it as needed for page table pages, KMemoryBlocks, and KBlockInfos. When this is zero, the process uses global shared heaps for these.
 
This enables a process to sacrifice some of the memory available to it in order to have higher limits on these resources, thus enabling the use of SvcMapPhysicalMemory.
 
Maximum size as 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. If zero, kernel will start the process's initial thread with sp=0.
 
= ACID =
{| class="wikitable" border="1"
|-
! 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_Format|NCA]] signature
|-
| 0x200
| 0x4
| Magic ("ACID")
|-
| 0x204
| 0x4
| Size
|-
| 0x208
| 0x1
| [9.0.0+] Version
|-
| 0x209
| 0x1
| [14.0.0+]
|-
| 0x20A
| 0x2
| Reserved
|-
| 0x20C
| 0x4
| [[#Flags_2|Flags]]
|-
| 0x210
| 0x8
| ProgramIdMin
|-
| 0x218
| 0x8
| ProgramIdMax
|-
| 0x220
| 0x4
| [[#FsAccessControl|FacOffset]]
|-
| 0x224
| 0x4
| [[#FsAccessControl|FacSize]]
|-
| 0x228
| 0x4
| [[#SrvAccessControl|SacOffset]]
|-
| 0x22C
| 0x4
| [[#SrvAccessControl|SacSize]]
|-
| 0x230
| 0x4
| [[#KernelCapability|KcOffset]]
|-
| 0x234
| 0x4
| [[#KernelCapability|KcSize]]
|-
| 0x238
| 0x8
| Reserved
|}
|}


Switch version of 3DS "System Control Info"?
== Flags ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 0
| ProductionFlag
|-
| 1
| UnqualifiedApproval
|-
| 2-5
| [5.0.0+] MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem)
|}


=ACID=
MemoryRegion is set to Application for "starter" and NonSecureSystem for "nvservices".
 
= ACI0 =
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 67: Line 249:
| 0x0
| 0x0
| 0x4
| 0x4
| Magicnum "ACID".
| Magic ("ACI0")
|-
| 0x4
| 0xC
| Reserved
|-
| 0x10
| 0x8
| ProgramId
|-
| 0x18
| 0x8
| Reserved
|-
| 0x20
| 0x4
| [[#FsAccessControl|FacOffset]]
|-
|-
| 0x24
| 0x4
| 0x4
| [[#FsAccessControl|FacSize]]
|-
| 0x28
| 0x28
| ?
| 0x4
| [[#SrvAccessControl|SacOffset]]
|-
|-
| 0x2C
| 0x2C
| 0x4
| 0x4
| Size of the Service Access Control.
| [[#SrvAccessControl|SacSize]]
|-
|-
| 0x30
| 0x30
| 0x4
| [[#KernelCapability|KcOffset]]
|-
| 0x34
| 0x4
| [[#KernelCapability|KcSize]]
|-
| 0x38
| 0x8
| Reserved
|}
= FsAccessControl =
For [[#ACID|ACID]] this is a simple descriptor as follows:
{| class="wikitable" border="1"
|-
! Offset
! Size
! Description
|-
| 0x0
| 0x1
| Version (always 1, must be non-zero)
|-
| 0x1
| 0x1
| [5.0.0+] ContentOwnerIdCount
|-
| 0x2
| 0x1
| [5.0.0+] SaveDataOwnerIdCount
|-
| 0x3
| 0x1
| Padding
|-
| 0x4
| 0x8
| [[#FsAccessFlag|FsAccessFlag]]
|-
| 0xC
| 0x8
| ContentOwnerIdMin
|-
| 0x14
| 0x14
| ?
| 0x8
| ContentOwnerIdMax
|-
| 0x1C
| 0x8
| SaveDataOwnerIdMin
|-
|-
| 0x44
| 0x24
| ?
| 0x8
| FS Permissions
| SaveDataOwnerIdMax
|-
|-
| 0xF0
| 0x2C
| <See above>
| 0x8 * ContentOwnerIdCount
| Service Access Control
| [5.0.0+] ContentOwnerIds
|-
| Variable
| 0x8 * SaveDataOwnerIdCount
| [5.0.0+] SaveDataOwnerIds
|}
|}


Switch version of AccessDesc?
For [[#ACI0|ACI0]] this embeds data as follows:
 
=ACI0=
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 100: Line 353:
|-
|-
| 0x0
| 0x0
| 0x1
| Version (always 1, must be non-zero)
|-
| 0x1
| 0x3
| Padding
|-
| 0x4
| 0x4
| Magicnum "ACI0".
| 0x8
| [[#FsAccessFlag|FsAccessFlag]]
|-
|-
| 0xC
| 0x4
| 0x4
| 0x28
| ContentOwnerInfoOffset
| ?
|-
|-
| 0x2C
| 0x10
| 0x4
| 0x4
| Size of the Service Access Control.
| ContentOwnerInfoSize
|-
|-
| 0x30
| 0x14
| 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"
|-
! 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
| DeviceTreeBlob
|
|-
| 38
| NotifyErrorContextServiceReady
|
|-
| 39
| CalibrationSystemData
|
|-
| 40
| CalibrationLog
|
|-
| 41
| StorageSecure
|
|-
| 42
| StorageControl
|
|-
| 43
| GameCardReport
|
|-
| 44
| MarkBeforeEraseBis
|
|-
| 45-61
| Reserved
|
|-
| 62
| Debug
| See [[SPL_services#GetConfig|here]].
|-
| 63
| 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:
* "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 =
{| 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.
 
= KernelCapability =
{| class="wikitable" border="1"
|-
! Pattern of lower bits
! Lowest clear bitmask/bit
! Description
|-
| <code>0bxxxxxxxxxxxx0111</code>
| Bit3
| [[#ThreadInfo]]
|-
| <code>0bxxxxxxxxxxx01111</code>
| Bit4
| [[#EnableSystemCalls]]
|-
| <code>0bxxxxxxxxx0111111</code>
| Bit6
| [[#MemoryMap]]
|-
| <code>0bxxxxxxxx01111111</code>
| Bit7
| [[#IoMemoryMap]]
|-
| <code>0bxxxxx01111111111</code>
| Bit10
| [8.0.0+] [[#MemoryRegionMap]]
|-
| <code>0bxxxx011111111111</code>
| Bit11
| [[#EnableInterrupts]]
|-
| <code>0bxx01111111111111</code>
| Bit13
| [[#MiscParams]]
|-
| <code>0bx011111111111111</code>
| Bit14
| [[#KernelVersion]]
|-
| <code>0b0111111111111111</code>
| Bit15
| [[#HandleTableSize]]
|-
| <code>0b1111111111111111</code>
| Bit16
| [[#MiscFlags]]
|-
| All ones
|
| Invalid
|}
 
These descriptors are identified by pattern 01..11 in low bits.
 
== ThreadInfo ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
|-
| 0x44
| 4-9
| ?
| LowestPriority
| FS Permissions
|-
|-
| 0x60
| 10-15
| <See above>
| HighestPriority
| Service Access Control
|-
| 16-23
| MinCoreNumber
|-
| 24-31
| MaxCoreNumber
|}
|}


== EnableSystemCalls ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 5-28
| SystemCallId
|-
| 29-31
| Index
|}


Switch version of 3DS ACI(Access Control Info)?
== 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)
|}


=Service Access Control=
=== Restrictions ===
This is a list of [[Services_API|service]]-name strings which the title has access to, with the following structure:
The physaddr range 0x80060000-0x2000000000 is not allowed to be mapped as IO.
  +0: control_byte
The physaddr range 0x80000000-0x2000000000 is not allowed to be mapped as Normal.
  +1: {service-name without nul-terminator}


Bitmask 0x0F in control_byte is the {length of the service-name without nul-terminator} - 1.
[2.0.0-4.1.0] The range for IO was changed into 0x80060000-0x81D3FFFF.


Bitmask 0x80 in control_byte means service is allowed to be registered.
[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)


The service string can contain a wildcard <code>*</code> character.
[5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied


=Access Descriptors=
== IoMemoryMap ==
Like the 3DS, the switch has a number of kernel capability descriptors. Unlike 3ds, where descriptors were identified by pattern 11..10 in high bits, on switch descriptors are identified by pattern 01..11 in low bits.
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 8-31
| BeginAddress
|}


== MemoryRegionMap ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Pattern of bits 20-31
! Bits
! Type
! Description
! Fields
|-
|-
| <code>0bxxxxxxxx0111?</code>
| 11-16
| Interrupt info?
| RegionType0 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB)
| ?
|-
|-
| <code>0bxxxxxxx01111</code>
| 17
| System call mask
| RegionIsReadOnly0
| Bits 29-31: System call mask table index; Bits 5-28: mask
|-
|-
| <code>0bxxxxx0111111?</code>
| 18-23
| Kernel release version?
| RegionType1 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB)
| ?
|-
|-
| <code>0bxxxx01111111?</code>
| 24
| Handle table size?
| RegionIsReadOnly1
| ?
|-
|-
| <code>0bxxx011111111?</code>
| 25-30
| Kernel flags?
| RegionType2 (0 = NoMapping, 1 = KernelTraceBuffer, 2 = OnMemoryBootImage, 3 = DTB)
| ?
|-
|-
| <code>0bx0111111111?</code>
| 31
| Map address range?
| RegionIsReadOnly2
| ?
|}
 
== EnableInterrupts ==
{| class="wikitable" border="1"
|-
|-
| <code>0b011111111111?</code>
! Bits
| Map memory page?
! Description
| ?
|-
| 12-21
| InterruptNumber0
|-
| 22-31
| InterruptNumber1
|}
|}


0x3FF means empty.


=FS Permissions=
== MiscParams ==
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
! Bit
! Bits
! Description
! Description
|-
|-
| 0
| 14-16
| MountContent* is accessible when set.
| 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 encodes the intended kernel version for the program.
 
The kernel requires that the intended version is >= the minimum supported version (3.0 for all released kernels), and <= the current version.
 
Kernel version is derived from/equivalent to SDK version:
* Kernel Major = SDK Major + 4
* Kernel Minor = SDK Minor
 
=== Versions ===
{| class="wikitable" border="1"
|-
! Firmware || Kernel Version || Corresponding SDK Version
|-
| 1.0.0 || 5.0 || 1.0.0.0
|-
| 2.0.0 || 6.1 || 2.1.0.0
|-
| 3.0.0 || 7.4 || 3.4.0.0
|-
| 3.0.2 || 7.4 || 3.4.0.0
|-
| 5.0.0 || 9.3 || 5.3.0.0
|-
| 10.0.0 || 14.4 || 10.4.0.0
|-
| 11.0.0 || 15.4 || 11.4.0.0
|-
| 11.0.1 || 15.4 || 11.4.0.0
|}
 
== HandleTableSize ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 16-25
| HandleTableSize
|}
 
== MiscFlags ==
{| class="wikitable" border="1"
|-
! Bits
! Description
|-
| 17
| EnableDebug
|-
| 18
| [19.0.0+] ForceDebugProd ([1.0.0-18.1.0] ForceDebug)
|-
|-
| 3
| 19
| This is only bit set for ShopN in the permissions-u32.
| [19.0.0+] ForceDebug
|}
|}