IOS: Difference between revisions
No edit summary |
No edit summary |
||
| Line 750: | Line 750: | ||
== Virtual Memory Map == | == Virtual Memory Map == | ||
{| class="wikitable" | |||
|- | |||
! Virtual address range | |||
! Physical address range | |||
! Size | |||
! Description | |||
|- | |||
| 0x04000000 - 0x04030000 | |||
| 0x08280000 - 0x082B0000 | |||
| 0x30000 | |||
| IOS-CRYPTO | |||
|- | |||
| 0x05000000 - 0x050C0000 | |||
| 0x081C0000 - 0x08280000 | |||
| 0xC0000 | |||
| IOS-MCP | |||
|- | |||
| 0x05100000 - 0x05120000 | |||
| 0x13D80000 - 0x13DA0000 | |||
| 0x20000 | |||
| IOS-MCP (debug and recovery mode) | |||
|- | |||
| 0x08120000 - 0x081C0000 | |||
| 0x08120000 - 0x081C0000 | |||
| 0xA0000 | |||
| IOS-KERNEL | |||
|- | |||
| 0x10000000 - 0x10100000 | |||
| 0x10000000 - 0x10100000 | |||
| 0x100000 | |||
| PRSH/PRST | |||
|- | |||
| 0x10100000 - 0x104D0000 | |||
| 0x10100000 - 0x104D0000 | |||
| 0x3D0000 | |||
| IOS-USB | |||
|- | |||
| 0x10700000 - 0x11C40000 | |||
| 0x10700000 - 0x11C40000 | |||
| 0x1540000 | |||
| IOS-FS (5.5.1 retail) | |||
|- | |||
| 0x10800000 - 0x11EE0000 | |||
| 0x10800000 - 0x11EE0000 | |||
| 0x16E0000 | |||
| IOS-FS (5.3.2 debug) | |||
|- | |||
| 0x11F00000 - 0x12160000 | |||
| 0x11F00000 - 0x12160000 | |||
| 0x260000 | |||
| IOS-PAD | |||
|- | |||
| 0x12300000 - 0x12890000 | |||
| 0x12300000 - 0x12890000 | |||
| 0x590000 | |||
| IOS-NET | |||
|- | |||
| 0x1D000000 - 0x1FB00000 | |||
| 0x1D000000 - 0x1FB00000 | |||
| 0x2B00000 | |||
| Global heap | |||
|- | |||
| 0x1FB00000 - 0x1FE00000 | |||
| 0x1FB00000 - 0x1FE00000 | |||
| 0x300000 | |||
| Global IOB (input/output block) | |||
|- | |||
| 0x1FE00000 - 0x1FE20000 | |||
| 0x1FE00000 - 0x1FE20000 | |||
| 0x40000 | |||
| IOS-MCP (shared region) | |||
|- | |||
| 0x1FE40000 - 0x20000000 | |||
| 0x1FE40000 - 0x20000000 | |||
| 0x1C0000 | |||
| IOS-MCP (setup region) | |||
|- | |||
| 0x20000000 - 0x28000000 | |||
| 0x20000000 - 0x28000000 | |||
| 0x8000000 | |||
| RAMDISK | |||
|- | |||
| 0xE0000000 - 0xE0270000 | |||
| 0x12900000 - 0x12B70000 | |||
| 0x270000 | |||
| IOS-ACP | |||
|- | |||
| 0xE1000000 - 0xE12F0000 | |||
| 0x12BC0000 - 0x12EB0000 | |||
| 0x2F0000 | |||
| IOS-NSEC | |||
|- | |||
| 0xE2000000 - 0xE26D0000 | |||
| 0x12EC0000 - 0x13590000 | |||
| 0x6D0000 | |||
| IOS-NIM-BOSS | |||
|- | |||
| 0xE3000000 - 0xE3300000 | |||
| 0x13640000 - 0x13940000 | |||
| 0x300000 | |||
| IOS-FPD | |||
|- | |||
| 0xE4000000 - 0xE4160000 | |||
| 0x13A40000 - 0x13BA0000 | |||
| 0x160000 | |||
| IOS-TEST | |||
|- | |||
| 0xE5000000 - 0xE5070000 | |||
| 0x13C00000 - 0x13C70000 | |||
| 0x70000 | |||
| IOS-AUXIL | |||
|- | |||
| 0xE6000000 - 0xE6050000 | |||
| 0x13CC0000 - 0x13D80000 | |||
| 0xC0000 | |||
| IOS-BSP | |||
|- | |||
| 0xE7000000 - 0xE7001000 | |||
| | |||
| | |||
| | |||
|- | |||
| 0xEFF00000 - 0xEFF08000 | |||
| 0xFFF00000 - 0xFFF08000 | |||
| 0x8000 | |||
| C2W (cafe2wii) boot heap | |||
|- | |||
| 0xFFFF0000 - 0xFFFFFFFF | |||
| 0xFFFF0000 - 0xFFFFFFFF | |||
| 0x10000 | |||
| Kernel SRAM / C2W (cafe2wii) | |||
|} | |||
The Starbuck MMU itself only has R/W permissions for data/instruction memory access, no XN. However, there is XN implemented via separate hardware registers at [[Hardware/XN_Controller|0x0d8b0XXX]]. The register relative-offset is calculated with the physaddr of the memory being protected. Each u32 register corresponds to a different block of physical memory. Among other things, this controls whether the ARM is allowed to access the memory for instruction-access, and in what ARM-mode(userland/privileged) the instruction-access is permitted. | The Starbuck MMU itself only has R/W permissions for data/instruction memory access, no XN. However, there is XN implemented via separate hardware registers at [[Hardware/XN_Controller|0x0d8b0XXX]]. The register relative-offset is calculated with the physaddr of the memory being protected. Each u32 register corresponds to a different block of physical memory. Among other things, this controls whether the ARM is allowed to access the memory for instruction-access, and in what ARM-mode(userland/privileged) the instruction-access is permitted. | ||
Revision as of 20:31, 14 January 2020
IOSU is the operating system running on the ARM in Wii U mode. It is the Wii U equivalent of IOS on the Wii, and similar in some regards, but it is a complete rewrite with many changes. IOSU implements the Wii U's security policy, which includes titles and hardware access. One of its primary responsibilities is enforcing code signing, verifying all titles before installation and launch. Another one of its jobs is managing access to most hardware, such as storage, network, USB, and the Gamepad. The PowerPC can talk to IOSU through an IPC interface, and make security and hardware requests.
See Also
Architecture
IOSU is an embedded operating system written by Nintendo, with a microkernel architecture. It contains a simple kernel that implements memory management and process and thread management. Device drivers and security handlers run as processes in the ARM user mode. These processes, called resource managers (RMs), can register as request handlers for resources, which are represented as nodes under /dev in a virtual filesystem. They communicate with each other through the kernel, using standard Unix file operations (open/close/read/write/seek/ioctl/ioctlv).
ELF loader
The IOSU firmware image file (fw.img), when decrypted, contains two distinguishable pieces of code: a small ELF loader and the actual firmware binary (ELF file). Each time the IOSU starts, the ELF loader is the first portion of code that runs in order to make preparations for the actual IOSU binary. During the console's initial boot, boot1 is responsible for fetching the IOSU's image and launch it (cold boot). However, IOS-MCP also has to do this when handling a system restart (warm boot). The IOS-MCP module begins by clearing up MEM1 then fetches the fw.img file from NAND. It verifies the image's header, decrypts it using the Starbuck Ancast Key and finally makes use of the execute_privileged system call in order to disable memory protections and jump to the IOSU's ELF loader code.
This loader then does the following:
- Clear it's own small stack; - Set 0x20 in HW_SRNPROT register (if not set already); - Fetch e_phnum from the IOSU's ELF header; - Loop through the ELF's program header structs; - For each program marked with PT_LOAD, copy it's code into the target physical memory; - Wipe the IOSU's ELF binary from MEM1; - Wipe itself from MEM1 (excluding the then running subroutine); - Branch to 0xFFFF0000 (IOSU kernel boot).
Kernel
After being parsed by it's own ELF loader, the IOSU's kernel is launched from the Wii U's SRAM (0xFFFF0000). IOSU's kernel follows a standard ARM microkernel architecture:
// IOSU kernel entry-point
// ARM vector table (firmware 5.5.1)
start() // 0xFFFF0000
{
// Reset handler
pc <- sub_FFFF0060
// Undefined handler
pc <- loc_812DD6C
// SWI handler
pc <- sub_812DD20
// Prefetch handler
pc <- sub_812E74C
// Abort handler
pc <- sub_812E720
// NULL
pc <- loc_FFFF0040
// IRQ handler
pc <- loc_FFFF0044
// FIQ handler
pc <- loc_FFFF0048
}
Execution follows into the reset handler:
// Reset handler (firmware 5.5.1)
sub_FFFF0060()
{
r0 <- 0
// Invalidate ICache
MCR p15, 0, R0,c7,c5, 0
// Invalidate DCache
MCR p15, 0, R0,c7,c6, 0
// Read control register
MRC p15, 0, R0,c1,c0, 0
// Set replacement strategy to Round-Robin
r0 <- r0 | 0x1000
// Enable alignment fault checking
r0 <- r0 | 0x2
// Write control register
MCR p15, 0, R0,c1,c0, 0
// Clear the IOS-KERNEL stack
memset_range(stack_start, stack_end, 0, 0x04);
// Disable boot0 mapping
r0 <- 0x0D80018C // HW_SPARE1
r1 <- 0x00(HW_SPARE1)
r1 <- r1 | 0x1000
0x00(HW_SPARE1) <- r1
// MSR CPSR_c, #0xD3 -> Enter supervisor mode, FIQ/IRQ disabled
// SP == 0xFFFF0904
init_svc_stack(0xFFFF0904);
// MSR CPSR_c, #0xD2 -> Enter IRQ mode, FIQ/IRQ disabled
// SP == 0xFFFF1104
init_irq_stack(0xFFFF1104);
// MSR CPSR_c, #0xD1 -> Enter FIQ mode, FIQ/IRQ disabled
// SP == 0xFFFF1504
init_fiq_stack(0xFFFF1504);
// MSR CPSR_c, #0xD7 -> Enter abort mode, FIQ/IRQ disabled
// SP == 0xFFFF0D04
init_abort_stack(0xFFFF0D04);
// MSR CPSR_c, #0xDB -> Enter undefined mode, FIQ/IRQ disabled
// SP == 0xFFFF1904
init_undefined_stack(0xFFFF1904);
// MSR CPSR_c, #0xDF -> Enter system mode, FIQ/IRQ disabled
// SP == 0xFFFF1904
init_user_stack(0xFFFF1904);
// Jump to MEM0 check
lr <- pc
pc <- sub_FFFFDA38
while(1);
}
MEM0's integrity is checked before going any further:
// Check MEM0 for IOS-KERNEL (firmware 5.5.1)
sub_FFFFDA38()
{
r1 <- 0x08143008 // IOSU kernel data region
r3 <- 0xA5A51212
r2 <- 0x00(0x08143008)
// Deadlock
if (0x00(0x08143008) != 0xA5A51212)
{
r3 <- 0xDEAD1111
sp <- 0xDEAD1111
while(1);
}
r12 <- 0xFFFF0500 // IOSU boot heap region
r2 <- 0x00(0xFFFF0500)
// Deadlock
if (0x00(0xFFFF0500) != 0xA5A51212)
{
r3 <- 0xDEAD1111
sp <- 0xDEAD1111
while(1);
}
// Set init magic
r2 <- 0x5A5AEDED
0x00(0xFFFF0500) <- 0x5A5AEDED
0x00(0x08143008) <- 0x5A5AEDED
// Flush AHB for Starbuck
ahbMemFlush(0);
ahb_flush_to(1);
// Load IOS_KERNEL
r2 <- sub_8121B18
sub_8121B18();
// Deadlock
r3 <- 0xDEAD2222
sp <- 0xDEAD2222
while(1);
}
And, finally, execution switches over to MEM0 where the IOS-KERNEL module will be running:
// Load IOS-KERNEL (firmware 5.5.1)
sub_8121B18()
{
// Read LT_DEBUG register
// and store it's value at 0x08150000
sub_8120970();
// Clear LT_DEBUG register
sub_8120988();
// Do a bitwise AND with the LT_DEBUG value
r0 <- 0x80000000
r0 <- sub_81209B8(0x80000000);
// If LT_DEBUG is 0x80000000
// the hardware is using RealView
if (r0 != 0)
{
r4 <- (sp + 0x04)
r3 <- 0
0x00(sp) <- 0
// Wait for user input
// to start the kernel
while (r3 != 0x01)
{
r0 <- "\n\n\n\n\n\n\n\n\n\n"
debug_printf("\n\n\n\n\n\n\n\n\n\n");
r0 <- "Enter '1' to proceed with kernel startup. "
debug_printf("Enter '1' to proceed with kernel startup. ");
r0 <- "%d"
r1 <- sp
debug_read("%d", sp);
r3 <- 0x00(sp)
}
}
// Initialize the MMU and map memory regions
sub_8120C58();
// Reset GPIOs and IRQs
sub_8120510();
// Setup IRQ handlers
sub_8120488();
// Clear and set some kernel structures
sub_812B308();
// Setup iobuf
sub_81235E8();
// Re-map shared_user_ro
sub_81294AC();
// Clear IOS_KERNEL module's thread stack and run it
sub_812CD08();
return;
}
At this point, the IOS-KERNEL module is running on it's own thread and becomes responsible for launching and controlling all the other IOSU modules. The kernel is responsible for tasks such as as IPC handling, permissions' control, resource managers (/dev nodes) and much more. System calls are handled through the ARM undefined handler and mapped into their respective kernel functions.
Threads
The IOSU is able to create and handle up to 0xB4 threads. Each thread has a corresponding internal structure stored in kernel SRAM (0xFFFF4D78 in firmware 5.5.1).
// Thread struct in memory
struct
{
0x00: saved_cpsr
0x04: saved_r0
0x08: saved_r1
0x0C: saved_r2
0x10: saved_r3
0x14: saved_r4
0x18: saved_r5
0x1C: saved_r6
0x20: saved_r7
0x24: saved_r8
0x28: saved_r9
0x2C: saved_r10
0x30: saved_r11
0x34: saved_r12
0x38: saved_r13
0x3C: saved_lr
0x40: thread_pc
0x44: thread_queue_next
0x48: thread_min_priority
0x4C: thread_max_priority
0x50: thread_state
0x54: owner_pid
0x58: thread_id
0x5C: flags
0x60: exit_value
0x64: join_thread_queue_head
0x68: current_thread_queue
0x6C: ?????
0x70: ?????
0x74: ?????
0x78: ?????
0x7C: ?????
0x80: ?????
0x84: ?????
0x88: ?????
0x8C: ?????
0x90: ?????
0x94: ?????
0x98: ?????
0x9C: ?????
0xA0: ?????
0xA4: thread_sp
0xA8: ?????
0xAC: ?????
0xB0: sys_stack_addr
0xB4: user_stack_addr
0xB8: user_stack_size
0xBC: ipc_buffer_pool
0xC0: profiled_count
0xC4: profiled_time
} thread_t; // sizeof() = 0xC8
Thread states 0x00 -> Available 0x01 -> Ready 0x02 -> Running 0x03 -> Stopped 0x04 -> Waiting 0x05 -> Dead 0x06 -> Faulted 0x07 -> Unknown
Bit 2 in the flags determines whether or not the thread has an IPC buffer pool.
Heaps
The IOSU is able to create and handle up to 0x30 heaps. Each heap has a corresponding descriptor structure stored in the kernel's BSS section (0x08150008 in firmware 5.5.1).
// Heap descriptor
struct
{
0x00: base
0x04: owner_pid
0x08: size
0x0C: first_free
0x10: error_count_out_of_memory
0x14: error_count_free_block_not_in_heap
0x18: error_count_expand_invalid_block
0x1C: error_count_corrupted_block
0x20: flags
0x24: total_allocated_size
0x28: largest_allocated_size
0x2C: total_allocation_count
0x30: total_freed_count
0x34: error_count_free_unallocated_block
0x38: error_count_alloc_invalid_heap
0x3C: heap_id
} heap_descriptor_t; // sizeof() = 0x40
All accesses to heaps are verified using owner PID and active PID. Heaps are referenced using IDs that are used as indices into the heap descriptor array. There are 3 special heap IDs:
| Heap ID | Purpose |
|---|---|
| 0x0001 | Shared heap |
| 0xCAFE | Local process heap for active PID |
| 0xCAFF | Cross process heap for active PID |
Access to special heap IDs is redirected to the appropriate heap.
Each process can allocate a cross process heap for multiple processes to use and a local process heap for itself. These are kept tracked of using two arrays following the heap descriptor array in kernel BSS:
int32 local_process_heaps[14]; int32 cross_process_heaps[14];
They are initialized to IOS_ERROR_INVALID within the IOSU kernel and are set to the appropriate heap ID when created using IOS_CreateLocalProcessHeap or IOS_CreateCrossProcessHeap. There may only be one cross/local process heap for each PID.
Each heap descriptor contains a flag field that contains information about the heap:
0x1: Local process heap 0x2: Cross process heap
Each heap is created from memory of the shared heap. It is initialized as one big seperate memory chunk. Memory chunks have the following structure:
// Heap chunk header
struct
{
0x00: magic
0x04: size
0x08: back
0x0C: next
} heap_chunk_header_t; // sizeof() = 0x10
There are 3 valid magic values:
| Magic | Meaning |
|---|---|
| 0xBABE0000 | Chunk is free |
| 0xBABE0001 | Chunks is used |
| 0xBABE0002 | Chunk is inner chunk and used |
When memory is allocated to a heap, the linked list (terminated using nullptr's) is traversed to find a large enough chunk, chunks are split and back and forward pointers are cleared for the allocated chunk. When a chunk is allocated aligned, a chunk bigger than the needed one may be allocated. Inside this chunk, a second heap chunk is set up in a fashion that the beginning of the memory block described by this "inner" chunk is aligned according to the specified alignment. It's magic is set to 0xBABE0002 and the back pointer is set to the chunk containing it. These inner chunks can not be expanded.
IPC
PowerPC code is able to call IOSU drivers through an IPC interface. It uses the same call interface as IOSU does internally. Userspace code submits IOSU requests with the IPCKDriver_SubmitRequest() syscall in the Cafe OS kernel. The kernel includes information to identify which Cafe OS process sent the request, allowing IOSU to check permissions on a per-app basis. Requests are contained in a struct, sent through a hardware interface, and marshalled by the IOSU kernel to a target process. An example of IOSU IPC from the PowerPC can be found here.
IPC request struct (size = 0x48, align = 0x20) 0x00: CMD (1=open, 2=close, 3=read, 4=write, 5=seek, 6=ioctl, 7=ioctlv) 0x04: Reply to client 0x08: Client FD 0x0C: Flags (always 0) 0x10: Client CPU (0=ARM internal, 1-3=PPC cores 0-2) 0x14: Client PID (PFID in older versions, RAMPID more recently?) 0x18: Client group ID (Title ID, upper) 0x1C: Client group ID (Title ID, lower) 0x20: Server handle (written by IOSU) 0x24: Arg0 0x28: Arg1 0x2C: Arg2 0x30: Arg3 0x34: Arg4 0x38: CMD (previous) 0x3C: Client FD (previous) 0x40: Virt0 (PPC virtual addresses to be translated) 0x44: Virt1 (PPC virtual addresses to be translated)
IPC commands 0x00 -> IOS_COMMAND_INVALID 0x01 -> IOS_OPEN 0x02 -> IOS_CLOSE 0x03 -> IOS_READ 0x04 -> IOS_WRITE 0x05 -> IOS_SEEK 0x06 -> IOS_IOCTL 0x07 -> IOS_IOCTLV 0x08 -> IOS_REPLY (internal to IOSU) 0x09 -> IOS_IPC_MSG0 (internal to IOSU) 0x0A -> IOS_IPC_MSG1 (internal to IOSU) 0x0B -> IOS_IPC_MSG2 (internal to IOSU) 0x0C -> IOS_SUSPEND (internal to IOSU) 0x0D -> IOS_RESUME (internal to IOSU) 0x0E -> IOS_SVCMSG (internal to IOSU)
IPC client PIDs On older versions of IOSU, it seems to match the PFID list. More recently, it appears to use the RAMPID. See the Cafe OS PID tables.
IPC arguments
Open CMD: Client FD == 0
Arg0 = name
Arg1 = name_size
Arg2 = mode (0 = none, 1 = read, 2 = write)
Arg3-Arg4 = u64 permissions_bitmask for the target IOSU process, loaded by the target IOSU process during fd init. With PPC this originates from the cos.xml of the source process.
Close CMD: Client FD != 0
Read CMD: Client FD != 0
Arg0 = outPtr
Arg1 = outLen
Write CMD: Client FD != 0
Arg0 = inPtr
Arg1 = inLen
Seek CMD: Client FD != 0
Arg0 = where
Arg1 = whence
IOCtl CMD: Client FD != 0
Arg0 = cmd
Arg1 = inPtr
Arg2 = inLen
Arg3 = outPtr
Arg4 = outLen
IOCtlv CMD: Client FD != 0
Arg0 = cmd
Arg1 = readCount
Arg2 = writeCount
Arg3 = vector
Error codes
Kernel errors 0x00000000 -> IOS_ERROR_OK 0xFFFFFFFF -> IOS_ERROR_ACCESS 0xFFFFFFFE -> IOS_ERROR_EXISTS 0xFFFFFFFD -> IOS_ERROR_INTR 0xFFFFFFFC -> IOS_ERROR_INVALID 0xFFFFFFFB -> IOS_ERROR_MAX 0xFFFFFFFA -> IOS_ERROR_NOEXISTS 0xFFFFFFF9 -> IOS_ERROR_QEMPTY 0xFFFFFFF8 -> IOS_ERROR_QFULL 0xFFFFFFF7 -> IOS_ERROR_UNKNOWN 0xFFFFFFF6 -> IOS_ERROR_NOTREADY 0xFFFFFFF5 -> IOS_ERROR_ECC 0xFFFFFFF4 -> IOS_ERROR_ECC_CRIT 0xFFFFFFF3 -> IOS_ERROR_BADBLOCK 0xFFFFFFF2 -> IOS_ERROR_INVALID_OBJTYPE 0xFFFFFFF1 -> IOS_ERROR_INVALID_RNG 0xFFFFFFF0 -> IOS_ERROR_INVALID_FLAG 0xFFFFFFEF -> IOS_ERROR_INVALID_FORMAT 0xFFFFFFEE -> IOS_ERROR_INVALID_VERSION 0xFFFFFFED -> IOS_ERROR_INVALID_SIGNER 0xFFFFFFEC -> IOS_ERROR_FAIL_CHECKVALUE 0xFFFFFFEB -> IOS_ERROR_FAIL_INTERNAL 0xFFFFFFEA -> IOS_ERROR_FAIL_ALLOC 0xFFFFFFE9 -> IOS_ERROR_INVALID_SIZE 0xFFFFFFE8 -> IOS_ERROR_NO_LINK 0xFFFFFFE7 -> IOS_ERROR_AN_FAILED 0xFFFFFFE6 -> IOS_ERROR_MAX_SEM_COUNT 0xFFFFFFE5 -> IOS_ERROR_SEM_UNAVAILABLE 0xFFFFFFE4 -> IOS_ERROR_INVALID_HANDLE 0xFFFFFFE3 -> IOS_ERROR_INVALID_ARG 0xFFFFFFE2 -> IOS_ERROR_NO_RESOURCE 0xFFFFFFE1 -> IOS_ERROR_BUSY 0xFFFFFFE0 -> IOS_ERROR_TIMEOUT 0xFFFFFFDF -> IOS_ERROR_ALIGNMENT 0xFFFFFFDE -> IOS_ERROR_BSP 0xFFFFFFDD -> IOS_ERROR_DATA_PENDING 0xFFFFFFDC -> IOS_ERROR_EXPIRED 0xFFFFFFDB -> IOS_ERROR_NO_R_ACCESS 0xFFFFFFDA -> IOS_ERROR_NO_W_ACCESS 0xFFFFFFD9 -> IOS_ERROR_NO_RW_ACCESS 0xFFFFFFD8 -> IOS_ERROR_CLIENT_TXN_LIMIT 0xFFFFFFD7 -> IOS_ERROR_STALE_HANDLE 0xFFFFFFD6 -> IOS_ERROR_UNKNOWN_VALUE
Modules
Similarly to the Wii, IOS modules roughly map to processes and drivers inside the kernel. Modules have a locked PID associated with them:
| PID | Name |
|---|---|
| 0 | IOS-KERNEL |
| 1 | IOS-MCP |
| 2 | IOS-BSP |
| 3 | IOS-CRYPTO |
| 4 | IOS-USB |
| 5 | IOS-FS |
| 6 | IOS-PAD |
| 7 | IOS-NET |
| 8 | IOS-ACP |
| 9 | IOS-NSEC |
| 10 | IOS-AUXIL |
| 11 | IOS-NIM-BOSS |
| 12 | IOS-FPD |
| 13 | IOS-TEST |
| 14 | COS-KERNEL |
| 15 | COS-ROOT |
| 16 | COS-02 |
| 17 | COS-03 |
| 18 | COS-OVERLAY |
| 19 | COS-HBM |
| 20 | COS-ERROR |
| 21 | COS-MASTER |
PIDs 14-21 are used for PPC side processes.
IOS-CRYPTO
Cryptography services.
- /dev/crypto - Cryptography API
IOS-MCP
Master title operations such as title launching and cafe2wii booting.
- /dev/mcp - Master title launching (also encapsulates ES from the Wii)
- /dev/mcp_recovery - Master title launching (recovery mode)
- /dev/volflush - Volume cache flushing service
- /dev/pm - Power management
- /dev/syslog - System logging
- /dev/usb_syslog - USB system logging
- /dev/dk_syslog - DevKit system logging
- /dev/ppc_app - PPC application service
- /dev/ppc_kernel - PPC kernel service
IOS-USB
USB controllers and devices.
- /dev/usbproc1 - USB internal process
- /dev/usbproc2 - USB internal recovery process
- /dev/uhs/0 - USB host stack (external ports)
- /dev/usb_cdc - USB communications device class
- /dev/usb_hid - USB human interface device
- /dev/usb_uac - USB audio class
- /dev/usb_midi - USB musical instrument digital interface
IOS-FS
File system services.
- /dev/fsa - Virtual file system API
- /dev/dk - DevKit file system API
- /dev/odm - Optical disk manager
- /dev/ramdisk_svc - RAM disk service
- /dev/ums - USB mass storage
- /dev/df - Disk format
- /dev/atfs - Optical disk file system
- /dev/isfs - Internal storage file system
- /dev/wfs - Wii file system
- /dev/pcfs - PC file system (only available in DEBUG or TEST mode)
- /dev/rbfs - Raw file system
- /dev/fat - FAT file system
- /dev/fla - Flash file system
- /dev/ahcimgr - Advanced host controller interface manager
- /dev/shdd - SATA hard disk drive
- /dev/md - Raw memory device
- /dev/scfm - SLC cache for MLC
- /dev/mmc - eMMC storage
- /dev/timetrace - File IO time tracer
IOS-PAD
Gamepad controllers and devices.
- /dev/uhs/1 - USB host stack (internal devices)
- /dev/ccr_io - Gamepad main service
- /dev/ccr_cdc - Gamepad RPC (CDC = Communications Device Class)
- /dev/ccr_hid - Gamepad input (HID = Human Interface Device)
- /dev/ccr_nfc - Gamepad NFC reader
- /dev/ccr_uac - Gamepad microphone (UAC = USB Audio Class)
- /dev/ccr_uvc - Gamepad camera (UVC = USB Video Class)
- /dev/usb/btrm - Bluetooth module (for Wii Remote and Pro Controller)
- /dev/usb/early_btrm - Secondary Bluetooth module
IOS-NET
Network services.
- /dev/network - Network main service
- /dev/socket - BSD sockets API
- /dev/ifnet - Network interface
- /dev/net/ifmgr - Network interface manager
- /dev/net/ifmgr/wd - Wireless device?
- /dev/net/ifmgr/ncl - Network configuration
- /dev/net/ifmgr/usbeth - Ethernet over USB
- /dev/ifuds - UDS interface
- /dev/udscntrl - UDS control. Used by nn_uds.rpl(see here).
- /dev/wl0 - Wireless interface
- /dev/wifidata - ?????
- /dev/wifi24 - Standby mode?
- /dev/ac_main - Auto Connection, used by nn_ac.rpl.
- /dev/ndm - ?????
- /dev/dlp - 3DS Download Play hosting, used by nn_dlp.rpl.
IOS-ACP
User level application management.
- /dev/acpproc - Application management internal process
- /dev/acp_main - Application management main service
- /dev/emd - ?????
- /dev/pdm - Play data manager? (stores applications' statistics)
- /dev/nnsm - Nintendo Network service manager?
- /dev/nnmisc - Nintendo Network miscellaneous?
IOS-NSEC
Network security services. This uses OpenSSL, as of 5.5.0 this is: "OpenSSL 1.0.0f 4 Jan 2012".
- /dev/nsec - Network security
- /dev/nsec/nss - Network security services
- /dev/nsec/nssl - Network SSL API
IOS-NIM-BOSS
Nintendo's proprietary online services such as update installations. This uses statically-linked libcurl.
IOS-FPD
Nintendo's proprietary friend system. This uses statically-linked libcurl.
IOS-TEST
Debugging and testing services.
- /dev/testproc1 - Test process
- /dev/testproc2 - Test process
- /dev/iopsh - IOP shell?
- /dev/cbl - Cafe OS block log
- /debug/prof - Profiler (DEBUG mode only)
- /test/ppcprotviol - PPC protocol violation (TEST mode only)
- /test/sp - System profiler (TEST mode only)
- /test/test_rm - Resource manager test (TEST mode only)
IOS-AUXIL
Auxiliary services.
- /dev/auxilproc - Auxiliary service's internal process
- /dev/im - Home menu
- /dev/usr_cfg - User configuration
IOS-BSP
Hardware.
- /dev/bsp - Board support package? (hardware interface)
Others
These are not real /dev nodes. Instead, they represent internal mappings of system volumes created by the IOS-FS process as part of the virtual file system API's initialization.
The virtual file system API is able to map more than one instance of such volumes, whence why the final node name always has an integer representing it's instance (e.g.: 01).
- /dev/si01 - ?????
- /dev/slccmpt01 - NAND SLC (vWii compatible)
- /dev/slc01 - NAND SLC
- /dev/ramdisk01 - RAM disk
- /dev/mlc01 - NAND MLC
- /dev/hfio01 - Host file IO
- /dev/odd01 - Optical disk drive
- /dev/sdcard01 - SD card
- /dev/sd01 - ?????
- /dev/usb01 - USB device
- /dev/mlcorig01 - NAND MLC original?
- /dev/unknown01 - Unrecognized
Virtual Memory Map
| Virtual address range | Physical address range | Size | Description |
|---|---|---|---|
| 0x04000000 - 0x04030000 | 0x08280000 - 0x082B0000 | 0x30000 | IOS-CRYPTO |
| 0x05000000 - 0x050C0000 | 0x081C0000 - 0x08280000 | 0xC0000 | IOS-MCP |
| 0x05100000 - 0x05120000 | 0x13D80000 - 0x13DA0000 | 0x20000 | IOS-MCP (debug and recovery mode) |
| 0x08120000 - 0x081C0000 | 0x08120000 - 0x081C0000 | 0xA0000 | IOS-KERNEL |
| 0x10000000 - 0x10100000 | 0x10000000 - 0x10100000 | 0x100000 | PRSH/PRST |
| 0x10100000 - 0x104D0000 | 0x10100000 - 0x104D0000 | 0x3D0000 | IOS-USB |
| 0x10700000 - 0x11C40000 | 0x10700000 - 0x11C40000 | 0x1540000 | IOS-FS (5.5.1 retail) |
| 0x10800000 - 0x11EE0000 | 0x10800000 - 0x11EE0000 | 0x16E0000 | IOS-FS (5.3.2 debug) |
| 0x11F00000 - 0x12160000 | 0x11F00000 - 0x12160000 | 0x260000 | IOS-PAD |
| 0x12300000 - 0x12890000 | 0x12300000 - 0x12890000 | 0x590000 | IOS-NET |
| 0x1D000000 - 0x1FB00000 | 0x1D000000 - 0x1FB00000 | 0x2B00000 | Global heap |
| 0x1FB00000 - 0x1FE00000 | 0x1FB00000 - 0x1FE00000 | 0x300000 | Global IOB (input/output block) |
| 0x1FE00000 - 0x1FE20000 | 0x1FE00000 - 0x1FE20000 | 0x40000 | IOS-MCP (shared region) |
| 0x1FE40000 - 0x20000000 | 0x1FE40000 - 0x20000000 | 0x1C0000 | IOS-MCP (setup region) |
| 0x20000000 - 0x28000000 | 0x20000000 - 0x28000000 | 0x8000000 | RAMDISK |
| 0xE0000000 - 0xE0270000 | 0x12900000 - 0x12B70000 | 0x270000 | IOS-ACP |
| 0xE1000000 - 0xE12F0000 | 0x12BC0000 - 0x12EB0000 | 0x2F0000 | IOS-NSEC |
| 0xE2000000 - 0xE26D0000 | 0x12EC0000 - 0x13590000 | 0x6D0000 | IOS-NIM-BOSS |
| 0xE3000000 - 0xE3300000 | 0x13640000 - 0x13940000 | 0x300000 | IOS-FPD |
| 0xE4000000 - 0xE4160000 | 0x13A40000 - 0x13BA0000 | 0x160000 | IOS-TEST |
| 0xE5000000 - 0xE5070000 | 0x13C00000 - 0x13C70000 | 0x70000 | IOS-AUXIL |
| 0xE6000000 - 0xE6050000 | 0x13CC0000 - 0x13D80000 | 0xC0000 | IOS-BSP |
| 0xE7000000 - 0xE7001000 | |||
| 0xEFF00000 - 0xEFF08000 | 0xFFF00000 - 0xFFF08000 | 0x8000 | C2W (cafe2wii) boot heap |
| 0xFFFF0000 - 0xFFFFFFFF | 0xFFFF0000 - 0xFFFFFFFF | 0x10000 | Kernel SRAM / C2W (cafe2wii) |
The Starbuck MMU itself only has R/W permissions for data/instruction memory access, no XN. However, there is XN implemented via separate hardware registers at 0x0d8b0XXX. The register relative-offset is calculated with the physaddr of the memory being protected. Each u32 register corresponds to a different block of physical memory. Among other things, this controls whether the ARM is allowed to access the memory for instruction-access, and in what ARM-mode(userland/privileged) the instruction-access is permitted.
Hence, userland .text is only executable from userland. From userland, the only executable memory is the process .text. In privileged-mode, the only executable memory is the main kernel .text(0x08120000) and 0xffff0000(the latter is also RWX).
Exception Handling
The data-abort and prefetch-abort exception handlers will first check whether a certain flag is clear(flagsfield & (1<<PID)). When that bit is clear and the PID is <=13(highest IOSU PID value that exists), it will just return from the function then do a context-switch. Otherwise, iosPanic() is called.