IOS is a somewhat unique system in that many games use (and come with) their own version of the IOS, though many games use the same IOS versions. There is no "true" version of the operating system, instead there are many of what could be called "slots" for different versions of IOS to sit in. IOS versions are not aware of each other, and are not used or invoked at all unless software specifically requests to run using them. In this way it can be considered "safe" to install custom IOS modules, or to patch any IOS module so long as it is not used by the system menu, as if it becomes corrupt it can be deleted and replaced without damaging the system as a whole.
It should be noted that the IOS does not act as a hypervisor, the "Home" menu you see when you press the Home button is part of the game, it is not provided by the running IOS or the System Menu. To put it simply, the game does not run "on top of" the system menu. When a game is launched the system menu is closed and the game is started, and when the game calls to return to the system menu, the game closes and the system menu is restarted. There can only be one IOS running at a time.
- IOS - Questions and Answers
- IOS History
- IOS Syscalls
- Syscall IDAPython
- Struct IOVEC
- Resource request
Communication with IOS from PPC code is done using an IPC mechanism. There are 7 calls that can be made using this system:
There is one more cmd value (8) that is used for messages that are automatically sent to an IOS queue when an asynchronous syscall completes.
ipc struct size = 0x40, aligned to 0x20 00: cmd // 1=open 2=close 3=read 4=write 5=seek 6=ioctl 7=ioctlv 8=async response 04: ret 08: fd 0c: arg // IOS does not care about data beyond here 20: async1 24: async2 28: 0 3F: relaunch, used for ioctlvreboot open: fd = 0 arg0, arg1: name, mode (1=read 2=write) close: fd read: fd arg0, arg1: addr, len write: fd arg0, arg1: addr, len seek: fd arg0, arg1: where, whence ioctl: fd arg0: ioctl # arg1, arg2: addr, len arg3, arg4: addr, len ioctlv: fd arg0: ioctl # arg1: # in arg2: # out (or in-out) arg3: pointer to # in plus # out pairs of (addr, len) async: ret: result from asynchronous syscall arg[0-5]: will be untouched from when the ipcmessage struct was passed to the syscall, so you can put whatever you like in them beforehand.
fd is a handle you get back from ios on "open", and that you should pass back to all other calls --segher
Most non-trivial operations are performed by opening one of the below resources, then calling ioctl or ioctlv on it.
The Starlet kernel hands these calls over to the individual drivers / processes within the Starlet. The processes register themselves to handle requests by creating one or more queues and assigning them to handle requests from a particular /dev device.
IOS is a Nintendo-proprietary, embedded operating system. It uses a microkernel architecture, with several independent modules that talk to each other via "resources", which are organized as entries in the /dev tree.
The Kernel is the piece of code that is actually booted; it contains a small ELF-loader header at the beginning, and then is an ELF file. In addition to the core microkernel stuff, it contains the bare minimum drivers necessary to read the rest of the drivers from the NAND filesystem -- specifically, FFS (Flash Filesystem), ES (E-Ticket Services), and IOSP (Responsible for booting and managing Broadway?).
- /dev/net/ip/top - TCP/IP Socket operations
- Opens /dev/net/wd/top
- Opens /dev/net/usbeth/top