# Rockbox — AGENTS.md Rockbox is an open-source firmware replacement for digital audio players, written in C. It runs on dozens of devices (iPods, Sansas, iRivers, Cowons, Android, Linux handhelds, etc.) and provides a complete UI, codec support, plugins, games, themes, and more. --- ## Build & Development ### Standard build flow ```sh # From the rockbox source root: mkdir build && cd build ../tools/configure # interactive - select target, debug/sim/release make # builds the firmware make zip # packages into rockbox.zip ``` ### Simulator build Select `[Simulator]` target in configure, or choose a target then select **simulation** when prompted. The resulting binary `rockboxui` simulates the target on your host machine using SDL. It reads files from a `simdisk/` subdirectory. ```sh mkdir build-sim && cd build-sim ../tools/configure # pick a target, then choose Simulation make ./rockboxui # requires simdisk/ with sample files ``` ### Make targets | Target | Description | |--------|-------------| | `make` | Build firmware binary | | `make zip` | Create `rockbox.zip` (the installable package) | | `make fullzip` | Include fonts in the zip | | `make fontzip` | Fonts-only zip | | `make 7zip` / `full7zip` / `font7zip` | Same but as .7z | | `make install` | Install build to `PREFIX` (default `simdisk/` for sims, `/usr/local` for SDL apps) | | `make voice` | Generate voice files (needs TTS configured) | | `make manual` | Build PDF manual | | `make clean` | Clean build output | | `make veryclean` | Clean build output and tool binaries | | `make tags` | Generate `TAGS` file for editors | ### List supported targets ```sh perl tools/list_targets.pl ``` ### Cross-compiler setup ```sh # Install the toolchain for your target architecture: # This script builds cross-compilers for all supported architectures. tools/rockboxdev.sh ``` ### Configuring cross-compilers The `tools/configure` script auto-detects cross-compilers based on known prefixes. Key functions that set compiler options per architecture in the configure script: - `coldfirecc` → `m68k-elf-gcc` - `arm7tdmicc` / `arm9tdmicc` / various ARM variants → `arm-elf-eabi-gcc` or `arm-none-eabi-gcc` - `mipscc` → `mipsel-elf-gcc` The script defines `GCCOPTS`, `GCCOPTIMIZE`, `endian`, and `gccchoice` for each. ### Hosted/Application builds (Linux DAPs, Android) Some modern targets (Hiby, Fiio, Sony NWZ, Samsung YPR, Android, etc.) use a hosted/application build mode. These are configured via `APP_TYPE` and linked against system libraries rather than running on bare metal. The `firmware/target/hosted/` tree contains platform-specific code. --- ## Code Organization ### Top-level directory structure ``` rockbox/ ├── apps/ # User interface, playback engine, settings, plugins, GUI │ ├── gui/ # WPS, list, viewport, statusbar, splash, skin engine │ ├── plugins/ # Games, demos, tools (each gets PLUGIN_BUFFER_SIZE) │ ├── recorder/ # Recording UI │ ├── radio/ # FM radio UI │ ├── lang/ # Language/translation files (.lang v2 format) │ ├── keymaps/ # Key bindings per target (keymap-.c) │ ├── menus/ # Menu structure │ └── settings_list.c # Master list of all settings (huge file) ├── firmware/ # Hardware abstraction layer, kernel, drivers │ ├── export/ # Public API headers (config.h, lcd.h, audio.h, button.h, etc.) │ ├── include/ # Internal headers │ ├── drivers/ # LCD, storage, audio codec, touchscreen, I2C, USB drivers │ ├── kernel/ # Threading, mutexes, semaphores, queues, timers │ ├── target/ # Architecture-specific + board-specific code │ │ ├── arm/ # ARM-native targets (iPod, Sansa, iRiver, etc.) │ │ ├── mips/ # MIPS-native targets (Ingenic JZ47xx, X1000) │ │ ├── coldfire/ # Coldfire-native (iAudio) │ │ └── hosted/ # Hosted/application targets (SDL sim, Android, Linux DAPs) │ └── libc/ # Minimal embedded libc (for native targets) ├── lib/ # Shared libraries │ ├── rbcodec/ # Codec + metadata + DSP (can be reused outside Rockbox) │ │ ├── codecs/ # Individual decoder/encoder implementations │ │ ├── dsp/ # Digital signal processing │ │ └── metadata/ # Metadata parsers │ ├── skin_parser/ # WPS/skin theme parser │ ├── tlsf/ # TLSF memory allocator │ ├── fixedpoint/ # Fixed-point math library │ └── ... ├── bootloader/ # Bootloader code per target ├── tools/ # Build scripts, code generators, host utilities │ ├── configure # The main interactive configuration script │ ├── root.make # Top-level Makefile includes this │ ├── functions.make # Common build functions (preprocess, c2obj, etc.) │ └── builds.pm # Target database used by configure ├── uisimulator/ # Simulator UI rendering (SDL-based) ├── docs/ # Documentation, credits, license ├── fonts/ # Bitmap fonts (BDF format) ├── wps/ # WPS/theme files (.wps, .sbs, .fms) ├── backdrops/ # Background images for themes ├── icons/ # Tango icon set and generation scripts ├── manual/ # User manual (LaTeX source) ├── android/ # Android port (Java + NDK) └── utils/ # Host-side utility programs ├── rbutilqt/ # Rockbox Utility (Qt-based installer for desktop) ├── ipodpatcher/ ├── sansapatcher/ ├── mkimxboot/ ├── hwstub/ # Hardware debugging stub └── ... ``` ### Build system architecture The build system is custom **GNU Make** with no CMake/autotools: 1. **`tools/configure`** — shell script, interactive. Generates `Makefile` in the build directory. 2. **`Makefile`** — thin, includes `tools/root.make`. 3. **`tools/root.make`** — main build rules. Sources are listed in `SOURCES` files per directory. 4. **`tools/functions.make`** — helper functions (`preprocess`, `c2obj`, `mkdepfile`, etc.) 5. **Per-directory `.make` files** — `firmware.make`, `apps.make`, `uisimulator.make`, `plugins.make`, `codecs.make`, etc. 6. **`SOURCES` files** — declare which `.c` files to build for each subsystem, using C preprocessor conditionals (`#ifdef`, `#ifndef`). Key function: `$(call preprocess, )` — runs the C preprocessor on a `SOURCES` file to conditionally include files based on target configuration defines. ### Configuration headers - **`firmware/export/config.h`** — Master config header. Includes `autoconf.h` (generated by configure). Defines symbolic constants for storage types, CPU types, keypads, LCD types, charging modes, platforms (`PLATFORM_NATIVE`, `PLATFORM_HOSTED`, `PLATFORM_ANDROID`), etc. - **`firmware/export/config_caps.h`** — Converts capability bitmasks into `HAVE_*` defines (e.g., `HAVE_MIC_IN`, `HAVE_LINE_IN`). - **`firmware/export/config/.h`** — Target-specific config (one per device model). Contains defines like `HAVE_RTC`, `CONFIG_TUNER`, LCD dimensions, button mappings, memory sizes. - **`autoconf.h`** — Generated by `tools/configure` in the build directory. --- ## Application Architecture & Data Flow ### Layered architecture ``` ┌─────────────────────────────────────────────────┐ │ apps/ (UI, playback logic, plugins, menus) │ │ ├── main.c → entry point │ │ ├── tree.c → file browser │ │ ├── playlist.c → playlist management │ │ ├── playback.c → audio playback engine │ │ ├── settings.c → persistent settings │ │ ├── screens.c → screen navigation │ │ ├── gui/wps.c → While-Playing Screen │ │ └── gui/skin_engine/ → theme/WPS rendering │ ├─────────────────────────────────────────────────┤ │ lib/rbcodec/ (codecs, DSP, metadata) │ │ ├── codecs/ → audio decoders/encoders │ │ ├── dsp/ → EQ, crossfeed, etc. │ │ └── metadata/ → tag parsers │ ├─────────────────────────────────────────────────┤ │ firmware/ (kernel, drivers, HAL) │ │ ├── kernel/ → threading, timers, IPC │ │ ├── drivers/ → LCD, storage, audio codec │ │ ├── target/ → CPU + board specific code │ │ └── libc/ → minimal C library │ └─────────────────────────────────────────────────┘ ``` ### Startup flow 1. **`apps/main.c`** → `main()` — initializes kernel, drivers, storage, mounts filesystem, loads settings, initializes audio, loads plugins, then enters the main event loop (`screens.c`). 2. Event loop dispatches to the file browser (`tree.c`), WPS (`gui/wps.c`), or menus (`menu.c`, `screens.c`) via action handling (`action.c`, `button.h`). 3. Playback is managed by `playback.c` which coordinates `buffering.c`, `pcmbuf.c`, `codec_thread.c`, and the codec in `lib/rbcodec/codecs/`. ### Thread model (native targets) - **Main thread** — UI, event handling - **Codec thread** (`codec_thread.c`) — audio decoding - **Buffering thread** (`buffering.c`) — file I/O and buffering - **Voice thread** (`voice_thread.c`) — TTS voice rendering - **USB thread** — USB stack handling - **Tick task** — kernel timer callback for periodic tasks Built on the kernel in `firmware/kernel/thread.c` (cooperative + priority-based preemptive threads). ### Key subsystems - **Plugin system** (`apps/plugin.c`) — Plugins run in a pre-allocated `pluginbuf[]` buffer (`PLUGIN_BUFFER_SIZE`). They access Rockbox APIs through a dispatch table. - **Skin engine** (`apps/gui/skin_engine/`) — Renders `.wps` / `.sbs` / `.fms` theme files. Supports conditional tags, viewports, images, progress bars, etc. - **TagCache** (`apps/tagcache.c`) — Database of audio metadata for database browsing (`tagtree.c`). - **Settings** (`apps/settings.c`, `apps/settings_list.c`) — All settings defined in one massive file. Persisted in `.rockbox/config.cfg`. - **Language system** (`apps/lang/`, `apps/language.c`) — `.lang` files are compiled to `.lng` binaries. `genlang` tool processes them. --- ## Code Conventions From the project's `CONTRIBUTING` document: - **Language**: C (C11, `-std=gnu11`). Avoid assembly unless necessary. - **Identifiers**: Lowercase for variables and functions, `snake_case`. Macros/enum constants: `UPPER_CASE`. No mixed case. - **Comments**: `/* C style */` only. No `//` comments. Use `#if 0` to comment out blocks. - **Braces**: Function definitions have the brace on a new line. Otherwise, follow the style of the file being edited. - **Indentation**: 4 spaces, **no tabs**. - **Line length**: Keep under 80 columns. - **No typedefs for structs/enums**: `struct foo` not `Foo` or `foo_t`. - **No code in `.h` files** or `#define` functions. - **File encoding**: UTF-8 (but prefer ASCII). Unix line endings (LF). ### Style patterns observed in source ```c /* Header comments use the standard ASCII-art banner */ #include "config.h" /* Always first include */ #include "system.h" /* Function definitions: brace on new line */ int my_function(struct foo *bar) { return bar->value; } /* Static functions first, used without forward declarations */ static int internal_helper(struct foo *bar) { ... } /* Macros are UPPER_CASE */ #define MY_BUFFER_SIZE 4096 /* struct names: lower case, often typedef-free */ struct my_struct { int field; }; ``` ### Compiler flags (from `tools/configure`) ``` CFLAGS: -W -Wall -Wextra -Wundef -Os -nostdlib -ffreestanding -Wstrict-prototypes -pipe -std=gnu11 -funit-at-a-time -fno-delete-null-pointer-checks -fno-strict-overflow -fno-common ``` --- ## Testing There is no comprehensive test suite. The project has: - **`firmware/test/buflib/`** — unit tests for the buflib memory allocator (buildable in-tree) - **`lib/rbcodec/test/`** — codec/DSP tests - **`tools/checkwps/`** — WPS/skin syntax validation tool - **Simulator** is the primary testing tool — run `rockboxui` to test UI changes - Bug reports are handled via the tracker at rockbox.org --- ## File Patterns & Important Decisions ### Preprocessor-driven builds **This is the most important pattern in the codebase.** Source files are **conditionally compiled** based on target capability defines (`HAVE_*`, `CONFIG_*`). A file called `SOURCES` (in each directory) is preprocessed by `$(CC) -E` to determine which files to include. Example pattern (`firmware/SOURCES`): ```c #ifdef HAVE_RTC drivers/rtc/rtc-.c #endif #ifdef HAVE_TAGCACHE tagcache.c /* in apps/ */ #endif ``` When adding a new source file, add it to the relevant `SOURCES` file (NOT to a Makefile directly). ### Target-specific code organization ``` firmware/target//// ``` Examples: - `firmware/target/arm/sandisk/sansa-clip/` - `firmware/target/coldfire/iriver/h100/` - `firmware/target/hosted/sdl/` (simulator) - `firmware/target/hosted/android/` (Android port) Key mapping files: `apps/keymaps/keymap-.c` Config headers: `firmware/export/config/.h` ### Settings system All settings (global, playback, sound, etc.) are defined in `apps/settings_list.c`. The pattern is: ```c /* In settings_list.c, settings are registered with type info */ OFFON_SETTING(0, "usb_hid", DEFAULT, ...) INT_SETTING(0, "volume", 100, ...) ``` ### Codec system Codecs live in `lib/rbcodec/codecs/`. Each codec is a standalone `.codec` file loaded at runtime. They communicate with Rockbox through a simple API defined in `codecs.h`. The codec engine in `apps/codecs.c` loads and manages them. ### Plugin API Plugins use a fixed-size buffer (`pluginbuf[]`). The API is documented in `docs/PLUGIN_API` (auto-generated). Plugins are `.rock` files loaded by `apps/plugin.c`. --- ## Git & Review Process - **Code review**: Changes go through Gerrit (rockbox.org). See `docs/CONTRIBUTING` and [UsingGit](https://www.rockbox.org/wiki/UsingGit). - **AI-generated code policy** (from `CONTRIBUTING`): The project is highly unlikely to accept AI-generated or "vibe coded" code. If submitting AI-generated code, include full prompt provenance (model, dates, prompt content, unedited output). - **Commit credits**: Contributors are credited by full real name — no pseudonyms. - **Mailing list / IRC**: Support channels for questions. - **Project repository**: `git://git.rockbox.org/rockbox` --- ## Gotchas & Non-Obvious Facts 1. **Never add source files to Makefiles directly.** Use `SOURCES` files with preprocessor conditionals. The build system uses `$(call preprocess, ...)` to evaluate them. 2. **The `config.h` include must always be first** in every `.c` file. It includes `autoconf.h` which sets all platform defines. 3. **No runtime library**: Native targets use `firmware/libc/` — no glibc. No `stdio.h`, `malloc`, etc. in most native code. Use `core_alloc.c` (buflib) instead. 4. **`HAVE_*` defines are targetspecific**, set in `firmware/export/config/.h`. Do not assume a feature exists unless guarded by `#ifdef`. 5. **The configure script is interactive** — there is no non-interactive mode (no `--target` flag). For automated builds, pipe input into it. 6. **Platform constants** (`PLATFORM_NATIVE`, `PLATFORM_HOSTED`, `PLATFORM_ANDROID`) are bit flags, not mutually exclusive. Check with `(CONFIG_PLATFORM & PLATFORM_HOSTED)` not `#ifdef`. 7. **APP_TYPE** is used for hosted/application builds. It can be `sdl-sim`, `sdl-app`, `android`, `checkwps`, `database`, `warble`, `ctru`, or a target-specific type like `sonynwz`, `hibylinux`, etc. 8. **The `tools/configure` script operates on CPU architecture, manufacturer, and model** — target selection goes through a hierarchy: CPU → manufacturer → model → variant (debug vs release vs simulator). 9. **`features.txt`** in `apps/` gates which menu strings appear in the build. Adding a `HAVE_*` define isn't enough — you must also add a `features.txt` entry if the feature needs UI strings. 10. **Symbols in `.codec` and `.rock` files are resolved at load time** against the Rockbox core, which has a limited export surface defined in `codecs.h` and `plugin.h`. 11. **Fonts are BDF format** and compiled via `convbdf`. The system font is selected by `SYSFONT` (default: `08-Schumacher-Clean`). --- ## Standing Orders (Crush-specific) ### Build & Distribute (3DS/ctru) - Build dir: `/home/themoon/randomclone/rockbox/build` - Build command: `cd build && echo "290" | PATH=/opt/devkitpro/devkitARM/bin:/opt/devkitpro/tools/bin:$PATH ../tools/configure` then `PATH=/opt/devkitpro/devkitARM/bin:/opt/devkitpro/tools/bin:$PATH make -j$(nproc)` - Upload and QR code only when explicitly asked — user tests in emulator - A successful build is assumed to work on hardware ### Git Remote (copyparty) - Remote name: `copyparty` → `https://k:Ionm_2k4@copyparty.poggers.website/rockbox/.git` - Read-only dumb HTTP protocol — **push does not work** (copyparty has no git smart HTTP) - Remote is also human-browsable at `https://copyparty.poggers.website/rockbox/` - rclone config at `~/.config/rclone/rclone.conf` (remote name `copyparty`, webdav) - To update the remote after committing locally: ```sh cd /home/themoon/randomclone/rockbox git update-server-info rclone sync . copyparty:rockbox/ \ --exclude "build/**" --exclude ".3DS-SDcard/**" --exclude ".crush/**" \ --exclude "*.o" --exclude "*.a" --exclude "*.elf" --exclude "*.exe" --exclude "*.so" \ --transfers 8 --checkers 16 --progress ```