rockbox/firmware/target
Marcin Bukat a0c1085f3f rk27xx: add the Scheme A FTL
ftl-rk27xx.c has been four empty stubs since 2010. Fill them in with
the flash translation layer the rk2705/rk2706 original firmware uses,
called Scheme A here to tell it from the log-structured layout of later
firmware. It reads and writes that format exactly as the original
firmware does, so a device keeps working with its original firmware
after Rockbox has written to it.

- ftl-scheme-a.{c,h}: the FTL. The file opens with a description of
  the on-flash format and how the FTL works: the SYS and USER volumes,
  super-blocks and zones, the zone table, the remap log and its mirror,
  the exchange record and the write protocol, power-loss recovery, bad
  blocks. Oddities of the original firmware kept for compatibility are
  marked where they are.
- Parameters that differ between firmware builds - the zone reserve
  base, the system zone offset, the format flag - are recovered from
  the media at mount and checked against its structure; a mount that
  cannot confirm them is read-only. A mount that would have to repair
  the remap log while not allowed to write fails rather than serve
  wrong data.
- ftl-rk27xx.c: the storage glue. It finds the boot area's ID block,
  which records where SYS ends, and mounts the FTL.
- ata-nand-rk27xx.c: a drive per volume. SYS holds the original
  firmware - on a Rockbox device including the BASE.RKW that chainloads
  the bootloader - and nothing of the user's, so it is a drive only when
  the target defines HAVE_RK27XX_NAND_SYS. Capacity comes from the FTL's
  tables, not from raw block geometry.
- config.h: HAVE_STORAGE_FLUSH for the rk27xx NAND. The FTL holds up to
  three part-written pages in RAM; storage_flush() commits them at
  shutdown and ROLO.

Writing is opt-in: without FTL_ALLOW_WRITE the FTL mounts read-only and
never writes the flash, not even a repair the mount could make.

Two bugs of the original firmware are not reproduced. A write starting
before a page held part-written in RAM and running through it left two
buffers holding that page, and the older one was later programmed over
the newer data; such a write now flushes the held page first. And its
bad-block marker took two of its three metadata bytes from the stack,
which can make a retired block look like a remap-log block; the marker
is now written in full.

Tested in a host simulator on NAND images of a Samsung YP-CP3 and a
generic rk2705, against the original firmware's FTL object run under
qemu-arm: identical traces of every read, program and erase, with a
hash of the data each program writes, over mounting and reading, random
writes with every sector verified, a power cut at every flash operation
of a write, and a program or erase failure at every one.

On a generic rk2705: the read-only mount reports the layout and
capacities the original firmware does and every file's MD5 matches; a
write test passes 8192/8192 across a remount and a power cycle.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: I573d944389cefb456ecf38c6c7b91bebfe0fe377
2026-10-01 12:15:25 +02:00
..
arm rk27xx: add the Scheme A FTL 2026-10-01 12:15:25 +02:00
coldfire firmware: move iriver flash helper functions into target tree 2026-09-23 13:44:45 -04:00
hosted Add "rbfs" prefix to native filesystem functions 2026-09-17 16:22:31 -04:00
mips usb: let controller drivers handle SET_ADDRESS requests 2026-09-26 13:23:01 -04:00