Changes

Jump to navigation Jump to search
1,447 bytes added ,  20:14, 12 December 2019
no edit summary
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 37: Line 37:  
| 0xC
 
| 0xC
 
| 0x1
 
| 0x1
| Flags (bit0 = Is64BitInstruction, bit1 = AddressSpace64BitOld, bit2 = AddressSpace32Bit, bit3 = AddressSpace32BitNoReserved, bit4 = AddressSpace64Bit)
+
| [[#Flags]]
 
|-
 
|-
 
| 0xD
 
| 0xD
Line 45: Line 45:  
| 0xE
 
| 0xE
 
| 0x1
 
| 0x1
| MainThreadPriority (0-63)
+
| [[#MainThreadPriority]]
 
|-
 
|-
 
| 0xF
 
| 0xF
Line 57: Line 57:  
| 0x14
 
| 0x14
 
| 0x4
 
| 0x4
| [3.0.0+] System resource (PersonalMmHeap) size (max size as of 5.x: 534773760)
+
| [3.0.0+] [[#SystemResourceSize]]
 
|-
 
|-
 
| 0x18
 
| 0x18
 
| 0x4
 
| 0x4
| Version (0 for all titles prior to [[8.1.0]], 1 for certain titles since).
+
| [[#Version]]
 
|-
 
|-
 
| 0x1C
 
| 0x1C
 
| 0x4
 
| 0x4
| 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?)
+
| [[#MainThreadStackSize]]
 
|-
 
|-
 
| 0x20
 
| 0x20
 
| 0x10
 
| 0x10
| Title name (usually/always "Application")
+
| Name (usually/always "Application")
 
|-
 
|-
 
| 0x30
 
| 0x30
 
| 0x10
 
| 0x10
| Product code (usually/always all zeroes)
+
| ProductCode (usually/always all zeroes)
 
|-
 
|-
 
| 0x40
 
| 0x40
Line 81: Line 81:  
| 0x70
 
| 0x70
 
| 0x4
 
| 0x4
| [[#ACI0]] offset
+
| [[#ACI0|AciOffset]]
 
|-
 
|-
 
| 0x74
 
| 0x74
 
| 0x4
 
| 0x4
| [[#ACI0]] size
+
| [[#ACI0|AciSize]]
 
|-
 
|-
 
| 0x78
 
| 0x78
 
| 0x4
 
| 0x4
| [[#ACID]] offset
+
| [[#ACID|AcidOffset]]
 
|-
 
|-
 
| 0x7C
 
| 0x7C
 
| 0x4
 
| 0x4
| [[#ACID]] size
+
| [[#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.
 +
 +
== 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 117: Line 149:  
| 0x204
 
| 0x204
 
| 0x4
 
| 0x4
| Data size
+
| Size
 
|-
 
|-
 
| 0x208
 
| 0x208
Line 125: Line 157:  
| 0x20C
 
| 0x20C
 
| 0x4
 
| 0x4
| Flags (bit0 = ProductionFlag, bit1 = UnqualifiedApproval, [5.0.0+] bit2-3: MemoryRegion (0 = Application, 1 = Applet, 2 = SecureSystem, 3 = NonSecureSystem) "starter" is set to Application and "nvservices" is set to NonSecureSystem)
+
| [[#Flags]]
 
|-
 
|-
 
| 0x210
 
| 0x210
Line 137: Line 169:  
| 0x220
 
| 0x220
 
| 0x4
 
| 0x4
| [[#FS Access Control]] offset
+
| [[#FsAccessControl|FsAccessControlOffset]]
 
|-
 
|-
 
| 0x224
 
| 0x224
 
| 0x4
 
| 0x4
| [[#FS Access Control]] size
+
| [[#FsAccessControl|FsAccessControlSize]]
 
|-
 
|-
 
| 0x228
 
| 0x228
 
| 0x4
 
| 0x4
| [[#Service Access Control]] offset
+
| [[#SrvAccessControl|SrvAccessControlOffset]]
 
|-
 
|-
 
| 0x22C
 
| 0x22C
 
| 0x4
 
| 0x4
| [[#Service Access Control]] size
+
| [[#SrvAccessControl|SrvAccessControlSize]]
 
|-
 
|-
 
| 0x230
 
| 0x230
 
| 0x4
 
| 0x4
| [[#Kernel Access Control]] offset
+
| [[#KernelCapability|KernelCapabilityOffset]]
 
|-
 
|-
 
| 0x234
 
| 0x234
 
| 0x4
 
| 0x4
| [[#Kernel Access Control]] size
+
| [[#KernelCapability|KernelCapabilitySize]]
 
|-
 
|-
 
| 0x238
 
| 0x238
Line 163: Line 195:  
| Reserved
 
| 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 189: Line 239:  
| 0x20
 
| 0x20
 
| 0x4
 
| 0x4
| [[#FS Access Header]] offset
+
| [[#FsAccessControl|FsAccessControlOffset]]
 
|-
 
|-
 
| 0x24
 
| 0x24
 
| 0x4
 
| 0x4
| [[#FS Access Header]] size
+
| [[#FsAccessControl|FsAccessControlSize]]
 
|-
 
|-
 
| 0x28
 
| 0x28
 
| 0x4
 
| 0x4
| [[#Service Access Control]] offset
+
| [[#SrvAccessControl|SrvAccessControlOffset]]
 
|-
 
|-
 
| 0x2C
 
| 0x2C
 
| 0x4
 
| 0x4
| [[#Service Access Control]] size
+
| [[#SrvAccessControl|SrvAccessControlSize]]
 
|-
 
|-
 
| 0x30
 
| 0x30
 
| 0x4
 
| 0x4
| [[#Kernel Access Control]] offset
+
| [[#KernelCapability|KernelCapabilityOffset]]
 
|-
 
|-
 
| 0x34
 
| 0x34
 
| 0x4
 
| 0x4
| [[#Kernel Access Control]] size
+
| [[#KernelCapability|KernelCapabilitySize]]
 
|-
 
|-
 
| 0x38
 
| 0x38
Line 216: Line 266:  
|}
 
|}
   −
= FS Access Header =
+
= FsAccessControl =
 +
For [[#ACID]] this is a simple descriptor as follows:
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 224: Line 275:  
|-
 
|-
 
| 0x0
 
| 0x0
 +
| 0x1
 +
| Version (always 1, must be non-zero)
 +
|-
 +
| 0x1
 +
| 0x3
 +
| Padding
 +
|-
 
| 0x4
 
| 0x4
 +
| 0x8
 +
| [[#FsAccessFlag]]
 +
|-
 +
| 0xC
 +
| 0x20
 +
| Reserved
 +
|}
 +
 +
For [[#ACI0]] this embeds data as follows:
 +
{| class="wikitable" border="1"
 +
|-
 +
! Offset
 +
! Size
 +
! Description
 +
|-
 +
| 0x0
 +
| 0x1
 
| Version (always 1, must be non-zero)
 
| Version (always 1, must be non-zero)
 +
|-
 +
| 0x1
 +
| 0x3
 +
| Padding
 
|-
 
|-
 
| 0x4
 
| 0x4
 
| 0x8
 
| 0x8
| Permissions bitmask
+
| [[#FsAccessFlag]]
 
|-
 
|-
 
| 0xC
 
| 0xC
Line 268: Line 347:  
|}
 
|}
   −
= FS Access Control =
+
== FsAccessFlag ==
{| class="wikitable" border="1"
  −
|-
  −
! Offset
  −
! Size
  −
! Description
  −
|-
  −
| 0x0
  −
| 0x1
  −
| Version (always 1, must be non-zero)
  −
|-
  −
| 0x1
  −
| 0x3
  −
| Padding
  −
|-
  −
| 0x4
  −
| 0x8
  −
| Permissions bitmask
  −
|-
  −
| 0xC
  −
| 0x20
  −
| Reserved
  −
|}
  −
 
  −
[[Filesystem_services#Permissions|Permissions]] bitmask:
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Bit
+
! Bits
 
! Name
 
! Name
 
! Description
 
! Description
Line 435: Line 490:  
|  
 
|  
 
|-
 
|-
| 34-61
+
| 34
 +
| RegisterProgramIndexMapInfo
 +
|
 +
|-
 +
| 35
 +
| CreateOwnSaveData
 +
|
 +
|-
 +
| 36-61
 
| Reserved
 
| Reserved
 
|  
 
|  
Line 447: Line 510:  
| Enables access to everything: all [[Filesystem_services#Permissions|permission types]] which check a bitmask have this bit set.
 
| 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 453: Line 518:     
= Service Access Control =
 
= Service Access Control =
This is a list of [[Services_API|service]]-name strings which the title has access to, with the following structure:
+
{| class="wikitable" border="1"
  +0: control_byte
+
|-
  +1: {service-name without nul-terminator}
+
! 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
 +
|}
   −
Bitmask 0x07 in control_byte is the {length of the service-name without nul-terminator} - 1.
+
This is a list of [[Services_API|service]]-name strings which the title has access to.
   −
Bitmask 0x80 in control_byte means IsServer (service is allowed to be registered).
+
The service name string starts after the first byte and supports the wildcard <code>*</code> character.
   −
The service string can contain a wildcard <code>*</code> character.
+
= KernelCapability =
 
+
These descriptors are identified by pattern 01..11 in low bits.
= Kernel Access Control =
  −
On Switch, descriptors are identified by pattern 01..11 in low bits.
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 470: Line 544:  
! Pattern of lower bits
 
! Pattern of lower bits
 
! Lowest clear bitmask/bit
 
! Lowest clear bitmask/bit
! Type
+
! Description
! Fields
   
|-
 
|-
 
| <code>0bxxxxxxxxxxxx0111</code>
 
| <code>0bxxxxxxxxxxxx0111</code>
 
| Bit3
 
| Bit3
| ThreadInfo
+
| [[#ThreadInfo]]
| Bit31-24: MaxCoreNumber, bit23-16: MinCoreNumber, bit15-10: HighestPriority, bit9-4: LowestPriority.
   
|-
 
|-
 
| <code>0bxxxxxxxxxxx01111</code>
 
| <code>0bxxxxxxxxxxx01111</code>
 
| Bit4
 
| Bit4
| EnableSystemCalls
+
| [[#EnableSystemCalls]]
| Bits29-31: SystemCallId; Bits5-28: Mask.
   
|-
 
|-
 
| <code>0bxxxxxxxxx0111111</code>
 
| <code>0bxxxxxxxxx0111111</code>
 
| Bit6
 
| Bit6
| MemoryMap
+
| [[#MemoryMap]]
| Bits7-30: Alternates between BeginAddress and Size, bit31: Alternates between Permission (MemoryPermission_RO or MemoryPermission_RW) and Type (MemoryType_Io or MemoryType_Static).
   
|-
 
|-
 
| <code>0bxxxxxxxx01111111</code>
 
| <code>0bxxxxxxxx01111111</code>
 
| Bit7
 
| Bit7
| MemoryMap (RW)
+
| [[#IoMemoryMap]]
| Bits8-31: BeginAddress.
   
|-
 
|-
 
| <code>0bxxxxx01111111111</code>
 
| <code>0bxxxxx01111111111</code>
 
| Bit10
 
| Bit10
| [8.0.0+] MemoryRegionMap
+
| [8.0.0+] [[#MemoryRegionMap]]
| Bits 11-17: Region0, Bits 18-24: Region1, bits 25-31: Region2. Region is bit 0-6: MemoryRegionType, bit 7 = IsReadOnly.
   
|-
 
|-
 
| <code>0bxxxx011111111111</code>
 
| <code>0bxxxx011111111111</code>
 
| Bit11
 
| Bit11
| EnableInterrupts
+
| [[#EnableInterrupts]]
| Bits12-21: Irq0, bits22-31: Irq1, 0x3FF means empty.
   
|-
 
|-
 
| <code>0bxx01111111111111</code>
 
| <code>0bxx01111111111111</code>
 
| Bit13
 
| Bit13
| MiscParams
+
| [[#MiscParams]]
| Bit16-14: ProgramType (0 = System, 1 = Application, 2 = Applet), bit16 ignored. Parsed by [[Process Manager services]]. Defaults to 0 if descriptor doesn't exist. Can only run 1 application at a time.
   
|-
 
|-
 
| <code>0bx011111111111111</code>
 
| <code>0bx011111111111111</code>
 
| Bit14
 
| Bit14
| KernelVersion
+
| [[#KernelVersion]]
| Bits15-18: MinorVersion, bits19-31: MajorVersion. The raw descriptor 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.
   
|-
 
|-
 
| <code>0b0111111111111111</code>
 
| <code>0b0111111111111111</code>
 
| Bit15
 
| Bit15
| HandleTableSize
+
| [[#HandleTableSize]]
| Bit16-25: Number of handles the table shall fit.
   
|-
 
|-
 
| <code>0b1111111111111111</code>
 
| <code>0b1111111111111111</code>
 
| Bit16
 
| Bit16
| MiscFlags
+
| [[#MiscFlags]]
| Bit17: EnableDebug, bit18: ForceDebug.
   
|-
 
|-
 
| All ones
 
| All ones
 
|  
 
|  
 
| Ignored
 
| Ignored
|
   
|}
 
|}
   −
Note: the 8.0.0+ MemoryRegionMap descriptor is supported by the kernel but not by [[Loader_services|Loader]]. Thus, only initial processes may possess this capability.
+
== 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
 +
| Mask
 +
|-
 +
| 29-31
 +
| SystemCallId
 +
|}
 +
 
 +
== MemoryMap ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 7-30
 +
| BeginAddress or Size
 +
|-
 +
| 31
 +
| IsRw or IsIo
 +
|}
 +
 
 +
MemoryMap entries are stored alternating between BeginAddress + IsRw and Size + IsIo.
   −
== Mapping restrictions ==
+
=== 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.
Line 548: Line 655:  
[5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied
 
[5.0.0+] For IO, this blacklist was abandoned and instead two range checks were added. For Normal mappings it is still applied
   −
== Kernel versions ==
+
== IoMemoryMap ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 8-31
 +
| BeginAddress
 +
|}
 +
 
 +
== MemoryRegionMap ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 11-16
 +
| RegionType0
 +
|-
 +
| 17
 +
| RegionIsReadOnly0
 +
|-
 +
| 18-23
 +
| RegionType1
 +
|-
 +
| 24
 +
| RegionIsReadOnly1
 +
|-
 +
| 25-30
 +
| RegionType2
 +
|-
 +
| 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 564: Line 750:  
|}
 
|}
   −
Bit31-19: Major version</br>
+
== HandleTableSize ==
Bit18-15: Minor version</br>
+
{| class="wikitable" border="1"
Bit14-0: Zeroes
+
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 16-25
 +
| HandleTableSize
 +
|}
 +
 
 +
== MiscFlags ==
 +
{| class="wikitable" border="1"
 +
|-
 +
! Bits
 +
! Description
 +
|-
 +
| 17
 +
| EnableDebug
 +
|-
 +
| 18
 +
| ForceDebug
 +
|}

Navigation menu