IOS/Syscalls
< IOS
Internally, IOS uses a syscall table that is stored toward the end of the binary. The exact address varies with version of IOS; as a concrete example, boot2's syscall_base is at 0xFFFF7F60.
Syscalls are invoked by way of the invalid instruction handler; syscalls take the form 0xE6000010 | (syscall_num << 5). (E.g. E6000010 is syscall 0, E60006D0 is syscall 0x36, etc.)
tmbinc has written an IDAPython script which can take a database that has "syscall_base" defined, and transform the references to it into more meaningful things -- it is available here: IOS/Syscall_IDAPython
(please feel free to contribute your own findings!)
| ID # | Internal name | Description | Return value |
|---|---|---|---|
| 0 | u32 thread_create( u32 (*proc)(void* arg), u8 priority, u32* stack, u32 stacksize, void* arg, BOOL autostart) | Creates a thread | Returns threadid |
| 1 | thread_join | ||
| 2 | thread_cancel | ||
| 3 | get_tid | ||
| 4 | get_pid | ||
| 5 | thread_continue | ||
| 6 | thread_stop | ||
| 7 | thread_yield | ||
| 8 | thread_get_priority | ||
| 9 | thread_set_priority | ||
| a | message_queue_create | ||
| b | message_queue_destroy | ||
| c | message_queue_send | ||
| d | message_queue_send_now | ||
| e | message_queue_receive | ||
| f | RegisterEventHandler | ||
| 10 | UnregisterEventHandler | ||
| 11 | timer_create | ||
| 12 | timer_restart | ||
| 13 | timer_stop | ||
| 14 | timer_destroy | ||
| 15 | timer_now | ||
| 16 | heap_create | ||
| 17 | heap_destroy | ||
| 18 | heap_alloc | ||
| 19 | heap_alloc_aligned | ||
| 1a | heap_free | ||
| 1b | BOOL device_register(char* device, u32 messagequeue) | Registers device to the device tree, so it can be opened (from Starlet and PPC) | Returns 0 on success, else error |
| 1c | u32 device_open(char* device, int mode) | Similar to IOS_Open on PPC, except now internal to the IOS system | Returns an fd |
| 1d | device_close | ||
| 1e | device_read | ||
| 1f | device_write | ||
| 20 | device_seek | ||
| 21 | device_ioctl | ||
| 22 | device_ioctlv | ||
| 23 | device_open_async | ||
| 24 | device_close_async | ||
| 25 | device_read_async | ||
| 26 | device_write_async | ||
| 27 | device_seek_async | ||
| 28 | device_ioctl_async | ||
| 29 | device_ioctlv_async | ||
| 2a | syscall_2a | seems to set the return value of a received message | |
| 2b | SetUID | ||
| 2c | get_hmac_queue_for_pid | ||
| 2d | SetGID | ||
| 2e | lookup_GID_maybe | ||
| 2f | cc_ahbMemFlush | ||
| 30 | syscall_ahbMemFlush_wrapper | ||
| 31 | software_IRQ_31 | seems to enable hardware interrupts for device nr 31 | |
| 32 | software_irq_18 | seems to enable hardware interrupts for device nr 18 | |
| 33 | software_IRQ_7_or_8(id) | seems to enable hardware interrupts for device nr 7 if id==0, else device nr 8 | |
| 34 | software_IRQ(id) | seems to enable hardware interrupts for device nr. id | |
| 35 | _return_0 | ||
| 36 | syscall_36 | ||
| 37 | syscall_37 | ||
| 38 | iobuf_log_header_info | ||
| 39 | iobuf_log_buffer_info | ||
| 3a | syscall_3a | ||
| 3b | syscall_3b | ||
| 3c | syscall_3c | ||
| 3d | syscall_3d | ||
| 3e | syscall_3e | ||
| 3f | void sync_before_read(u32 address, u32 size) | Invalidates dcache, and something (probably related to flushing memory) | |
| 40 | sync_after_write | ||
| 41 | ppc_boot | ||
| 42 | ios_boot | ||
| 43 | syscall_43 | ||
| 44 | int syscall_assert_di_reset | Clears bit 10 of 0xD800194 | Returns 0 on success, -1 on error |
| 45 | int syscall_deassert_di_reset | Enables bit 10 of 0xD800194 | Returns 0 on success, -1 on error |
| 46 | BOOL syscall_check_di_reset | Checks bit 10 of 0xD800194 | Returns 1 on reset asserted, 0 on (deasserted or error) |
| 47 | zero_r0_r1 | ||
| 48 | set_r0_1_r1_0 | ||
| 49 | get_boot_vector | ||
| 4a | syscall_4a | ||
| 4b | kernel_debug_print | ||
| 4c | kernel_set_version | ||
| 4d | kernel_get_version | ||
| 4e | poke_E0_1 | ||
| 4f | virt_to_phys | ||
| 50 | syscall_50 | ||
| 51 | syscall_51 | ||
| 52 | syscall_52 | ||
| 53 | syscall_53 | ||
| 54 | syscall_54 | ||
| 55 | get_bc_flag | ||
| 56 | poke_gpios | ||
| 57 | syscall_57 | ||
| 58 | call_poke_debug_port | ||
| 59 | create_key | ||
| 5a | destroy_key | ||
| 5b | es_syscall_5b | ||
| 5c | es_syscall_5c | ||
| 5d | set_public_key | ||
| 5e | es_syscall_5e | ||
| 5f | es_syscall_5f | ||
| 60 | es_syscall_60 | ||
| 61 | get_keyid | ||
| 62 | es_syscall_62 | ||
| 63 | es_syscall_63 | ||
| 64 | sha_async | ||
| 65 | sha | ||
| 66 | aes_async | ||
| 67 | aes | ||
| 68 | es_syscall_68 | ||
| 69 | es_syscall_69 | ||
| 6a | es_syscall_6a | ||
| 6b | hmac | ||
| 6c | hmac_async | ||
| 6d | es_syscall_6d | ||
| 6e | get_ng_cert | ||
| 6f | key_set_permission_mask | ||
| 70 | es_syscall_70 | ||
| 71 | es_syscall_71 | ||
| 72 | es_syscall_72 | ||
| 73 | es_syscall_73 | ||
| 74 | es_syscall_74 | ||
| 75 | ?? | ||
| 76 | ?? |