Difference between revisions of "KProcess"

From 3dbrew
Jump to navigation Jump to search
(How a final handle is created)
 
(75 intermediate revisions by 7 users not shown)
Line 1: Line 1:
[[Category:Kernel objects]]
+
[[Category:Kernel synchronization objects]]
class [[KProcess]] extends [[KSynchronizationObject]];
+
[[Category:Kernel interrupt events]]
 +
class [[KProcess]] extends [[KSynchronizationObject]] and [[KSendableInterruptEvent]];
  
Size : 0x260 bytes
+
Size : 0x270 (N3DS) / 0x268 bytes (O3DS post 8.x) / 0x260 bytes (O3DS pre 8.x). 0x4D8 bytes on ARM9.
 +
The only field that changed is the [[KProcessHwInfo]] member instance. The definition of KProcess remain identical in all cases.
 +
 
 +
The listed offsets are N3DS-only.
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 11: Line 15:
 
|-
 
|-
 
| 0x0
 
| 0x0
| u32
+
| void**
 
| Pointer to vtable
 
| Pointer to vtable
 
|-
 
|-
Line 18: Line 22:
 
| Reference count
 
| Reference count
 
|-
 
|-
| 0x54
+
| 0x8
 
| u32
 
| u32
| Virtual address of the MMU table for this process
+
| Count of KThreads that sync with this object - number of nodes in the linked list below
 
|-
 
|-
| 0x6C
+
| 0xC
| s32
+
| KLinkedListNode*
| Ideal processor
+
| Pointer to first KLinkedListNode in node list of KThreads that sync with this object
 
|-
 
|-
| 0x7C
+
| 0x10
| u32
+
| KLinkedListNode*
| Number of threads which belong to this process.
+
| Pointer to last KLinkedListNode in node list of KThreads that sync with this object
 
|-
 
|-
| 0x79
+
| 0x14
| u8
+
| [[KSendableInterruptEvent]]
| Proc affinity mask
+
| Interrupt event (*this) sent to terminate the process
 
|-
 
|-
| 0x80
+
| 0x1C
| 0x10-bytes
+
| [[KProcessHwInfo]]
| SVC access control mask from the exheader kernel descriptors.
+
| Process hardware/context info. Used to manage segmentation, etc.
 
|-
 
|-
| 0xA0
+
| 0x68
 
| u32
 
| u32
| Kernel flags from the exheader kernel descriptors.
+
| Total size of all [[Memory_layout#0xFF4XX000|Thread Context]] pages owned by threads that belong to this process
 
|-
 
|-
| 0xA4
+
| 0x6C
| u16
 
| Handle table size from the exheader kernel descriptors. When this is 0, handle table is stored in WRAM.
 
|-
 
| 0xA6
 
| u16
 
| Kernel release version field, from the exheader kernel descriptors.
 
|-
 
| 0xA8
 
 
| u32
 
| u32
| Pointer to [[KCodeSet]] instance
+
| Number of [[KThreadLocalPage|KThreadLocalPages]] used by this KProcess
 
|-
 
|-
| 0xAC
+
| 0x70
| u32
+
| KLinkedListNode*
| Process id, this always begins at 0x0 for the first process.
+
| Pointer to first KLinkedListNode in the list of KThreadLocalPages
 
|-
 
|-
| 0xB8
+
| 0x74
| KThread*
+
| KLinkedListNode*
| Pointer to the process's main (?) thread.
+
| Pointer to last KLinkedListNode in the list of KThreadLocalPages
|-
 
| 0xCC
 
| void*
 
| Pointer to the process's handle table.
 
|}
 
 
 
Structure for [[8.0.0-18]] NATIVE_FIRM:
 
 
 
Size : 0x268 bytes
 
 
 
{| class="wikitable" border="1"
 
|-
 
!  Offset
 
! Type
 
!  Description
 
 
|-
 
|-
| 0x0
+
| 0x78
 
| u32
 
| u32
| Pointer to vtable
+
| Unknown
 
|-
 
|-
| 0x4
+
| 0x7C
| u32
+
| s32
| Reference count
+
| Ideal processor for this process
 
|-
 
|-
| 0x4C
+
| 0x80
| u32
+
| KDebug*
| End of userland virtual memory for the process  
+
| KDebug object created from [[SVC|svc 0x60]] to debug the process
 
|-
 
|-
| 0x50
+
| 0x84
| u32*
+
| KResourceLimit*
| [[Memory_layout|LINEAR]] memory virtual address(userland) base for this process.
+
| Pointer to resource limits for process.
 
|-
 
|-
| 0x58
+
| 0x88
| u32
+
| u8
| Size of the MMU table
+
| Normally 1 to indicate process is open/available. Set to 2 to indicate process is exiting/closing and 3 to indicate exited/closed.
 
|-
 
|-
| 0x5C
+
| 0x89
| u32
+
| u8
| Virtual address of the MMU table for this process
+
| Process affinity mask
 
|-
 
|-
| 0x74
+
| 0x8A
| s32
+
| u16
| Ideal processor for this process
+
| Unused, alignment
 
|-
 
|-
| 0x7C
+
| 0x8C
| u32
+
| s16
| Pointer to resource limits for process.
+
| Number of threads which belong to this process.
 
|-
 
|-
| 0x84
+
| 0x8E
| u32
+
| s16
| Number of threads which belong to this process.
+
| Max number of threads which can belong to this process. This is always 0.
 
|-
 
|-
| 0x88
+
| 0x90
 
| 0x10-bytes
 
| 0x10-bytes
| SVC access control mask from the exheader kernel descriptors.
+
| SVC access control mask from the exheader kernel descriptors. This is copied to the [[Memory_layout#0xFF4XX000|Thread Context]] area when creating threads, which is the actual data the SVC-handler checks for SVC-access-control.
 
|-
 
|-
| 0xA8
+
| 0xA0
 +
| u32[4]
 +
| Interrupt flags- 32 interrupts per word, 4 words, 0x80 interrupts total divided evenly across 4 words
 +
|-
 +
| 0xB0
 
| u32
 
| u32
| Kernel flags from the exheader kernel descriptors.
+
| Kernel flags from the exheader kernel descriptors.  
 
|-
 
|-
| 0xAC
+
| 0xB4
 
| u16
 
| u16
 
| Handle table size from the exheader kernel descriptors. When this is 0, handle table is stored in WRAM.
 
| Handle table size from the exheader kernel descriptors. When this is 0, handle table is stored in WRAM.
 
|-
 
|-
| 0xAE
+
| 0xB6
 
| u16
 
| u16
 
| Kernel release version field, from the exheader kernel descriptors.
 
| Kernel release version field, from the exheader kernel descriptors.
 
|-
 
|-
| 0xB0
+
| 0xB8
| u32
+
| KCodeSet*
 
| Pointer to [[KCodeSet]] instance
 
| Pointer to [[KCodeSet]] instance
 
|-
 
|-
| 0xB4
+
| 0xBC
 
| u32
 
| u32
 
| Process id, this always begins at 0x0 for the first process.
 
| Process id, this always begins at 0x0 for the first process.
 
|-
 
|-
 
| 0xC0
 
| 0xC0
 +
| s64
 +
| Process creation time as tick count
 +
|-
 +
| 0xC8
 
| KThread*
 
| KThread*
| Pointer to the process's main (?) thread.
+
| Pointer to the process's main thread.
 
|-
 
|-
| 0xD4
+
| 0xCC
| KProcessHandleTable
+
| u32[4]
 +
| Interrupt enabled flags- 32 interrupts per word, 4 words, 0x80 interrupts total divided evenly across 4 words
 +
|-
 +
| 0xDC
 +
| [[KProcess#KProcessHandleTable|KProcessHandleTable]]
 
| This is the data for tracking and using all of the KProcess's handles.
 
| This is the data for tracking and using all of the KProcess's handles.
 +
|-
 +
| 0x234
 +
| u32
 +
| Unused (From here up, everything is set to 0 on creation, has 0 written to it again during process creation, and is never used again.)
 +
|-
 +
| 0x238
 +
| u64
 +
| Unused
 +
|-
 +
| 0x240
 +
| u64
 +
| Unused
 +
|-
 +
| 0x248
 +
| u64
 +
| Unused
 +
|-
 +
| 0x250
 +
| u64
 +
| Unused
 +
|-
 +
| 0x258
 +
| u64
 +
| Unused
 +
|-
 +
| 0x260
 +
| u64
 +
| Unused
 +
|-
 +
| 0x268
 +
| u64
 +
| Unused
 
|}
 
|}
  
  
KProcessHandleTable info struct:
+
= KProcessHandleTable =
 +
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 155: Line 181:
 
|-
 
|-
 
| 0x0
 
| 0x0
| HandleData*
+
| HandleDescriptor*
 
| Pointer to the process's handle table.
 
| Pointer to the process's handle table.
 
|-
 
|-
 
| 0x4
 
| 0x4
| u16
+
| s16
 
| The max number of handles that can be open at once - usually 0x200.
 
| The max number of handles that can be open at once - usually 0x200.
 
|-
 
|-
 
| 0x6
 
| 0x6
| u16
+
| s16
| Unknown
+
| The highest count of handles that have been open at once
 
|-
 
|-
 
| 0x8
 
| 0x8
| HandleData*
+
| HandleDescriptor*
| Pointer to the next open HandleData entry in the handle table.  
+
| Pointer to the next open HandleDescriptor entry in the handle table.  
 
|-
 
|-
 
| 0xC
 
| 0xC
| u16
+
| s16
 
| Total handles used by this KProcess.
 
| Total handles used by this KProcess.
 
|-
 
|-
 
| 0xE
 
| 0xE
| u16
+
| s16
 
| The current number of handles in use.
 
| The current number of handles in use.
 
|-
 
|-
 
| 0x10
 
| 0x10
| u32
+
| [[KObjectMutex]]
| Unknown
+
| Mutex
|-
 
| 0x14
 
| u32
 
| Unknown
 
|-
 
| 0x16
 
| u32
 
| Unknown
 
 
|-
 
|-
 
| 0x18
 
| 0x18
| HandleData[28]
+
| HandleDescriptor[0x28]
| This small handle data table internal to the KProcess is only used in certain processes that don't have an external handle data table in FCRAM.  it is all zeros in most processes.
+
| This small handle data table, internal to the KProcess, is only used in certain processes that don't have an external handle descriptor table in FCRAM.  It is all zeros in most processes.
 
|}
 
|}
  
 
+
= HandleDescriptor =
HandleData struct:
 
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 218: Line 235:
 
On table creation, each entry in the handle data table is populated with a pointer to the next entry in the table.  When a new handle is created, that pointer is moved into offset 0x8 of the KProcessHandleTable info struct to use for generation of the next handle.
 
On table creation, each entry in the handle data table is populated with a pointer to the next entry in the table.  When a new handle is created, that pointer is moved into offset 0x8 of the KProcessHandleTable info struct to use for generation of the next handle.
  
The handle that gets returned when a handle is created is (handle_index | (handle_total << 15)), basically they take the index into the handle data table and OR that with the total handle count << 15.
+
The final handle that gets returned when a handle is created is (handle_index | (handle_total << 15)), basically they take the index into the handle data table and OR that with the total handle count << 15.  This returned value is the one that gets passed back to the running application and is used to look up the HandleDescriptor entry in the table.

Latest revision as of 18:37, 10 December 2016

class KProcess extends KSynchronizationObject and KSendableInterruptEvent;

Size : 0x270 (N3DS) / 0x268 bytes (O3DS post 8.x) / 0x260 bytes (O3DS pre 8.x). 0x4D8 bytes on ARM9. The only field that changed is the KProcessHwInfo member instance. The definition of KProcess remain identical in all cases.

The listed offsets are N3DS-only.

Offset Type Description
0x0 void** Pointer to vtable
0x4 u32 Reference count
0x8 u32 Count of KThreads that sync with this object - number of nodes in the linked list below
0xC KLinkedListNode* Pointer to first KLinkedListNode in node list of KThreads that sync with this object
0x10 KLinkedListNode* Pointer to last KLinkedListNode in node list of KThreads that sync with this object
0x14 KSendableInterruptEvent Interrupt event (*this) sent to terminate the process
0x1C KProcessHwInfo Process hardware/context info. Used to manage segmentation, etc.
0x68 u32 Total size of all Thread Context pages owned by threads that belong to this process
0x6C u32 Number of KThreadLocalPages used by this KProcess
0x70 KLinkedListNode* Pointer to first KLinkedListNode in the list of KThreadLocalPages
0x74 KLinkedListNode* Pointer to last KLinkedListNode in the list of KThreadLocalPages
0x78 u32 Unknown
0x7C s32 Ideal processor for this process
0x80 KDebug* KDebug object created from svc 0x60 to debug the process
0x84 KResourceLimit* Pointer to resource limits for process.
0x88 u8 Normally 1 to indicate process is open/available. Set to 2 to indicate process is exiting/closing and 3 to indicate exited/closed.
0x89 u8 Process affinity mask
0x8A u16 Unused, alignment
0x8C s16 Number of threads which belong to this process.
0x8E s16 Max number of threads which can belong to this process. This is always 0.
0x90 0x10-bytes SVC access control mask from the exheader kernel descriptors. This is copied to the Thread Context area when creating threads, which is the actual data the SVC-handler checks for SVC-access-control.
0xA0 u32[4] Interrupt flags- 32 interrupts per word, 4 words, 0x80 interrupts total divided evenly across 4 words
0xB0 u32 Kernel flags from the exheader kernel descriptors.
0xB4 u16 Handle table size from the exheader kernel descriptors. When this is 0, handle table is stored in WRAM.
0xB6 u16 Kernel release version field, from the exheader kernel descriptors.
0xB8 KCodeSet* Pointer to KCodeSet instance
0xBC u32 Process id, this always begins at 0x0 for the first process.
0xC0 s64 Process creation time as tick count
0xC8 KThread* Pointer to the process's main thread.
0xCC u32[4] Interrupt enabled flags- 32 interrupts per word, 4 words, 0x80 interrupts total divided evenly across 4 words
0xDC KProcessHandleTable This is the data for tracking and using all of the KProcess's handles.
0x234 u32 Unused (From here up, everything is set to 0 on creation, has 0 written to it again during process creation, and is never used again.)
0x238 u64 Unused
0x240 u64 Unused
0x248 u64 Unused
0x250 u64 Unused
0x258 u64 Unused
0x260 u64 Unused
0x268 u64 Unused


KProcessHandleTable[edit]

Offset Type Description
0x0 HandleDescriptor* Pointer to the process's handle table.
0x4 s16 The max number of handles that can be open at once - usually 0x200.
0x6 s16 The highest count of handles that have been open at once
0x8 HandleDescriptor* Pointer to the next open HandleDescriptor entry in the handle table.
0xC s16 Total handles used by this KProcess.
0xE s16 The current number of handles in use.
0x10 KObjectMutex Mutex
0x18 HandleDescriptor[0x28] This small handle data table, internal to the KProcess, is only used in certain processes that don't have an external handle descriptor table in FCRAM. It is all zeros in most processes.

HandleDescriptor[edit]

Offset Type Description
0x0 u32 Handle info
0x4 u32 Pointer to the kernel object that the handle references.

The handle info u32 works as such:

The high byte is a remainder from the pointer to the next entry that originally occupied the handle table entry. It is unused. Byte 2 is either the class type token starting with firmware version 9.0 or the lowest byte of the char* that points to the class type name in firmware versions below 9.0. The lower halfword is the handle number of the current handle taken from the total handle count for the KProcess that owns the table.

On table creation, each entry in the handle data table is populated with a pointer to the next entry in the table. When a new handle is created, that pointer is moved into offset 0x8 of the KProcessHandleTable info struct to use for generation of the next handle.

The final handle that gets returned when a handle is created is (handle_index | (handle_total << 15)), basically they take the index into the handle data table and OR that with the total handle count << 15. This returned value is the one that gets passed back to the running application and is used to look up the HandleDescriptor entry in the table.