Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rockchip RK3576

The RK3576 is one of two SoCs the wrong-loader gate is armed for. Every fact on this page is measured on one board, the H96 Max M9, unless a tag says otherwise. On another RK3576 board, each fact is [UNVERIFIED] until that board confirms it.

Identity

FactValue
USB ID, in maskrom and in loader mode2207:350e
chipver reply36 37 35 33 and 12 zero bytes, which reads “6753”
Chip field of an RKBOOT container built for it36 37 35 33
--soc namerk3576
Start of DRAM0x40000000
Serial console1500000 baud

The chipver reply is the SoC’s four ASCII digits, byte-reversed. db --soc rk3576 checks a container’s chip field before an upload, and --soc rk3576 checks the chipver reply before a write.

Maskrom

The BootROM is part of the SoC, so no write to storage removes maskrom mode. A board in maskrom presents the same USB ID, interface and bulk endpoints as a loader. Its endpoints serve nothing, so the verbs tell the two apart by sending a probe command.

rkbin’s SPL loader keeps the even bcdUSB flag that maskrom presents. On this SoC, the mode column in list therefore cannot tell maskrom from that loader, as Listing devices describes.

Two loaders boot from maskrom:

  • rk3576_spl_loader_v1.12.108.bin from rkbin, which serves rockusb
  • Mainline U-Boot v2026.04, built with CONFIG_ROCKCHIP_MASKROM_IMAGE and packed with boot_merger, which RAM-booting mainline U-Boot from maskrom covers

The BootROM accepts a corrupt upload and discards it without reporting an error. Bringing a maskrom board to loader mode describes how that failure appears, and how to retry.

The ID block

The values in this section are measured from rkbin’s rk3576_spl_loader_v1.12.108.bin, not on the board. Whether the board boots from the ID block they describe is [UNVERIFIED].

The container carries four flash stages. Each is stored scrambled per 512-byte block, and the container’s RC4 flag is set, so the flash holds them unscrambled. Unscrambled, FlashHead is an RKNS header, and the rest are the images it describes:

ImageStageSectorSectorsLoads at
0FlashBoost880x3ffc0000
1FlashData161600x3ff81000
2FlashBoot176528none

The header fills sectors 0 to 7, so the ID block is 704 sectors, written from sector 64. The header records each image’s SHA-256, and a SHA-256 of its own first 1536 bytes. Every one of them matches. FlashData is the DRAM init, byte for byte the 471 stage db uploads.

rkdeveloptool’s ul writes a different block from this container. It joins FlashHead, FlashData and FlashBoot, and leaves out FlashBoost. That puts the DRAM init at sector 8 and the SPL at sector 168, where the header says 16 and 176. write-idb and flash-firmware lay the block out as the header says, as Writing the ID block alone describes.

Writing the ID block needs a loader that claims NEW_IDB in its capability reply. Whether rkbin’s SPL loader claims it is [UNVERIFIED].

H96 Max M9

The H96 Max M9 is an Android TV box.

FactValue
eMMCSamsung, 244285440 sectors of 512 bytes (116.48 GiB)
Flash ID that info reports45 4d 4d 43 20, which reads “EMMC “
Partition tableGPT, with Android’s 16 partitions
The eMMC under mainline U-Bootmmc 0, at mmc@2a330000

Under mainline U-Boot, mmc 1 is an empty slot, and mmc info on it reports Card did not respond to voltage select! : -110.

Entering maskrom

If the eMMC clock line is shorted to ground at power-on, the BootROM enters maskrom whatever the eMMC holds [DOC]. Which mode the box’s hidden button enters is [UNVERIFIED].

The 32 MiB read wall

Through a rockusb loader, the H96 Max M9 answers every read at or past sector 65536 (32 MiB) with constant 0xCC and a success status. Two loaders do this: rkbin’s SPL loader and the factory U-Boot’s own rockusb gadget. The eMMC holds real data there. U-Boot’s mass-storage gadget and its mmc read command both read the whole eMMC.

Keep a read through rockusb wholly below sector 65536. A read that crosses it can return fill for its sectors below the wall as well. Through the factory gadget, a 16-sector dump from sector 65528 returned 0xCC for all 16 sectors.

The first 65536 sectors hold the partition table and the boot chain, from the ID block at sector 64 through vbmeta. A dump of them covers everything a bootloader write can break:

pyrographer dump 0 65536 first-32mib.img

dump warns of constant fill wherever it finds a run, as Constant-fill warnings describes. To read the whole eMMC, RAM-boot mainline U-Boot and dump through its mass-storage gadget, as the maskrom guide describes. Whether other RK3576 boards share the wall is [UNVERIFIED].