Rockchip RK3588
The RK3588 is the second SoC the wrong-loader gate is armed for. Every fact on this page is
measured on one board, the NanoPi R6S, unless a tag says otherwise. The R6S carries an RK3588S,
which is the RK3588 in a smaller package, and its loader answers as an RK3588. On another RK3588
or RK3588S board, each fact is [UNVERIFIED] until that board confirms it.
Identity
| Fact | Value |
|---|---|
| USB ID, in maskrom and in loader mode | 2207:350b |
chipver reply | 38 38 35 33 and 12 bytes of 0xff, which reads “8853” |
| Chip field of an RKBOOT container built for it | 38 38 35 33 |
--soc name | rk3588 |
The chipver reply opens with the SoC’s four ASCII digits, byte-reversed, as on the RK3576. The
12 bytes after them differ, because an RK3576 loader sends zeros there. Whether those bytes come
from the SoC or from the loader build is [UNVERIFIED]. The gate compares the whole reply, so it
refuses a loader that pads differently until a board pins that reply.
Maskrom
The BootROM presents 2207:350b with an even bcdUSB flag and no string descriptors. The
usbplug loader in FriendlyELEC’s MiniLoaderAll.bin keeps the same ID and the same even flag. It
adds the strings RockChip, USB-MSC and rockchip. The mode column in list reads maskrom
for both. The verbs settle it with a probe command, as
Listing devices describes.
db --loader MiniLoaderAll.bin uploads 166 KiB in under half a second. The usbplug loader comes
back at a new address within the same second. An RK3576 takes somewhat over three seconds.
The usbplug loader hung once, straight after an upload. It enumerated, then answered no command
and no standard USB request until the board was power-cycled. A second upload ran cleanly for
the rest of the session. The cause is [UNVERIFIED]. If every command after an upload reports
maskrom, power-cycle the board into maskrom and upload again.
The usbplug loader
The usbplug loader serves every query pyrographer sends, and capability reports 3f 07. That
sets read LBA and new IDB, along with two bits pyrographer has no name for.
The loader puts the reply’s length, big-endian, where the CSW reports the bytes left untransferred. pyrographer reads a value larger than the request as carrying no accounting. It checks the reply’s length directly instead.
Reads through this loader reach the last sector of the eMMC, with no constant fill. One command served 648 sectors.
Writes through it land and read back. A 168 MiB flash from sector 0 took 16.8 seconds, with
every window read back and compared. A verify through a fresh open then matched the whole
image. reset in its default mode reboots the board, which leaves the bus at once.
NanoPi R6S
The NanoPi R6S is a router board with an RK3588S.
| Fact | Value |
|---|---|
| eMMC | 60620800 sectors of 512 bytes (28.91 GiB) |
Flash ID that info reports | 45 4d 4d 43 20, which reads “EMMC “ |
Medium that storage reports | eMMC |
| Loader used | The usbplug in MiniLoaderAll.bin, from FriendlyELEC’s RK3588 eflasher image |
Entering maskrom
Hold the MASK button and apply power [DOC]. Connect a USB A-to-A cable from the host to the
board’s USB 3.0 Type-A port. On the other Type-A port, the host sees nothing at all. The board
keeps its own USB-C supply throughout, and the A-to-A cable carries data.
Reading
A dump of three ranges matched a raw read byte for byte. The ranges were the first 64 sectors,
the 648 sectors from sector 64, and the last 33 sectors of the eMMC.
OpenWrt
The R6S boots OpenWrt 25.12.5 written to its eMMC from maskrom, as Flashing a disk image from maskrom describes.
| Fact | Value |
|---|---|
| Image | openwrt-25.12.5-rockchip-armv8-friendlyarm_nanopi-r6s-squashfs-sysupgrade.img.gz |
| Unpacked size | 176160768 bytes (344064 sectors) |
| Partition table | MBR: a 16 MiB boot partition at sector 65536, and a 104 MiB root at sector 131072 |
| Boot chain | An RKNS ID block at sector 64, and a U-Boot FIT at sector 16384 |
A write took 16.8 seconds with its read-back, and a verify took 17.7 seconds.