Skip to content

Services, kernel objects and input

The runtime implements one local process with explicit service commands and checked TLS transport. Unknown commands fail with endpoint/header context; unavailable service names return SRV NotFound d88067fa. No generic-success stubs or asynchronous service directory are provided. CPU threads and memory define scheduling and backing ownership.

TLS, SRV and CFG

ARM MRC p15,0,Rd,c13,c0,3 reads the current thread's user read-only TLS address. Rd=PC, writes and other unsupported CP15 operations fault. The external adapter refreshes TLS at every execution entry so thread changes cannot retain stale TLS.

Interface Request Behavior
ConnectToPort 2d r1: checked NUL-terminated srv: Result in r0, generation-tagged SRV session in r1
SendSyncRequest 32 r0: session; command at TLS+0x80 Checked synchronous request/reply; SVC and service results are separate
SRV RegisterClient 00010002, PID descriptor 20, placeholder Registers the session; reply 00010040
SRV GetServiceHandle 00050100, name[8], length, flags 0/1 Opens supported named service; move descriptor 10
CFG SecureInfoGetRegion 00020000 Configured region
CFG GetSystemModel 00050000 Configured Old-family model
CFG GetModelNintendo2DS 00060000 0 for Old2DS, 1 otherwise
CFG GetConfigInfoBlk2 00010082, size 1, language block 000a0002, descriptor 1c/1e, output One configured language byte

ctr_guest_configure accepts region 0..6, language 0..11 and Old-family models 0 (Old3DS), 1 (Old3DS XL), 3 (Old2DS), before service access. Defaults are USA (1), English (1), Old3DS (0). Values are emulated policy, not inferred console settings. New-family models, notifications, user/server IPC, arbitrary descriptors, cross-process mappings and general CFG/Mii behavior are unsupported.

The 64-word command buffer is read/written as little-endian words. Reserved bits, word counts, descriptor shapes and full permissions are checked before effects. Mapped outputs cannot overlap the command buffer, including through aliases. The 64-slot generation table holds typed handles, including 16 session objects. Duplicate, stale, wrong-type and exhausted handles fail; closing SRV leaves already acquired service sessions alive.

Shared memory and synchronization

SVC Contract
CreateMemoryBlock 1e Zero source creates local zeroed backing; nonzero pins one contiguous owned RW heap allocation
MapMemoryBlock 1f Checked local aliases in [0x10000000,0x14000000)
UnmapMemoryBlock 20 Exact mapped address; releases the mapping reference
CreateMutex 13 / ReleaseMutex 14 Owner-aware recursive mutex with checked release
CreateSemaphore 15 / ReleaseSemaphore 16 Nonnegative count, positive signed maximum, bounded release; previous count in r1
WaitSynchronization 24 Event/mutex/semaphore/join acquisition or deferred timeout
WaitSynchronizationN 25 Up to 16 handles; wait-any index or atomic wait-all

Pools allow eight shared objects, 16 mutexes and 16 semaphores. Shared objects allow four mappings within the 32-fragment memory limit. Owned backing shares the combined 64 MiB budget; pinned heap is charged once. Own alias permissions must be a subset of object rights; other permissions match policy or DONTCARE 10000000. None/read/write/read-write are supported. Failed mapping preserves memory and references. Mapped objects survive final-handle close; pinned source allocations cannot be freed/reprotected before their last reference releases. Aliases report QueryMemory Shared state 6. Foreign-process and general GPU/DSP physical backing are absent.

Wait references survive handle closure. Wait-any consumes the first ready object in caller order. Wait-all preflights every object, rejects duplicates and returns index ffffffff; timeout uses the same index. Wait-any duplicates are accepted. Invalid requests consume nothing. Negative timeouts are infinite; finite overflow fails. Mutex owner exit releases its locks. Priority inheritance, pulse events and cross-process synchronization are unsupported.

Standard HID

hid:USER GetHandles request 000a0000 replies 000a0047, result 0, copy descriptor 14000000 and six typed handles: a shared page plus Pad0/Pad1, accelerometer, gyro and debug events. The last three events have no producer. Motion enable/disable, other HID commands, hid:SPVR, IRRST and New-family input fail. The device retains its six internal handles; returned copies and read-only mappings follow normal lifetime rules. Exhaustion rolls back allocations.

ctr_hid_update publishes physical button bits 0..11, Circle Pad axes -156..156 and valid touch coordinates within 320×240. Direction bits 28..31 use radius 40 and diagonal sectors; clients derive touch bit 20. ZL/ZR, C-stick, motion, slider and raw calibration are absent. Invalid values/nonincreasing timestamps publish nothing.

The eight-entry LE pad ring stores index at 0x10, current buttons at 0x1c and 16-byte entries from 0x28: held/added/removed/packed signed XY. Touch index is at 0xb8; eight-byte entries from 0xc8 store packed unsigned XY/validity. Indexes advance together. At index 0 wrap, current/previous timestamps at 0/8 and 0xa8/0xb0 use the 268111856 Hz guest tick scale. Pad0/Pad1 signal after publication. One host thread prevents concurrent partial reads.

VPAD maps to Old-family button bits; the left stick scales to ±156 and touch passes through the bottom-screen viewport. Diagnostic Plus/Minus/Y remain host controls, and Minus exits before publishing its press. The displayed right stick is not exposed as New-family input.

Validation and interface sources

make -C tests/services check sanitize
make -C tests/kernel check sanitize
make -C tests/hid check sanitize
python3 tools/validate-upstream.py --service-api --kernel-api --hid-api --output artifacts/service-check

Original ARM fixtures compare full state/memory through interpreter and both AOT paths. API checks cover wire layouts, complete preflight, stale/wrong handles, lifetimes, aliasing, rollback, waits, ring transitions and exhaustion. Public interface facts were checked against libctru 9b55eda44cf80b971503991e0c78f9bc8fe50425; no upstream implementation was copied. GSP/display, filesystem/APT and audio document the other service boundaries.


Maintained source: docs/services.md · 3849a94bd97b. GitHub source and issue links may require repository access.