IOS/Kernel: Difference between revisions
Hallowizer (talk | contribs) →Threads: this part of the kernel seems to be based on the DS |
Hallowizer (talk | contribs) →Message queues: added an event handlers subsection |
||
| Line 60: | Line 60: | ||
u32 messageCapacity; // 0x14 | u32 messageCapacity; // 0x14 | ||
void *ptr; // 0x18 | void *ptr; // 0x18 | ||
} | |||
</pre> | |||
=== Event handlers === | |||
The IRQ vector is responsible for sending event handler messages. This is done directly (not with <code>IOS_SendMessage</code>). | |||
<pre> | |||
struct IOS_EventHandler { | |||
IOS_MessageQueue *mq; | |||
u32 msg; | |||
u32 pid; | |||
u32 unknown; | |||
} | } | ||
</pre> | </pre> | ||
Revision as of 03:42, 10 July 2022
The IOS kernel is responsible for dispatching interrupts to processes, handling syscalls, and running the IOSP threads. It is independent of the Wii's specific architecture, as Wii-specific functions such as high-level title launching are provided by ES.
Threads
The thread system appears to be based on the DS thread system, but with round-robin scheduling due to the size of IOS. IOS uses the IOS_Thread struct to keep track of a thread.
struct IOS_Context {
u32 psr; // 0x0
u32 r0; // 0x4
u32 r1; // 0x8
u32 r2; // 0xC
u32 r3; // 0x10
u32 r4; // 0x14
u32 r5; // 0x18
u32 r6; // 0x1C
u32 r7; // 0x20
u32 r8; // 0x24
u32 r9; // 0x28
u32 r10; // 0x2C
u32 r11; // 0x30
u32 r12; // 0x34
void *sp; // 0x38
void *lr; // 0x3C
void *pc; // 0x40
}
struct IOS_Thread {
struct IOS_Context persistentCtx; // 0x0
struct IOS_Thread *next; // 0x44
s32 initialPriority; // 0x48
s32 priority; // 0x4C
u32 state; // 0x50 - 0 for a destroyed/uncreated thread, 1 for a thread that is queued to start, 2 for an active thread, 3 for a thread that has not been started, 4 for a blocked thread
u32 processId; // 0x54
bool detached; // 0x58
u32 result; // 0x5C
struct IOS_ThreadQueue joinQueue; // 0x60
struct IOS_ThreadQueue *queue; // 0x64
struct IOS_Context immediateCtx; // 0x68
void *defaultStackLocation ; // 0xAC
}
struct IOS_ThreadQueue {
struct IOS_Thread *head;
}
Thread queues in IOS are circular; the scheduler simply rotates the active queue when rescheduling. Each thread is inserted before the first thread with a lower priority, which works for IOS_CreateThread due to it only allowing a lower priority than the current thread, but IOS_SetThreadPriority allows the priority to be increased (but not past the initial priority), causing threads to be shuffled.
Unlike in Revolution OS, where the initial thread is created over the current code with __OSThreadInit, the first IOS thread (IOSP) is created by the reset vector, launching new code with the standard IOS_CreateThread function.
Message queues
Message queue IDs are allocated globally. A total of 255 message queues can be created.
struct IOS_MessageQueue {
IOS_ThreadQueue waitForSend; // 0x0
IOS_ThreadQueue waitForReceive; // 0x4
u32 processId; // 0x8
u32 messagesEnqueued; // 0xC
u32 rotation; // 0x10 - first message is at index rotation, last message is at index rotation-1
u32 messageCapacity; // 0x14
void *ptr; // 0x18
}
Event handlers
The IRQ vector is responsible for sending event handler messages. This is done directly (not with IOS_SendMessage).
struct IOS_EventHandler {
IOS_MessageQueue *mq;
u32 msg;
u32 pid;
u32 unknown;
}
Memory allocation
Memory allocation is similar to in the IPC library, although the IOS kernel supports 16 heaps instead of 8.
struct HeapBlockHeader {
u16 magic; // 0xbabe
u16 status; // 0 = free, 1 = allocated, 2 = aligned alias for header
u32 size;
struct HeapBlockHeader *prev; // depends on status; status 0 has the previous free block, status 1 has NULL, status 2 has the main block
struct HeapBlockHeader *next; // NULL for anything besides status 0
}
struct Heap {
void *base;
u32 owner; // pid of owning process
u32 size;
struct HeapBlockHeader *freeList;
}
When writing an aligned copy of a block, IOS does not check if it overlaps the existing copy; this could potentially be exploited.
IPC
Resource managers are the backends to the devices that can be opened with IOS_Open. The file descriptors returned by IOS_Open are mapped to internal file descriptors generated by the resource manager.
struct IOS_ResourceManager {
char path[0x40];
u32 pathLen;
struct IOS_MessageQueue *messageQueue;
u32 processId;
bool allowPpcAccess; // only exists in IOS28 and above
}
struct IOS_FileDescriptor {
u32 internalFd;
struct IOS_ResourceManager *resourceManager;
}
struct RequestWrapper {
struct IOSRequest request;
struct IOS_MessageQueue callbackQueue;
struct IOSRequest *replyBuf;
u32 owningThread; // shared pool only
bool allocated; // shared pool only
u32 resourceManagerPid;
}