ARM9 OS: Difference between revisions

Hallowizer (talk | contribs)
created with info i found in the dsi system menu. note that "unknown" means I haven't found it, not that nobody knows.
 
Hallowizer (talk | contribs)
Threads: kernelSp is a system stack used for thread cleanup and SVCs
 
(14 intermediate revisions by the same user not shown)
Line 2: Line 2:


== Threads ==
== Threads ==
The scheduler only runs the thread with the highest priority, and does not switch between threads if two threads have the same priority. Because of this, rescheduling only happens when a thread-related function is called and the thread with the highest priority can no longer run.
<pre>
<pre>
struct OSFpContext {
struct OSMathContext {
f64 REG_DIV_NUMER; // 0x0
u64 REG_DIV_NUMER; // 0x0
f64 REG_DIV_DENOM; // 0x8
u64 REG_DIV_DENOM; // 0x8
f64 SQRT_PARAM; // 0x10
u64 SQRT_PARAM; // 0x10
u16 REG_DIVCNT; // 0x18
u16 REG_DIVCNT; // 0x18
u16 REG_SQRTCNT; // 0x1a
u16 REG_SQRTCNT; // 0x1a
Line 29: Line 30:
void *lr; // 0x3c
void *lr; // 0x3c
void *pc; // 0x40
void *pc; // 0x40
void *kernelSp; // 0x44
void *systemStack; // 0x44
struct OSFpContext fp; // 0x48
struct OSMathContext math; // 0x48
}
}


Line 42: Line 43:
struct OSThreadQueue *queue; // 0x78
struct OSThreadQueue *queue; // 0x78
struct OSThreadLink linkQueue; // 0x7c
struct OSThreadLink linkQueue; // 0x7c
// more unknown fields - the total length is not known
struct OSMutex *mutex; // 0x84 - set to the mutex the thread is currently trying to lock
struct OSMutexQueue queueMutex; // 0x88
void *stackLo; // 0x90
void *stackHi; // 0x94
void *unknown2; // 0x98
struct OSThreadQueue queueJoin; // 0x9c
u32 unknown3[3]; // 0xa4
struct OSAlarm *timedSleepAlarm; // 0xb0
void (*cleanupFunc)(u32 res); // 0xb4
u32 unknown4[2];
}
}


Line 53: Line 63:
struct OSThread *prev;
struct OSThread *prev;
struct OSThread *next;
struct OSThread *next;
}
struct OSMutex {
struct OSThreadQueue waitingQueue;
struct OSThread *holder;
u32 timesLocked;
struct OSMutex *next;
struct OSMutex *prev;
}
struct OSMutexQueue {
struct OSMutex *head;
struct OSMutex *tail;
}
</pre>
== Message queues ==
<pre>
struct OSMessageQueue {
struct OSThreadQueue waitForReceive;
struct OSThreadQueue waitForSend;
u32 *buf;
u32 capacity;
u32 rotation;
u32 messagesEnqueued;
}
</pre>
== Memory allocation ==
3 types of heaps exist: EXPH (exponential heap), FRMH (frame heap), and UNTH (unit heap).
== Time ==
Timer 0 is used to keep track of global time by manually incrementing a global, while timer 1 is used to generate an interrupt for alarms. The OS orders the alarms by alert time, so that it only needs to keep track of the frontmost alarm.
<pre>
struct OSAlarm {
void (*handler)(void *userData);
void *userData;
u32 unknown;
u64 alertTime;
struct OSAlarm *prev;
struct OSAlarm *next;
u64 repeatInterval; // 0 for non-repeating alarms
u64 repeatStart; // undefined value for non-repeating alarms
}
struct OSAlarmQueue {
u32 unknown;
struct OSAlarm *head;
struct OSAlarm *tail;
}
}
</pre>
</pre>
== Interrupts ==
The interrupt handler called by the [[ARM9 BIOS]] calls a handler in a table mapping the raw IRQ IDs to handlers. Each handler is either a no-op (not listed in the table below) or a stub that calls <code>__OSDispatchInterrupt</code> with an OS interrupt ID. <code>__OSDispatchInterrupt</code> then calls the handler registered with <code>__OSSetInterruptHandler</code>.
{| class="wikitable sortable"
! Hardware ID
! Translated ID
! Name
|-
| 3
| 8
| Timer 0 overflow
|-
| 4
| 9
| Timer 1 overflow
|-
| 5
| 10
| Timer 2 overflow
|-
| 6
| 11
| Timer 3 overflow
|-
| 8
| 0
| DMA 0
|-
| 9
| 1
| DMA 1
|-
| 10
| 2
| DMA 2
|-
| 11
| 3
| DMA 3
|-
| 28
| 4
| New DMA 0
|-
| 29
| 5
| New DMA 1
|-
| 30
| 6
| New DMA 2
|-
| 31
| 7
| New DMA 3
|}