This note is about getting access to one of the Arm's privileged modes.
Software interrupts (SWIs) are the standard way to make system calls as they permit a change from user mode to supervisor mode. By default every software interrupt in the ARM CPUs is set to jump into a specific address. In the Nintendo DS, this address normally falls in the BIOS. The BIOS will eventually call a function pointer passed by the programmer to manage the software interrupt but before executing the call the BIOS will execute a piece of code like this:
subs pc, lr, #4
This causes the system to switch back to the previous CPU mode. So, if the calling program ran in user mode, then the ISR itself will run in user mode, and there's no way to switch back to system mode manually inside the ISR. The restriction can be bypassed by running user programs in system mode. Then the ISRs can manually switch from system mode to service mode or another privileged mode, and do all the kernel-related tasks. However, running user programs in system mode is not secure. This section explains how to leave user programs in user mode and run your operating system in system mode.
The ARM can only switch to privileged modes through SWI calls, IRQs, FIQs, exceptions, unexpected opcodes and software breakpoints (the latter are not implemented in the Nitro core). For your operating system to execute in system mode and receive calls from code running in user mode you need to reprogram the vectors.
As explained in the ARM ARM946E-S Revision r1p1 Technical Reference Manual CP15 register 1 bit 13 allows exception vectors to be reprogrammed to point at either 0x0000_0000 or 0xffff_0000. On bootup this bit is set by an external pin but you can change this once the machine has booted and you have your receiving code installed to receive exceptions. The relevant part of the manual text is
Bit 13, Alternate vectors select
This bit controls the base address used for the exception vectors.
When clear, the base address for the exception vectors is 0x00000000. When set, the base address is 0xFFFF0000.
This bit is initialized either set or clear during system reset, depending on the value of the input pin, VINITHI. This enables you to define the exception vector location during reset to suit the boot mechanism of the application. You can then reprogram this bit as required following system reset.
To read up on the ARM CPUs you will need the generic manual and the specific one for the device.
- Nintendo's Nitro (and GameBoy Advance) Programming. Nitro is the internal name of the Nintendo DS.
- ARM microkernel for x86 and for GameBoy Advance and other ARM platforms. The GBA has many features in common with the DS, it has an ARM7TDMI CPU and similar BIOS, so many concepts are kept the same. But the DS is more difficult to handle, because of the asymmetric dual core architecture and many pieces of additional hardware.
- Homebrew Nintendo DS development