Architecture¶
Chikuma's structure is not a design decision. Structure follows the firmware, not our taste -- if the layering here differs from the image's, this one is wrong. HFS and HFS+ are one driver in the original, so they are one driver here.
The hardware¶
| SoC | Samsung S5L8702, ARM926EJ-S, ARMv5TEJ |
| Cores | one -- the dual-core arrangement in Rockbox is PortalPlayer, a different device |
| DRAM | 64 MB at 0x08000000 |
| SRAM | 256 KB at 0x22000000 |
| Boot ROM | 64 KB at 0x20000000 |
| Peripherals | from 0x38000000 |
| Audio | sm1 at 0x38500000, a bus-mastering hardware decoder |
The MMU is on in RetailOS, with translation tables at 0x2200c000. Early emulator work assumed
physical addressing and was wrong about it.
The layers¶
UI views, text, the archive-driven screen builder, controllers
---------------------------------------------------------------------
media library model, artwork, playback, video
---------------------------------------------------------------------
drivers ATA, FAT16, HFS+, display pipe, I2C, PMU, wheel, AES, sm1
---------------------------------------------------------------------
kernel RTXC: tasks, timers, events, mutexes, heap, service dispatch
Each is described on its own page:
- Kernel -- the RTXC reproduction and the task table
- Storage -- the disk, and why the filesystem never calls it directly
- Display and UI -- the pipe, and screens that build themselves from the archive
- Audio and video -- a decoder in silicon, not in software
Where the data lives¶
Two things in the image matter more than any single function:
The resource archive carries the UI as records -- 27 sections, class names, screen definitions, menu items, event bindings, colours, strings. This is why screens can build themselves.
The name table maps 3,869 names to ids and sits before the archive. It is how a screen names another screen. An extraction that starts at the wrong offset silently loses a span of names, and every push into that span then fails quietly -- which is exactly the bug behind the unreachable Extras screens today.
Memory: how RetailOS allocates¶
Recovered by call signature -- every BL whose preceding instruction loads a constant into r0,
counted by distinct constant per target. One target dominates with 1,938 calls and 116 different
sizes, which is what an allocator looks like and nothing else does.
It is a boundary-tag allocator of the dlmalloc family: the request is rounded up by 4, an 8-byte
header added, the block floored at 0x10 and aligned to 8, with the size in bits 2..29 of the
header and flags in the low two bits.
There is more than one heap. The allocator takes a heap descriptor with its own state and its
own lock, and the device's diagnostics screen confirms the split -- it has rows for Heap Size,
Free Size, Requested Reserve Heap Size and Free Reserve Heap Size. A reserve heap kept apart
from the main one is how a device stops a failed allocation from taking the UI down.
What is not on the heap matters as much. RTXC's own objects are statically generated. Timer and event blocks come from a pool; one service goes further and carves a task timer's block out of that task's own stack, costing no allocation at all. Display surfaces are handed out by the display side, large and long-lived.
That is the design Chikuma copies: not one global heap, but heap objects with locks, several instances, a reserve, and pools for the things with predictable lifetimes.
Text and locale¶
- UTF-8 everywhere. Searched three ways:
Zurückappears five times as UTF-8 and zero times as Mac Roman or Latin-1. There is no legacy-encoding conversion layer to reproduce. - No wchar layer at all -- no
wcslen, nombstowcs, nowcharsymbol in the image. The firmware keeps UTF-8 bytes and decodes when it needs a codepoint. - The UTF-16 and UCS-2 strings that are in the image belong to SQLite, which ships inside RetailOS and is used for Genius.
- Dates and times are bespoke, not ICU. The firmware carries a city table with offsets, and daylight saving is a setting the user toggles rather than a rule looked up from a database -- which is exactly what the device's own UI does. Reproducing it needs a city table and a strftime, not a timezone database.