IOS is the operating system that runs on the Starlet coprocessor inside the Hollywood package. It provides services that are used by Wii code to access many system devices: USB, networking, security, app management, NAND flash storage, SD card, optical disc, and also WiiConnect24 features.

All software using the Wii SDK or libogc relies on a running IOS on the Starlet (with a few exceptions in the latter case - it is possible to shut down IOS services from libogc and work without it). Typically, the only times IOS is not in use is when running GameCube software (which uses MIOS instead - effectively a dummy IOS), or when BootMii and related software is in use (which uses mini instead).

IOS is versioned in a somewhat unique way. Instead of there being a single canonical version of IOS, there are multiple branches, each typically corresponding to one or more versions of the Wii SDK. Each branch is apparently specified to have a completely frozen API, and old versions are only updated to patch bugs (often security bugs) - Nintendo at one point created an entirely new IOS branch that differed only in the default value for the TCP buffer size. A fully updated Wii contains one copy of the latest version of each branch of IOS. On a Wii, these are installed as separate titles, often called "IOS slots". Due to this design, it is generally considered safe to uninstall, reinstall, or patch an IOS or IOS module, as long as it is not the slot used by the System Menu - if anything goes wrong, the broken version can be safely uninstalled and a vanilla copy reinstalled. IOS slots have title IDs 1-3 through 1-255. Unused (high) IOS slots are often used to install patched versions of IOS or alternative Starlet software (e.g. BootMii as IOS is installed as IOS254, which when invoked will subsequently load armboot.bin from the SD card, typically mini). See IOS History for a comprehensive list of IOS slots and versions.

IOS is not a "hypervisor", as it runs on a dedicated, separate CPU. However, IOS does isolate its memory from access by the main Broadway CPU, has the ability to reboot (and hence bootstrap) it, and is designed to be secure if the PowerPC side is compromised (although in practice many exploits have been found). In that sense, IOS is higher in the security hierarchy than code running on the PowerPC.

Since the IOS API is largely forwards-compatible, it is often possible (though not recommended) to run official software with an alternate IOS branch or slot. Homebrew software will often run under a relatively large range of IOS versions, sometimes constrained by requiring newer features (e.g. USB EHCI support).

When the Wii is in WiiConnect24 standby mode (yellow LED), the main PowerPC CPU is off, but IOS is still running.

See Also

Architecture

IOS is a Nintendo-proprietary, embedded operating system. It uses a microkernel architecture, where independent processes communicate using a standard file API (open/read/write/seek/ioctl/ioctlv/close) on resources identified by /dev/ entries in a virtual filesystem hierarchy. Real filesystems (chiefly the NAND filesystem) are also mounted this way (the NAND driver registers itself as the fallback handler for the root node, /).

Kernel

The kernel is the piece of code that is launched first; it consists of a small ELF-loader header followed by the ELF executable of the kernel proper. In addition to the core microkernel and the cryptography core, it contains the bare minimum set of processes/drivers necessary to load the rest of the modules from the NAND filesystem: FFS (Flash Filesystem), ES (E-Ticket Services), and IOSP (responsible for booting and managing the Broadway and its IPC interface). Older IOS versions were monolithic and contained all modules inside the single main ELF kernel. boot2 is essentially a standalone IOS kernel with no additional modules or drivers, whose sole purpose is to launch the System Menu (and, as part of that process, load the IOS slot that it requires).

The IOS kernel is able to handle up to 100 threads.

IPC

Communication with IOS from PPC code is done using an IPC mechanism. There are 7 calls that can be made using this system:

open

close

read

write

seek

ioctl

ioctlv

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.

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. The IPC interface is essentially identical to the internal microkernel inter-process communication system calls, and indeed maps directly: PPC requests are marshalled by IOSP and appear to come from its process ID to other IOS modules. Oversights in checking whether a request comes from another IOS module or the PowerPC have resulted in several exploitable bugs.

Modules

IOS modules are ELF executables contained in separate title content entries within an IOS title. Modules roughly map to processes and drivers inside the kernel. The shared-content mechanism allows different IOS slots to reuse the same module binaries when they have not changed, to save space in the console's Flash memory.

List of processes in IOS59

PID

Name

Notes

0

Kernel

1

ES

ES sets its own UID and GID to 0 on startup.

2

FS

3

DI

4

OH0

5

OH1

6

EHCI

7

SDI

8

USB Ethernet

9

Net

10

WD

11

WL

12

KD

13

NCD

14

STM

15

PPCBOOT

Requests from the PPC (via the IPC mechanism) appear to come from this process.

16

SSL

17

USB

Several internal USB modules check the UID to make sure their resource managers can only be opened from /dev/usb/usb.

18

P2P (?)

19

Unknown

Literally "unknown" in IOS.

Each process has an associated UID and GID, which can be only changed by the kernel or ES (PID <= 1). This is notably used to enforce filesystem permissions for requests coming from the PPC (PID 15), or to keep some resource managers and ioctls/ioctlvs internal to IOS itself.