KAutoObject and subclasses.
Kernel Objects
Kernel Objects
Category:Kernel Interrupt Events
KBaseInterruptEvent and subclasses.
KBlockInfo
Size : 0x8 bytes
Offset | Type | Description |
---|---|---|
0x0 | u32 | Pointer to memory section start in FCRAM using kernel vmem addresses |
0x4 | u32 | Page count |
KBlockInfo objects start with the FS KProcess on the kernel heap and continue in order. Each KProcess gets 3 or more KBlockInfo objects for (in order) .text pointer and page count, .rodata pointer and page count, and .data pointer and page count. Apps that require more space than is available in a given block will get multiple KBlockInfo objects for each section to split it up into open spaces.
KClassToken
Size : 0x5 bytes
Offset | Type | Description |
---|---|---|
0x0 | const char * | Pointer to kernel type string |
0x4 | u8 | Kernel object descriptive bitflags |
Each type of kernel object has a token that describes it. The token is used to make sure that a kernel object of a certain type is able to perform a function requested by the kernel.
Bitflags #
Bit | Description |
---|---|
0 | Can synchronize |
1 | Is interruptible |
2 | |
3 | |
4 | |
5 | |
6 | |
7 |
Bitflags and their corresponding objects #
Bits | ||
---|---|---|
7 | 6 | 5 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 1 |
0 | 0 | 1 |
0 | 0 | 1 |
0 | 1 | 0 |
0 | 1 | 0 |
0 | 1 | 0 |
0 | 1 | 1 |
0 | 1 | 1 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 0 | 0 |
1 | 0 | 0 |
1 | 0 | 1 |
1 | 0 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
1 | 1 | 0 |
KCoreContext
Size: 0x9000 bytes (effective size: 0x6000 bytes)
There’s one instance of this structure per core. The instance for the current core is aliased at 0xFFFF1000
Offset | Type | Description |
---|---|---|
0x0 | u32[0x400] | N/A (unmapped memory) |
0x1000 | u32[0x1000] | L1 translation table (TTB1). The unused part of it is used as stack for exception modes other than supervisor |
0x5000 | u32[0x400] | N/A |
0x6000 | KThreadContext | Context for the scheduler’s thread |
0x7000 | u32[0x400] | N/A |
0x8000 | KCoreObjectContext | Currently used objects, see below |
KCoreObjectContext
KDebugThread
Size : 0x18 bytes
Offset | Type | Description |
---|---|---|
0x0 | KThread * | Pointer to KThread object this KDebugThread is linked to |
0x4 | u8 | Indicates that svcBreak was used with type != (UN)LOAD_RO |
0x5 | u8 | Indicates that the thread has been locked by KDebug-related functions |
0x6 | u8 | Indicates that the thread shall be locked, set by KDebug-related functions |
0x7 | u8 | For SCHEDULE IN/OUT debug events: 0 for IN, 1 for OUT |
0x8 | u8 | Thread is attached |
0x9 | u8 | For SYSCALL IN/OUT debug events: 0 for IN, 1 for OUT |
0xA | u8[2] | Padding |
0xC | u32 | Thread exit reason |
0x10 | u32 | ID of the creator thread |
0x14 | u32 | Fault Address Register (when applicable) |
KEventInfo
Size : 0x38 bytes
It is converted to struct DebugEventInfo by using svcContinueDebugEvent.
Object definition #
Offset | Type | Description |
---|---|---|
0x0 | u32 | Event type |
0x4 | u32 | Current KThread ID |
0x8 | u32 | Flags. In all observed cases, bit0 means that svcContinueDebugEvent needs to be called for this event (except for EXIT PROCESS events, for which you need to call svcContinueDebugEvent even if this bit is clear) |
0xC | u8 | ATTACH PROCESS/THREAD events: 1 if the object was attached by svcDebugActiveProcess, 0 otherwise (this is always 1 for processes) |
0xD | u8 | Equal to bit0 of field 0x8 in all observed cases: indicates that svcContinueDebugEvent needs to be called for this event (except for EXIT PROCESS events, for which you need to call svcContinueDebugEvent even if this bit is clear) |
0xE | bool | Ignore continue |
0xF | u8 | Indicates that the event has been handled and should be deleted |
0x10 | union { ... } | Event-specific data, see below (slightly different from DebugEventInfo) |
Event-specific data #
ATTACH PROCESS event #
Type | Field |
---|---|
KProcess * | Process |
ATTACH THREAD event #
Type | Field |
---|---|
u32 | Creator thread ID (0 if attached by svcDebugActiveProcess) |
void * | Thread local storage |
u32 * | Entrypoint = .text load address of the parent process |
EXIT THREAD/PROCESS events #
Type | Field |
---|---|
u32 | Exit reason |
EXCEPTION event #
Type | Field |
---|---|
u32 | Exception type |
u32 | Exception address |
u32 | Exception category: 4 for DEBUGGER BREAK, 3 for USER BREAK, 2 for STOP POINT, 1 for DATA ABORT/UNALIGNED DATA ACCESS/UNDEFINED SYSCALL, 0 otherwise |
union { ... } | Type-specific data, see below |
UNDEFINED INSTRUCTION/PREFETCH ABORT/DATA ABORT/UNALIGNED DATA ACCESS/UNDEFINED SYSCALL/STOP POINT events #
Type | Field |
---|---|
u32 | Fault information: Fault Address Register (for watchpoints, DATA ABORT and UNALIGNED DATA ACCESS), attempted SVC ID (for UNDEFINED SYSCALL), otherwise 0 |
u32 | Stop point type that caused the event (when applicable): 0 = svc 0xFF, 1 = breakpoint, 2 = watchpoint |
USER BREAK event #
Type | Field |
---|---|
u32 | Break reason |
u32[2] | User-provided parameters for debug reasons, or 0 |
DEBUGGER BREAK event #
Type | Field |
---|---|
s32[4] | IDs of the attached process’s threads that were running on each core at the time of the @ref svcBreakDebugProcess call, or -1 (only the first 2 values are meaningful on O3DS). |
SCHEDULE IN/OUT events #
Type | Field |
---|---|
u64 | Clock tick |
u32 | CPU ID |
u32[5] | Unknown |
u32 (?) | Event info, apparently 0 |
SYSCALL IN/OUT events #
Type | Field |
---|---|
u64 | Clock tick |
u32 | Syscall ID |
OUTPUT STRING event #
Type | Field |
---|---|
u32 | String address |
u32 | String size |
MAP event #
Type | Field |
---|---|
u32 | Mapped address |
u32 | Mapped size |
u32 | MemoryPermission |
u32 | MemoryState |
KInterruptEventMailbox
Size : 0x14 bytes
There are only two instances of this class. The first mailbox contains pointers to KProcess instances (viewed as KSendableInterruptEvent), and its handling thread has a priority of 0; whereas the second mailbox contains pointers to KThread instances (viewed as KSendableInterruptEvent), and DMA-related interrupt events, and its handling thread has a priority of 16.
The handling thread executes the handler function, i.e. the first virtual function (then removes the interrupt event from the list) of all the KSendableInterruptEvent instances the mailbox contains. When that list is empty, it sets the mailbox’s “is busy” flag and unschedules itself.
KLinkedList
Size : 0xC bytes
Offset | Type | |
---|---|---|
0x0 | u32 | |
0x4 | KLinkedListNodePair | KLinkedListNode* |
KLinkedListNode* |
KLinkedListNode
Size : 0xC bytes
Offset | Type | Description |
---|---|---|
0x0 | KLinkedListNode* | Next |
0x4 | KLinkedListNode* | Previous |
0x8 | void* | Pointer to the node’s data (‘key’ field). |
KMemoryBlock
Size : 0x14 bytes
Offset | Type | Description |
---|---|---|
0x0 | void* | Base address of memory block. |
0x4 | u32 | Block size in pages. |
0x8 | u32 | Memory block permissions - rwx. |
0xC | u32 | Memory state bitflags - the lowest byte is the type of memory and the second byte is for specific properties of the block. |
0x10 | u32 | Zero |
KObjectLink
Size : 0x10 bytes
This is used to keep track of kernel objects and allocate new ones.
Offset | Type | Description |
---|---|---|
0x0 | u32 | Pointer to next available kernel object |
0x4 | u32 | Pointer to first kernel object |
0x8 | u32 | Size of kernel heap allocation for this specific kernel object |
0xC | u32 | Size of this kernel object |
KObjectList
Size : 0x28 bytes
This object
Offset | Type | Description |
---|---|---|
0x0 | u32 | Current count for object |
0x4 | KLinkedListNode* | KLinkedListNode for first object in list |
0x8 | KLinkedListNode* | KLinkedListNode for last object in list |
0xC | KObjectMutex | Mutex |
0x14 | u16 | Total objects of this type that have been created |
0x16 | u16 | Alignment |
0x18 | KObjectLink | Object info tracking |
KObjectMutex
Size : 0x8 bytes
This is used to provide thread-safety when manipulating kernel objects such as KProcessHwInfo, KProcessHandleTable, InterruptTable, etc.
Offset | Type | Description |
---|---|---|
0x0 | KThread * | Thread owning the mutex |
0x4 | s16 | Incremented at the start of each “try-acquire” loop, then decremented. Used to detect errors (error if counter > 0) |
0x6 | s16 | Incremented before each context switch while trying to acquire the mutex, then decremented |
KObjectName
Size : 0x10 bytes
Offset | Type | Description |
---|---|---|
0x0 | char[12] | Object name |
0xC | KClientPort* | KClientPort that’s part of the parent KPort that uses this module |
KProcessHwInfo
Struct inside the KProcess object. Starts at KProcess+0x1C.
Size : 0x4C bytes (on N3DS)
Offsets above 0x8 are only for N3DS.
Offset | Type | Description |
---|---|---|
0x0 | KObjectMutex | Mutex |
0x8 | u32[number of cores] | TLB entries for process need invalidating on core(i) |
0x18 | u32 | KMemoryBlock count for KProcess |
0x1C | KLinkedListNode* | First KLinkedListNode in list of KMemoryBlocks |
0x20 | KLinkedListNode* | Last KLinkedListNode in list of KMemoryBlocks |
0x24 | u32 | Unknown |
0x28 | u32 | Unknown |
0x2C | void* | Translation table base |
0x30 | u8 | Context ID |
0x31 | bool | Indicates that a global TLB flush is needed |
0x32 | bool | Process is the current running game/app |
0x34 | u32 | Unknown |
0x38 | void* | End of userland memory for process |
0x3C | void* | Linear memory start for process (since 8.0.0-18) |
0x40 | u32 | Unknown (since 8.0.0-18) |
0x44 | u32 | MMU table size |
0x48 | u32* | Pointer to the MMU table in kernel FCRAM vmem |
KRecursiveLock
Size : 0x8 bytes
Used to implement critical sections, etc.
This class has 3 methods : Lock
, Unlock
, and LocalUnlock
. The only
difference between the two last methods is that the last one never
triggers SGI #8 (rescheduling signal, associated to
KScheduler objects)
Lock
/ Unlock
blocks are always used with the same object.
Lock
/ LocalUnlock
are always used with the associated attribute of
the timer/watchdog timer interrupt object.
KSchedulableInterruptEventLinkedList
Size : 0x10 bytes
There is exactly one instance of this class per core.
On interrupt requests, when the interrupt handler of a KSchedulableInterruptEvent returns anything else than NULL or 1, it is added to this list.
After being added to this list, the thread handling this object (which is a thread created by the kernel main function) is scheduled and the context is switched. That thread pops the first interrupt event from the list and execute its second virtual function, then unschedules itself and switches context back.
KThreadContext
Size : 0x1000 bytes (1 page)
Each thread is allocated a 0x1000-byte page in this region for the thread context. Each thread has its context address stored as 2 members:
Offset | Type | Description |
---|---|---|
0x88 | u32* | Ptr to svc mode register storage for KThread inside the thread context. |
0x8C | u32* | End-address of the page for this thread context allocated in the 0xFF4XX000 region. |
KThread offset 0x88 points to offset 0xF50 in the thread context and 0x8C points to the end of the thread context page. The kernel refers to the thread context page by subtracting from the end instead of adding from the beginning.
KThreadLocalPage
Size : 0x18 bytes
Offset | Type | Description |
---|---|---|
0x0 | u32 | Pointer to memory page used for thread local regions for threads owned by a given process |
0x4 | KProcess* | Owner process |
0x8 | u32 | Number of threads owned by the process |
0xC | char[8] | Used to track the usage of thread local regions in the local page. |
0x14 | u32 | Zero |
The 8-byte array used to track the regions in use in the page works like so: