Line 4:
Line 4:
*[[IOSU_Syscalls|IOSU Syscalls]]
*[[IOSU_Syscalls|IOSU Syscalls]]
−
==Architecture==
+
== 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).
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===
+
=== 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).
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.
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.
Line 15:
Line 15:
This loader then does the following:
This loader then does the following:
- Clear it's own small stack;
- Clear it's own small stack;
−
- Set 0x20 in LT_MEMIRR register (if not set already);
+
- Set 0x20 in HW_SRNPROT register (if not set already);
- Fetch e_phnum from the IOSU's ELF header;
- Fetch e_phnum from the IOSU's ELF header;
- Loop through the ELF's program header structs;
- Loop through the ELF's program header structs;
Line 23:
Line 23:
- Branch to 0xFFFF0000 (IOSU kernel boot).
- Branch to 0xFFFF0000 (IOSU kernel boot).
−
===Kernel===
+
=== Kernel ===
After being parsed by it's own ELF loader, the IOSU's kernel is launched from the Wii U's SRAM (0xFFFF0000).
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's kernel follows a standard ARM microkernel architecture:
Line 83:
Line 83:
// Disable boot0 mapping
// Disable boot0 mapping
−
r0 <- 0x0D80018C // LT_BOOT0
+
r0 <- 0x0D80018C // HW_SPARE1
−
r1 <- 0x00(LT_BOOT0)
+
r1 <- 0x00(HW_SPARE1)
r1 <- r1 | 0x1000
r1 <- r1 | 0x1000
−
0x00(LT_BOOT0) <- r1
+
0x00(HW_SPARE1) <- r1
// MSR CPSR_c, #0xD3 -> Enter supervisor mode, FIQ/IRQ disabled
// MSR CPSR_c, #0xD3 -> Enter supervisor mode, FIQ/IRQ disabled
Line 236:
Line 236:
[[IOSU_Syscalls|System calls]] are handled through the ARM undefined handler and mapped into their respective kernel functions.
[[IOSU_Syscalls|System calls]] are handled through the ARM undefined handler and mapped into their respective kernel functions.
−
===Threads===
+
=== 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).
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
// Thread struct in memory
Line 306:
Line 306:
Bit 2 in the flags determines whether or not the thread has an IPC buffer pool.
Bit 2 in the flags determines whether or not the thread has an IPC buffer pool.
−
===Heaps===
+
=== 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).
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).
Line 390:
Line 390:
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.
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===
+
=== 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() [[Cafe_OS_Kernel_Syscalls|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/IPC|hardware interface]], and marshalled by the IOSU kernel to a target process. An example of IOSU IPC from the PowerPC can be found [https://github.com/darksideos/darkside-kernel/blob/wiiu/bal/src/platform/wiiu/ios.c here].
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() [[Cafe_OS_Kernel_Syscalls|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/IPC|hardware interface]], and marshalled by the IOSU kernel to a target process. An example of IOSU IPC from the PowerPC can be found [https://github.com/darksideos/darkside-kernel/blob/wiiu/bal/src/platform/wiiu/ios.c here].
Line 471:
Line 471:
Arg3 = vector
Arg3 = vector
−
===Error codes===
+
=== Error codes ===
Kernel errors
Kernel errors
Line 519:
Line 519:
0xFFFFFFD6 -> IOS_ERROR_UNKNOWN_VALUE
0xFFFFFFD6 -> IOS_ERROR_UNKNOWN_VALUE
−
==Modules==
+
== Modules ==
Similarly to the Wii, IOS modules roughly map to processes and drivers inside the kernel. Modules have a locked PID associated with them:
Similarly to the Wii, IOS modules roughly map to processes and drivers inside the kernel. Modules have a locked PID associated with them:
Line 595:
Line 595:
PIDs 14-21 are used for PPC side processes.
PIDs 14-21 are used for PPC side processes.
−
===IOS-CRYPTO===
+
=== IOS-CRYPTO ===
Cryptography services.
Cryptography services.
*[[:/dev/crypto]] - Cryptography API
*[[:/dev/crypto]] - Cryptography API
−
===IOS-MCP===
+
=== IOS-MCP ===
Master title operations such as title launching and [[:cafe2wii]] booting.
Master title operations such as title launching and [[:cafe2wii]] booting.
Line 613:
Line 613:
*[[:/dev/ppc_kernel]] - PPC kernel service
*[[:/dev/ppc_kernel]] - PPC kernel service
−
===IOS-USB===
+
=== IOS-USB ===
USB controllers and devices.
USB controllers and devices.
Line 624:
Line 624:
*[[:/dev/usb_midi]] - USB musical instrument digital interface
*[[:/dev/usb_midi]] - USB musical instrument digital interface
−
===IOS-FS===
+
=== IOS-FS ===
File system services.
File system services.
Line 647:
Line 647:
*[[:/dev/timetrace]] - File IO time tracer
*[[:/dev/timetrace]] - File IO time tracer
−
===IOS-PAD===
+
=== IOS-PAD ===
Gamepad controllers and devices.
Gamepad controllers and devices.
Line 660:
Line 660:
*[[:/dev/usb/early_btrm]] - Secondary Bluetooth module
*[[:/dev/usb/early_btrm]] - Secondary Bluetooth module
−
===IOS-NET===
+
=== IOS-NET ===
Network services.
Network services.
Line 679:
Line 679:
*[[:/dev/dlp]] - 3DS Download Play hosting, used by nn_dlp.rpl.
*[[:/dev/dlp]] - 3DS Download Play hosting, used by nn_dlp.rpl.
−
===IOS-ACP===
+
=== IOS-ACP ===
User level application management.
User level application management.
Line 689:
Line 689:
*[[:/dev/nnmisc]] - Nintendo Network miscellaneous?
*[[:/dev/nnmisc]] - Nintendo Network miscellaneous?
−
===IOS-NSEC===
+
=== IOS-NSEC ===
Network security services. This uses OpenSSL, as of 5.5.0 this is: "OpenSSL 1.0.0f 4 Jan 2012".
Network security services. This uses OpenSSL, as of 5.5.0 this is: "OpenSSL 1.0.0f 4 Jan 2012".
Line 696:
Line 696:
*[[:/dev/nsec/nssl]] - Network SSL API
*[[:/dev/nsec/nssl]] - Network SSL API
−
===IOS-NIM-BOSS===
+
=== IOS-NIM-BOSS ===
Nintendo's proprietary online services such as update installations. This uses statically-linked libcurl.
Nintendo's proprietary online services such as update installations. This uses statically-linked libcurl.
Line 702:
Line 702:
*[[:/dev/boss]] - BOSS service
*[[:/dev/boss]] - BOSS service
−
===IOS-FPD===
+
=== IOS-FPD ===
Nintendo's proprietary friend system. This uses statically-linked libcurl.
Nintendo's proprietary friend system. This uses statically-linked libcurl.
Line 708:
Line 708:
*[[:/dev/act]] - Authentication account library
*[[:/dev/act]] - Authentication account library
−
===IOS-TEST===
+
=== IOS-TEST ===
Debugging and testing services.
Debugging and testing services.
Line 720:
Line 720:
*[[:/test/test_rm]] - Resource manager test (TEST mode only)
*[[:/test/test_rm]] - Resource manager test (TEST mode only)
−
===IOS-AUXIL===
+
=== IOS-AUXIL ===
Auxiliary services.
Auxiliary services.
Line 727:
Line 727:
*[[:/dev/usr_cfg]] - User configuration
*[[:/dev/usr_cfg]] - User configuration
−
===IOS-BSP===
+
=== IOS-BSP ===
Hardware.
Hardware.
*[[:/dev/bsp]] - Board support package? (hardware interface)
*[[:/dev/bsp]] - Board support package? (hardware interface)
−
===Others===
+
=== 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.<br>
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.<br>
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).
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).
Line 749:
Line 749:
*[[:/dev/unknown01]] - Unrecognized
*[[:/dev/unknown01]] - Unrecognized
−
==Virtual Memory Map==
+
== Virtual Memory Map ==
*0x04000000 - 0x04030000 '''IOS-CRYPTO'''
*0x04000000 - 0x04030000 '''IOS-CRYPTO'''
*0x05000000 - 0x050C0000 '''IOS-MCP'''
*0x05000000 - 0x050C0000 '''IOS-MCP'''
Line 777:
Line 777:
*0xEFF00000 - 0xEFF08000 '''Unknown'''
*0xEFF00000 - 0xEFF08000 '''Unknown'''
*0xFFFF0000 - 0xFFFFFFFF '''Kernel SRAM'''
*0xFFFF0000 - 0xFFFFFFFF '''Kernel SRAM'''
−
Line 784:
Line 783:
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).
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==
+
== 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.
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.