Skip to content

driver: add RKUSBMaskromDriver bootstrap driver#1721

Open
Kwiboo wants to merge 4 commits intolabgrid-project:masterfrom
Kwiboo:rkusbmaskrom
Open

driver: add RKUSBMaskromDriver bootstrap driver#1721
Kwiboo wants to merge 4 commits intolabgrid-project:masterfrom
Kwiboo:rkusbmaskrom

Conversation

@Kwiboo
Copy link
Copy Markdown
Contributor

@Kwiboo Kwiboo commented Aug 27, 2025

Description

Add a RKUSBMaskromDriver bootstrap driver with an accompanying rkusbmaskrom agent to support bootstrapping targets with Rockchip SoCs.

The rkusbmaskrom agent expects the target to be in MASKROM mode and send images to BootROM using vendor specific 0x471 and 0x472 control transfers, in 4 KiB chunks.

The first image is loaded to SRAM using 0x471 and is expected to initialize DRAM and then return back to BootROM.
A second image can then be loaded to start of DRAM using 0x472.

The rkusbmaskrom agent also support extracting the needed 0x471 and 0x472 images from a vendor loader image, typically created with the vendor boot_merger tool from the rkbin repo, or idblock boot images, typically created with the U-Boot mkimage or the Barebox rkimage tools.

Related

Checklist

  • Documentation for the feature
  • The arguments and description in doc/configuration.rst have been updated
  • PR has been tested

Example usage

$ labgrid-client -v -c remote.yaml -p rk3528-radxa-e20c bootstrap u-boot-rockchip-usb472.bin
INFO               root: Selected role rk3528-radxa-e20c from configuration file
INFO         StepLogger:  → RKUSBMaskromDriver.load(filename='<path>/u-boot-rockchip-usb472.bin')
INFO    SSHConnection(h:   Created new SSH connection to noble
INFO    ManagedFile(loc:   Synchronizing <path>/u-boot-rockchip-usb471.bin to noble
INFO         StepLogger:   → ProcessWrapper.check_output(command=['rsync', ...])
INFO         StepLogger:   ← ProcessWrapper.check_output() result=b'' [0.073s]
INFO    ManagedFile(loc:   Synchronizing <path>/u-boot-rockchip-usb472.bin to noble
INFO         StepLogger:   → ProcessWrapper.check_output(command=['rsync', ...])
INFO         StepLogger:   ← ProcessWrapper.check_output() result=b'' [0.072s]
INFO         StepLogger:  ← RKUSBMaskromDriver.load() [3.001s]
INFO    SSHConnection(h:  Closing SSH connection to noble
$ labgrid-client -v -c remote.yaml -p rk3528-radxa-e20c console
INFO               root: Selected role rk3528-radxa-e20c from configuration file
INFO               root: microcom not available, using telnet instead
INFO               root: connecting to NetworkSerialPort(target=Target(name='rk3528-radxa-e20c', env=Environment(config_file='remote.yaml')), name='USBSerialPort', state=<BindingState.bound: 1>, avail=True, host='noble', port=57985, speed=1500000, protocol='rfc2217') calling telnet noble 57985
Connected to noble.
Escape character is '^]'.
DDR 56f70fd2ad huan.he 25/02/26-09:55:30,fwver: v1.11
LP4/4x derate e, other dram:1x trefi
ddrconfig:0
MID:0x6
LPDDR4, 324MHz
BW=32 Co=10 Bk=8 CS0 Row=16 CS=1 Die BW=16 Size=2048MB
...
out

U-Boot SPL 2025.10-rc2 (Aug 25 2025 - 22:27:40 +0000)
Trying to boot from RAM
## Checking hash(es) for config config-1 ... OK
## Checking hash(es) for Image atf-1 ... sha256+ OK
## Checking hash(es) for Image u-boot ... sha256+ OK
## Checking hash(es) for Image fdt-1 ... sha256+ OK
## Checking hash(es) for Image atf-2 ... sha256+ OK
## Checking hash(es) for Image atf-3 ... sha256+ OK
NOTICE:  BL31: v2.3():v2.3-912-gfe961b77f:derrick.huang, fwver: v1.20
NOTICE:  BL31: Built : 16:59:19, Mar 31 2025
INFO:    rk_otp_init finish!
INFO:    code: 0x28
INFO:    ARM GICv2 driver initialized
INFO:    nonboot_cpus_off: clst_st=0xc0e, core_st=0xe1e0 boot_cpu=0
INFO:    idle_st=0x0, pd_st=0x0
INFO:    Using opteed sec cpu_context!
INFO:    boot cpu mask: 1
INFO:    RK3528 SoC (0x101)
INFO:    BL31: Initializing runtime services
WARNING: No OPTEE provided by BL2 boot loader, Booting device without OPTEE initialization. SMC`s destined for OPTEE will return SMC_UNK
ERROR:   Error initializing runtime service opteed_fast
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x800000
INFO:    SPSR = 0x3c9


U-Boot 2025.10-rc2 (Aug 25 2025 - 22:27:40 +0000)

Model: Radxa E20C
SoC:   RK3528A
DRAM:  2 GiB
Core:  197 devices, 32 uclasses, devicetree: separate
MMC:   mmc@ffbf0000: 0, mmc@ffc30000: 1
Loading Environment from nowhere... OK
In:    serial@ff9f0000
Out:   serial@ff9f0000
Err:   serial@ff9f0000
Net:   eth0: ethernet@ffbe0000
Hit any key to stop autoboot: 0
=>
telnet> quit
Connection closed.

@codecov
Copy link
Copy Markdown

codecov bot commented Aug 28, 2025

Codecov Report

❌ Patch coverage is 63.18408% with 74 lines in your changes missing coverage. Please review.
✅ Project coverage is 45.5%. Comparing base (b94e172) to head (5369f81).
⚠️ Report is 38 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
labgrid/util/agents/rkusbmaskrom.py 55.3% 71 Missing ⚠️
labgrid/driver/usbloader.py 92.6% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           master   #1721     +/-   ##
========================================
+ Coverage    45.2%   45.5%   +0.3%     
========================================
  Files         174     175      +1     
  Lines       13752   13952    +200     
========================================
+ Hits         6224    6358    +134     
- Misses       7528    7594     +66     
Flag Coverage Δ
3.10 45.5% <63.1%> (+0.3%) ⬆️
3.11 45.5% <63.1%> (+0.3%) ⬆️
3.12 45.5% <63.1%> (+0.3%) ⬆️
3.13 45.5% <63.1%> (+0.3%) ⬆️
3.14 45.5% <63.1%> (+0.3%) ⬆️
3.9 45.6% <63.0%> (+0.3%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Kwiboo Kwiboo force-pushed the rkusbmaskrom branch 6 times, most recently from d011ad1 to c096575 Compare September 3, 2025 07:54
Comment thread doc/configuration.rst Outdated
Comment thread labgrid/driver/usbloader.py Outdated
Comment thread labgrid/driver/usbloader.py Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: use snagboot instead?

bootlin/snagboot#56 brings Rockchip support to snagboot.

The benefit is that other SoC vendors are supported by snagboot so we could have a snagboot driver to support multiple SoC vendors at once in labgrid.

This would also stop reimplementing the rockusb protocol in yet another project (hello rkdeveloptool, rockusb from rockchiprs, rkflashtool, snagboot, ...).

This was briefly discussed with @a3f @jluebbe at OSSEU/ELCE this year. Talking with snagboot's maintainer, there are plans to merge the Rockchip support for snagboot very soon and do a release soon after.

Copy link
Copy Markdown
Contributor Author

@Kwiboo Kwiboo Sep 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: use snagboot instead?

I will be using this agent/driver and not snagboot in my personal lab ;-)

bootlin/snagboot#56 brings Rockchip support to snagboot.

I will take a closer look little bit later and add some review comments, I can already see some issues in that implementation.

This would also stop reimplementing the rockusb protocol in yet another project (hello rkdeveloptool, rockusb from rockchiprs, rkflashtool, snagboot, ...).

All of those seem to have their own special issues, are not fully featured or can get stuck etc.
This driver works and only requires pyusb installed on the exporter, for my personal lab I do not want to deal with lots of third party tools ;-)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kwiboo Are you aware of a specific issue why snagboot couldn't work as well as this driver? They also use pyusb and no vendor-specific tool.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you aware of a specific issue why snagboot couldn't work as well as this driver? They also use pyusb and no vendor-specific tool.

@jluebbe snagboot does not support Rockchip, I did send review comments on the snagboot Rockchip PR, but there has not been any progress.

This is adding optimized and full featured support to ramboot all Rockchip boards in my labgrid boardfarm using a simple template:

targets:
  main:
    resources:
      RemotePlace:
        name: !template $LG_PLACE
    drivers:
      SerialDriver: {}
      LinkPiSmartHUBPowerDriver: {}
      RKUSBMaskromDriver:
        initial: rkmaskrom471
        image: rkmaskrom472
      BootstrapStrategy: {}

images:
  rkmaskrom471: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb471.bin
  rkmaskrom472: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb472.bin

options:
  coordinator_address: 'labgrid'

This works fine for my limited need and allows me to not have to deal with trying to bend yet another third party tools or system like snagboot and pdudaemon to work for my need.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jluebbe The original contributor for Rockchip support in snagboot doesn't seem to be active anymore since June 2nd last year, so I'm of the opinion we shouldn't wait for this hypothetical support in snagboot and go ahead with this here. If support comes along to snagboot in the future, then we can always deprecate this implementation here and switch to snagboot if we wanted to. What do you think?

Comment thread doc/configuration.rst
Comment on lines +2661 to +2663
RKUSBMaskromDriver:
initial: 'rkmaskrom471'
image: 'rkmaskrom472'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: is this compatible with Barebox?

Barebox seems to be generating only one binary which contains both "files". I think it'd make sense to support Barebox file format as well, which likely differs from U-Boot's (currently two separate files IIRC) or the binary generated by Rockchip's boot_merger?

@a3f any opinion on that maybe?

EDIT: I see that the next patch adds the implementation for reading the file from boot_merger, so I guess if we have a unique way of identifying Barebox's implementation that would work too. Still, wondering if we shouldn't simply use snagboot and implement stuff there if necessary?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Barebox seems to be generating only one binary which contains both "files". I think it'd make sense to support Barebox file format as well, which likely differs from U-Boot's (currently two separate files IIRC)

Barebox uses the IDBlock v2 format, i.e. same format that mkimage produce for TPL and SPL in U-Boot for RK35xx.
Will add an implementation for extracting images from the IDBlock v1 and v2 formats, thanks!

or the binary generated by Rockchip's boot_merger?

This format is supported with the second commit, one special thing that boot_merger does differently for RK35xx is that it adds an IDBlock v2 header for the 471 and 472 files referenced in the rkboot .ini-files.
However, this extra header does not seem to be required on all RK35xx SoCs I have tested.

Also the BootROM seem to use a much slower crc16 implementation, so validating a huge blob for i.e. U-Boot RAM boot can take several seconds.
Will send an updated Rockchip U-Boot RAM-boot series that take advantage of FIT compression along with relocation the FIT to the 2 MiB offset to help speed up RAM-boot.

Still, wondering if we shouldn't simply use snagboot and implement stuff there if necessary?

Feel free to implement and use a snagboot driver, I will be using this for my personal lab ;-)

Copy link
Copy Markdown
Contributor Author

@Kwiboo Kwiboo Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have now added a new commit with support for decoding the IDBlock v2 image format (both unsigned and signed) in addition to the loader image format.

With that added we should be able to use the Barebox output image or u-boot-rockchip.bin to at least boot into SPL on newer Rockchip SoCs.

Will run some more tests and add one more commit to add support for the legacy IDBlock image format to make this fully featured.

This will need to be tested some more on e.g. RK3576 where more than two idblock images is typically used to e.g. fixup booting from SD-card.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have now pushed one more commit with support for decoding the legacy IDBlock image format, the boot image format used for Rockchip SoCs prior to the RK35xx line.

With this I can now use something like the following labgrid-client command on my Rockchip boards:

labgrid-client -v -c remote.yaml -p rk3399-rock-4 bootstrap u-boot-rockchip.bin

And as expected, without a proper FIT available or SPL DFU working, U-Boot SPL will fail trying to bootstrap a plain U-Boot u-boot-rockchip.bin image:

U-Boot TPL 2025.10-rc5 (Sep 29 2025 - 19:04:10)
lpddr4_set_rate: change freq to 400MHz 0, 1
Channel 0: LPDDR4, 400MHz
BW=32 Col=10 Bk=8 CS0 Row=15 CS=1 Die BW=16 Size=1024MB
Channel 1: LPDDR4, 400MHz
BW=32 Col=10 Bk=8 CS0 Row=15 CS=1 Die BW=16 Size=1024MB
256B stride
lpddr4_set_rate: change freq to 800MHz 1, 0
Trying to boot from BOOTROM
Returning to boot ROM...

spl:init dram

U-Boot SPL 2025.10-rc5 (Sep 29 2025 - 19:04:10 +0000)
board_spl_was_booted_from: failed to resolve brom_bootdevice_id a
Trying to boot from MMC1
mmc_load_image_raw_sector: mmc block read error
Error: -38
Trying to boot from MMC2
Card did not respond to voltage select! : -110
spl: mmc init failed with error: -95
Error: -95
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as expected, without a proper FIT available or SPL DFU working, U-Boot SPL will fail trying to bootstrap a plain U-Boot

In u-boot-rockchip.bin, there's a FIT already. But I'm assuming since its information is not stored in the idblock header, we cannot know where to look for it in the file? Do you think it'd be possible to find where in the file the FIT binary is (without elaborate and error-prone guessing)? We do have binman symbols available in SPL so maybe there's something to do with that.

I'm wondering if another option isn't to generate a u-boot-rockchip-usb.bin in that format (or maybe rather the one from boot_merger?) in U-Boot. I'm assuming this is why you wanted to have the ability to upload to 0x472 directly with the first patch in this PR, so you can directly use u-boot-rockchip-usb472.bin generated by U-Boot without having to go through boot_merger or mkimage?

Comment thread labgrid/util/agents/rkusbmaskrom.py Outdated
@Kwiboo Kwiboo force-pushed the rkusbmaskrom branch 2 times, most recently from 1838792 to d4626c9 Compare February 6, 2026 17:47
@Kwiboo Kwiboo force-pushed the rkusbmaskrom branch 2 times, most recently from b5d5459 to 361549d Compare February 15, 2026 14:50
Add a RKUSBMaskromDriver bootstrap driver with an accompanying
rkusbmaskrom agent to support bootstrapping targets with Rockchip SoCs.

The rkusbmaskrom agent expects the target to be in MASKROM mode and send
images to BootROM using vendor specific 0x471 and 0x472 control
transfers, in 4 KiB chunks.

The first image is loaded to SRAM using 0x471 and is expected to
initialize DRAM and then return back to BootROM. A second image can then
be loaded to start of DRAM using 0x472.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Add support for using vendor loader image files, typically created using
the vendor boot_merger tool in the rkbin repo.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Add support for using vendor idblock v2 image files, typically created
using the U-Boot mkimage or Barebox rkimage tools.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Add support for using vendor idblock v1 image files, typically created
using the U-Boot mkimage tool.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
@QSchulz
Copy link
Copy Markdown
Contributor

QSchulz commented Feb 16, 2026

General comments.

As far as I understood this supports many things:

  1. Raw binaries (typically 471 and 472 binaries from U-Boot), rkusbmaskrom.py agent will handle "encrypting" for old SoCs and upload them.
  2. boot_merger binary. Typically what you generate from https://github.com/rockchip-linux/rkbin. This will extracts the files from within that binary and upload them.
  3. mkimage -T rksd binaries for newer SoCs (idblock v2; idbloader.img in U-Boot). Also used by barebox. Extracts the binaries defined in the header and upload them.
  4. mkimage -T rksd binaries for older SoCs (idblock v1; idbloader.img in U-Boot). Extracts the binaries defined in the header and upload them.

I am not sure we absolutely need 1. We could ask the user to generate binaries with boot_merger or mkimage -T rksd and not have to support this. This also means everything we upload now has a header and we can check that instead of having either a path or a bytearray to know if we're in case 1. or the others like done here: 7abb766#diff-4717e427bdffde63a29a83ebf945dd18f8e5caf30896ef89f71f303891a66cecR178

If I understood patch 1 in the PR, 1. requires two binaries, initial (471) and image (471 if no initial, otherwise 472) but we can only override one with the .load() method. In the U-Boot case, this means you'll not easily be able to test the TPL as that isn't supposed to be changed as it's not part of the API. Imagine from a U-Boot maintainer perspective trying to make sure that everything works with a TPL blob from Rockchip and the DRAM init open-source implementation in U-Boot as a replacement. Or simply testing a newer version of the TPL blob or DRAM init open-source implementation before merging. I think this is another reason for pushing the user to use a single binary (either generated by boot_merger, mkimage -T rksd or rkimage), it simplifies the code and makes the interface for the user much easier to understand and play with. Or maybe I'm missing something, it's been a long time since I had a look at labgrid :/ The labgrid-client bootstrap command also seems to support passing multiple additional args so I guess an option for recovering could be to pass a second parameter which would be initial (471) such that image (472) is passed to .load(). Feels wrong to me though, so probably not something to pursue.

If I understood correctly, 3. and 4. are only actually usable with U-Boot if using SPL_DFU or entering rockusb (how?) from SPL, or if a FIT is already on a storage medium somewhere the SPL can find it. So not really an option for recovering a device as part of a strategy for example. I think it's nice for Barebox though! My understanding is that we would gain the ability to boot a Barebox for rk3188 and rk3288 (the only old SoCs supported by Barebox right now I believe).

Once this PR is merged, I think we need to revamp RKUSBDriver entirely to split the logic of uploading a binary over USB to BootROM (db command of rkdeveloptool) and flashing (wl command, right now forced to offset 64 even, which prevents me from flashing the SPI-NOR on my RK3399 Puma :) ). The db part will be handled by this RKUSBMaskromDriver added here, but then we'll need something to allow reflashing the eMMC/SPI-NOR/UFS from a USB-loaded bootloader. DFU should already be supported so that's an option I guess. USB load a RAM-only binary and start dfu with a UbootDriver/Bareboxdriver. I guess we should also think about supporting rockusb such that it works with rkdeveloptool and old blobs from Rockchip (rkbin git repo). We need to specify an offset and medium to flash to though. But that's a problem for later I think :)

I'll give this a try tomorrow once I'm in office and have access to my neglected labgrid desktop :)

Jonas, thanks again for all the work you do on Rockchip.

Comment thread doc/configuration.rst Outdated
Comment on lines +2721 to +2722
- image (str): optional, key in :ref:`images <labgrid-device-config-images>` containing the path
of a bootloader image to load to start of DRAM, or to SRAM when an initial image is unused
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (non-blocking): specify this can be overridden at runtime

The user can actually override (or provide if none is provided in the conf) the image via the load(filename: str) method of the BootstrapProtocol class.

But we cannot change initial.

Comment thread doc/configuration.rst
Comment on lines +2693 to +2694
An :any:`RKUSBMaskromDriver` is used to upload an image into a device in the
*Rockchip USB Maskrom state*.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: confusing documentation

This states that we're expecting the device to be in the USB Maskrom state while we bind to an RKUSBLoader which

describes a USB device in the Rockchip loader state.

and we even check here: c091cde#diff-4717e427bdffde63a29a83ebf945dd18f8e5caf30896ef89f71f303891a66cecR89 that we are NOT in the LOADER state. So which is which?

Comment thread doc/configuration.rst
Comment on lines +2661 to +2663
RKUSBMaskromDriver:
initial: 'rkmaskrom471'
image: 'rkmaskrom472'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And as expected, without a proper FIT available or SPL DFU working, U-Boot SPL will fail trying to bootstrap a plain U-Boot

In u-boot-rockchip.bin, there's a FIT already. But I'm assuming since its information is not stored in the idblock header, we cannot know where to look for it in the file? Do you think it'd be possible to find where in the file the FIT binary is (without elaborate and error-prone guessing)? We do have binman symbols available in SPL so maybe there's something to do with that.

I'm wondering if another option isn't to generate a u-boot-rockchip-usb.bin in that format (or maybe rather the one from boot_merger?) in U-Boot. I'm assuming this is why you wanted to have the ability to upload to 0x472 directly with the first patch in this PR, so you can directly use u-boot-rockchip-usb472.bin generated by U-Boot without having to go through boot_merger or mkimage?

@Kwiboo
Copy link
Copy Markdown
Contributor Author

Kwiboo commented Feb 16, 2026

  1. Raw binaries (typically 471 and 472 binaries from U-Boot), rkusbmaskrom.py agent will handle "encrypting" for old SoCs and upload them.

I am not sure we absolutely need 1. We could ask the user to generate binaries with boot_merger or mkimage -T rksd and not have to support this.

This 1. part is the main reason why I added this in the first place 😄, to be able to use the plain u-boot-rockchip-usb471/usb472.bin files without having to run a separate tool/script to generated some intermediate image format that immediately needs to be decoded and unpacked.

Mostly added support for format 2., 3., and 4. on your request and to be fully compatible with all known RK image formats that a user may want to send to the device.

I am only using the 1. part from this, with following labgrid template to ramboot into my boards:

targets:
  main:
    resources:
      RemotePlace:
        name: !template $LG_PLACE
    drivers:
      SerialDriver: {}
      LinkPiSmartHUBPowerDriver: {}
      RKUSBMaskromDriver:
        initial: rkmaskrom471
        image: rkmaskrom472
      BootstrapStrategy: {}

images:
  rkmaskrom471: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb471.bin
  rkmaskrom472: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb472.bin

And run labgrid-client using something like following:

export LG_COORDINATOR=<coordinator>
export LG_PLACE=<board>
~/labgrid/bin/labgrid-client -v -c ~/labgrid/ramboot-template.yaml -s cycle console

To be more precise I am using something closer to https://github.com/Kwiboo/scripts/blob/main/labgrid.sh so that I can simplify my U-Boot (and Linux) dev workflow with something like following:

./u-boot.sh rk3588-rock-5b && ./labgrid.sh rk3588-rock-5b -s cycle bootstrap -

while having another terminal constant connected to the serial console of the board for interaction:

./labgrid.sh rk3588-rock-5b lock
./labgrid.sh rk3588-rock-5b console

@Kwiboo
Copy link
Copy Markdown
Contributor Author

Kwiboo commented Feb 17, 2026

If I understood patch 1 in the PR, 1. requires two binaries, initial (471) and image (471 if no initial, otherwise 472) but we can only override one with the .load() method. In the U-Boot case, this means you'll not easily be able to test the TPL as that isn't supposed to be changed as it's not part of the API. Imagine from a U-Boot maintainer perspective trying to make sure that everything works with a TPL blob from Rockchip and the DRAM init open-source implementation in U-Boot as a replacement.

Correct, this PR does not try to make any assumptions or enforcement on how the user wants to use it, it can be used with initial and image in the configuration/template or by supplying a single image to bootstrap/.load().

The labgrid-client bootstrap command also seems to support passing multiple additional args so I guess an option for recovering could be to pass a second parameter which would be initial (471) such that image (472) is passed to .load(). Feels wrong to me though, so probably not something to pursue.

My primary need (based on my limited knowledge of labgrid) is to use the initial and image configuration in a template, the addition of .load() was to try and make it work as best as possible with existing commands and protocols. Something that currently require supplying a single image if I am not mistaken. Updating the bootstrap command to allow none or multiple images is not something I want to touch in this PR without having better understanding of how labgrid-client commands or protocols are used.

I even sometime (ab)use the labgrid-client bootstrap command to force a bootstrap of the files from the initial and image configuration by supplying a file that does not exists, -. The command fails to transfer the non-existing file but continues to boot using the image file:

> bin/labgrid-client -v -c ramboot-template.yaml -s cycle bootstrap -
INFO               root: Selected role main from configuration file
INFO               root: Transitioning into state cycle
INFO         StepLogger:  → BootstrapStrategy.transition(status='cycle')
INFO         StepLogger:   → LinkPiSmartHUBPowerDriver.off()
INFO         StepLogger:   ← LinkPiSmartHUBPowerDriver.off() [0.037s]
INFO         StepLogger:   → LinkPiSmartHUBPowerDriver.get()
INFO         StepLogger:   ← LinkPiSmartHUBPowerDriver.get() [0.211s]
INFO         StepLogger:   → LinkPiSmartHUBPowerDriver.on()
INFO         StepLogger:   ← LinkPiSmartHUBPowerDriver.on() [0.994s]
INFO         StepLogger:   → RKUSBMaskromDriver.load(filename=None)
INFO    SSHConnection(h:    Created new SSH connection to panther
INFO    ManagedFile(loc:    Synchronizing /srv/u-boot/rk3566-zero-3w/u-boot-rockchip-usb471.bin to panther
INFO    ManagedFile(loc:    Synchronizing /srv/u-boot/rk3566-zero-3w/u-boot-rockchip-usb472.bin to panther
INFO         StepLogger:   ← RKUSBMaskromDriver.load() [1.376s]
INFO         StepLogger:  ← BootstrapStrategy.transition() [8.205s]
INFO         StepLogger:  → RKUSBMaskromDriver.load(filename='-')
INFO    ManagedFile(loc:   Synchronizing /srv/u-boot/rk3566-zero-3w/u-boot-rockchip-usb471.bin to panther
INFO         StepLogger:  ⚠ RKUSBMaskromDriver.load() [0.092s] exception=Local file /home/kwiboo/- not found
INFO    SSHConnection(h:  Closing SSH connection to panther

If I understood correctly, 3. and 4. are only actually usable with U-Boot if using SPL_DFU or entering rockusb (how?) from SPL, or if a FIT is already on a storage medium somewhere the SPL can find it.

Correct, this only make it possible to transfer binary blobs encoded in common RK image formats to the BootROM and does not impose any restriction or make assumptions on what the blobs/images are used for.

I use u-boot-rockchip-usb471/usb742.bin (with some extra .config-fragments) to fully boot boards in my boardfarm into Linux using boot_tragets=pxe from U-Boot proper. And I suppose that if you want to load a device into some sort of flashing-mode that is also possible but will require special configuration of e.g. U-Boot.

@QSchulz
Copy link
Copy Markdown
Contributor

QSchulz commented Feb 23, 2026

  1. Raw binaries (typically 471 and 472 binaries from U-Boot), rkusbmaskrom.py agent will handle "encrypting" for old SoCs and upload them.

I am not sure we absolutely need 1. We could ask the user to generate binaries with boot_merger or mkimage -T rksd and not have to support this.

This 1. part is the main reason why I added this in the first place 😄, to be able to use the plain u-boot-rockchip-usb471/usb472.bin files without having to run a separate tool/script to generated some intermediate image format that immediately needs to be decoded and unpacked.

Mostly added support for format 2., 3., and 4. on your request and to be fully compatible with all known RK image formats that a user may want to send to the device.

Oh well, I had forgotten but seems like my opinion hasn't changed since :D

I am only using the 1. part from this, with following labgrid template to ramboot into my boards:

Considering you're parsing the file generated by boot_merger... How difficult would it be to implement an rkusb type in mkimage such that we generate an rkdeveloptool-compatible image? It would help get rid of the awkwardness around handling two binaries (471 and 427) in labgrid (and encourage people using it outside of labgrid too). I'm not asking you to do it, I'm just wondering if I'm missing something. What stands out are the _PARAM INI sections (BOOT0_PARAM, BOOT1_PARAM, LOADER2_PARAM, etc...). I'm assuming the LOADER ones aren't necessary, only for the LOADER_OPTION section which I'm assuming is only needed with rkdeveloptool ul? I'm assuming we can carry something similar to the RKBOOT ini files but in DTS for binman?

targets:
  main:
    resources:
      RemotePlace:
        name: !template $LG_PLACE
    drivers:
      SerialDriver: {}
      LinkPiSmartHUBPowerDriver: {}
      RKUSBMaskromDriver:
        initial: rkmaskrom471
        image: rkmaskrom472
      BootstrapStrategy: {}

images:
  rkmaskrom471: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb471.bin
  rkmaskrom472: /srv/u-boot/$LG_PLACE/u-boot-rockchip-usb472.bin

FYI, the BootstrapStrategy is not in this MR (could find it in your rockchip branch). (Stating this in case anyone wants to try this out)

[...]

If I understood patch 1 in the PR, 1. requires two binaries, initial (471) and image (471 if no initial, otherwise 472) but we can only override one with the .load() method. In the U-Boot case, this means you'll not easily be able to test the TPL as that isn't supposed to be changed as it's not part of the API. Imagine from a U-Boot maintainer perspective trying to make sure that everything works with a TPL blob from Rockchip and the DRAM init open-source implementation in U-Boot as a replacement.

Correct, this PR does not try to make any assumptions or enforcement on how the user wants to use it, it can be used with initial and image in the configuration/template or by supplying a single image to bootstrap/.load().

I'm a bit confused by labgrid choices sometimes. My understanding is that you need the environment (the one with targets like above) on the client-side. Considering this is where you define the images to use, you necessarily need the binary client-side as well (or is there some trick I'm unaware of?)... So what's the use-case of passing an argument to the bootstrap command if we need an environment file which defines the files to bootstrap anyway? I'm asking because I frankly see as a blocker only being able to override RKUSBMaskromDriver:image from the CLI if RKUSBMaskromDriver:initial is set. This is the kind of awkwardness I was talking about earlier.

The labgrid-client bootstrap command also seems to support passing multiple additional args so I guess an option for recovering could be to pass a second parameter which would be initial (471) such that image (472) is passed to .load(). Feels wrong to me though, so probably not something to pursue.

My primary need (based on my limited knowledge of labgrid) is to use the initial and image configuration in a template, the addition of .load() was to try and make it work as best as possible with existing commands and protocols. Something that currently require supplying a single image if I am not mistaken. Updating the bootstrap command to allow none or multiple images is not something I want to touch in this PR without having better understanding of how labgrid-client commands or protocols are used.

Yeah but we cannot decide to not support load() at all since we're designing a BootstrapProtocol here.

I even sometime (ab)use the labgrid-client bootstrap command to force a bootstrap of the files from the initial and image configuration by supplying a file that does not exists, -. The command fails to transfer the non-existing file but continues to boot using the image file:

Yeah, I was also very confused upon reading bootstrap command from labgrid-client actually requires a file... Why? It's already in the env (use that one, and if it isn't in the env, then tell the user?). I think we're missing some use-cases that warranted this kind of split.

[...]

If I understood correctly, 3. and 4. are only actually usable with U-Boot if using SPL_DFU or entering rockusb (how?) from SPL, or if a FIT is already on a storage medium somewhere the SPL can find it.

Correct, this only make it possible to transfer binary blobs encoded in common RK image formats to the BootROM and does not impose any restriction or make assumptions on what the blobs/images are used for.

OK. I'm assuming this could be useful to Barebox where they have SPL+proper (or whatever their terms are :) ) concatenated into one big binary if I remember correctly. Limited use for upstream U-Boot so far.

I use u-boot-rockchip-usb471/usb742.bin (with some extra .config-fragments) to fully boot boards in my boardfarm into Linux using boot_tragets=pxe from U-Boot proper. And I suppose that if you want to load a device into some sort of flashing-mode that is also possible but will require special configuration of e.g. U-Boot.

You should be able to simply control the console via the UbootDriver from a strategy once you're able to reach proper's CLI and make it enter DFU/fastboot/rockusb/rkmtd/tftp/you name it. For use with rockusb, we'll need a new driver in labgrid though, not sure if we need a new labgrid-client command (see dfu and fastboot) or if we can hook ourselves as a USBStorageDriver maybe.. Who knows. Maybe labgrid people would rather see us use an external tool (rkdeveloptool, rockusb) rather than reimplement this here. But again, to be able to support writing to flash until the device is supported upstream we don't have a choice aside from rockusb protocol I believe.

For what it's worth, I tested on PX30, RK3399 and RK3588 option 1. (slow on RK3399, likely due to BootROM having a slow CRC16 implementation according to you; it uploads decently fast but then takes some time to boot into SPL (the first part of our upstream U-Boot 472 payload), and option 3. for RK3588, and option 4. for PX30. All do what they must.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants