nuttx icon indicating copy to clipboard operation
nuttx copied to clipboard

[FEATURE] raspberrypi 2/3/4/5 firmware flashing automation with make flash (no uSD).

Open cederom opened this issue 1 month ago • 5 comments

Is your feature request related to a problem? Please describe.

  • Right now we need to build NuttX, then mount uSD card, copy nuttx.bin and some other files to the uSD card, umount, and move card from the build host to the target board slot.
  • Testing requires manual interaction that blocks automated testing.

Describe the solution you'd like

  • It would be great to have make flash that would remotely flash and boot the NuttX on rPI 2/3/4/5 boards :-)
  • Because additional the USB-UART is required for now for nsh console maybe xmodem can be used to provide nuttx.bin over U-Boot?
  • I know @linguini1 works on the NuttX port to rPI 4B and I bought some 1/2/8GB RAM boards for testing. We can start with rPI 4B :-)

Describe alternatives you've considered

  • @lupyuen found SDWire interface [1] to emulate uSD card and enable testing automation. But this is dedicated hardware and for many boards comes quite expensive more expensive than the boards themselves :-P

[1] https://shop.3mdeb.com/product/sdwire/

Verification

  • [x] I have verified before submitting the report.

cederom avatar Nov 09 '25 21:11 cederom

I like this idea! It will probably be complicated to implement though since you'll always need to eject the uSD card and put it in the Pi (for now, unless of course you're using the sdwire). I would also think we want to be careful about automatically touching the SD card so we always know which one the user is planning to use with the Pi. And auto-formatting it may be a risky choice for the user for similar reasons.

I am pretty certain that you can also boot the Pi over a network connection. I believe QNX used U-Boot for this ability over Ethernet on the Pi4B, but I don't fully remember.

And there is also the ability to use a USB flash drive, I don't believe that requires extra support at all. If I remember correctly, the firmware will try to mount the SD card and if it can't, it will try to mount from USB next. I think there's also a config.txt option for making USB the default.

In any case, network booting is probably the most convenient alternative to the SD card and would work well for NXDART.

linguini1 avatar Nov 09 '25 22:11 linguini1

Very useful information on boot process and settings for various rPI models: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#boot-diagnostics The problem is different families support only some and/or different modes so this is not really coherent for all rPI.

Here is boot flow explained: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#eeprom-boot-flow

cederom avatar Nov 09 '25 22:11 cederom

For the rPI 4B I made it to boot Nuttx over usb :-)

In order to update rPI boot config [1]:

  • Boot the RPIOS [2] from uSD card.
  • Run sudo rpi-eeprom-config -e to open eeprom config editor.
  • Set BOOT_UART=1. This enables UART on GPIO 14 and 15 where for now nsh runs.
  • In BOOT_ORDER add 3 after f (i.e. BOOT_ORDER=0xf341). This value is the boot device code (see [1]) and the list read from right to left. f means boot to first boot device from the list (3 will prevent getting there). 3 enables RPIBOOT application [3] on the USBC port. 4 enables USB-MSD storage boot that is USB pendrive (we want that after SD). 1 enables SD card boot (we want that first). Default value was 0xf14.
  • You may want to set POWER_OFF_ON_HALT=1 too so rPI powers off on halt.
  • Run reboot to apply update (visible right after reboot).

After rPI boot config update:

  • UART pins 14 and 15 shows boot log but there is no boot shell (or I cannot trigger it maybe there is none).
  • USBC when attached to PC exposes ugen1.12: <Broadcom BCM2711 Boot> at usbus1 device that can be operated by rpiboot application [3] (build quickly and works on FreeBSD too).
  • Install rpi usbboot / rpiboot [3].
  • Go to nuttx build dir and build your nuttx.bin.
  • Create a rpi4b-nuttx directory and copy all files over there that would go to SD card.
  • You need to copy firmware/2711/bootcode4.bin from [3] to rpi4b-nuttx. This is the initial bootloader that will load the rest of the files over USB.
  • Run rpiboot -d rpi4b-nuttx that will transfer all files over USB and boot NuttX! The console is on pins 14 and 15 and there you should see the nsh> prompt :-) I had to do it two times and the lvgl demo does not run over HDMI so additional setup is required but we have proof that is it possible to flash NuttX to rPI with no SD involved :-)
  3.77 USB-OTG disconnect
 10.42 Read config.txt bytes       47 hnd 0x0
 10.27 HDMI1 edid block 0 offset 0
 10.27 00ffffffffffff001e6d0677a9840400
 10.27 091f0103803c2278ea3e31ae5047ac27
 10.28 0c50542108007140818081c0a9c0d1c0
 10.28 8100010101011a6800a0f0381f403020
 10.28 3a0058542100001a023a801871382d40
 10.29 582c450058542100001e000000fd0038
 10.29 3d1e871e000a202020202020000000fc
 10.29 004c472048445220344b0a2020200141
 10.31 HDMI1 edid block 1 offset 128
 10.31 02031b714490040301230907076d030c
 10.31 001000b83c200060010203023a801871
 10.32 382d40582c450058542100001e000000
 10.32 00000000000000000000000000000000
 10.32 00000000000000000000000000000000
 10.33 00000000000000000000000000000000
 10.33 00000000000000000000000000000000
 10.34 000000000000000000000000000000b5
 10.34 HDMI1: best-mode 1 (limit 1) 1280x720 60 Hz CEA modes 1a000100000000000000000000000000 extensions 1
 10.29 not found: pieeprom.sig -1
 10.42 Read pieeprom.upd failed
 10.97 not found: recover4.elf -1
 10.49 Read recover4.elf failed
 10.01 not found: recovery.elf -1
 10.50 Read recovery.elf failed
 10.21 Read start4.elf bytes  2299008 hnd 0x0
 10.91 Read fixup4.dat bytes     5496 hnd 0x0
 10.92 0x00d03115 0x00000000 0x00001fff
 10.95 MEM GPU: 76 ARM: 948 TOTAL: 1024
 10.95 Firmware: cd866525580337c0aee4b25880e1f5f9f674fb24 Aug 20 2025 17:02:31
 10.32 Starting start4.elf @ 0xfec00200 partition -1
 10.95 XHCI-STOP
 10.95 xHC0 ver: 256 HCS: 05000420 fc000031 00e70004 HCC: 002841eb
 10.96 USBSTS 18
 10.96 PCI0 reset
 11.01 +
- Ready to Boot Primary CPU
- Boot from EL2
- Boot from EL1
- Boot to C runtime for OS Initialize

NuttShell (NSH) NuttX-10.4.0
nsh> uname -a
NuttX 10.4.0 31b677cb78 Nov  9 2025 06:00:12 arm64 raspberrypi-4b
nsh> help
help usage:  help [-v] [<cmd>]

    .           cp          expr        mkdir       rmdir       umount
    [           cmp         false       mkrd        set         unset
    ?           dirname     fdinfo      mount       sleep       uptime
    alias       df          free        mv          source      usleep
    unalias     dmesg       help        pidof       test        watch
    basename    echo        hexdump     printf      time        xd
    break       env         kill        ps          true        wait
    cat         exec        pkill       pwd         truncate
    cd          exit        ls          rm          uname

Builtin Apps:
    fb          lvgldemo    nsh         ostest      sh
nsh> free
      total       used       free    maxused    maxfree  nused  nfree name
18446744073636958208      2204018446744073636936168      2271218446744073636936168     27      1 Umem
nsh> lvgldemo

NOTES:

  • IMPORTANT IF YOU EVER MESS UP BOOT ORDER OF YOUR RPI THEN PRESS SPACE SEVERAL TIMES RIGHT AFTER POWER ON DURING BOOT FROM THE USB KEYBOARD THEN BOOT SCREEN WILL SHOW UP AND YOU CAN BOOT FROM SD TO FIX STUFF :-)
  • BOOT_ORDER 5 enables BCM-USB-MSD that is boot from USBC. Is this a way to boot over USBC from pendrive skipping all rPI parts or some other protocol to use with bcm tools directly?
  • Do NOT put 3 or 5 at the end of BOOT_ORDER of the rPI wont boot from SD lol :D
  • On rPI 5 power button needs to be pressed before USBC is attached to enable RPIBOOT/USBBOOT.
  • nRPIBOOT may be used as boot select GPIO. This is different GPIO for different BCM chips (i.e. 20 or 40). rPI 4B does not have dedicated nRPIBOOT pin it can be configured by using one of the free GPIO (over dedicated tools or manual process) we do not seem to need that (yet?).
  • ./rpiboot -d mass-storage-gadget boots "Gadget Linux" on rPI over USB (just to make sure some sort of reference point works).
  • When rPI is connected to HDMI display (must be connected before power on to work) it displays boot menu when no usable boot device found. F1 shows boot options. SPACE changes boot mode. Holding SHIFT enables netboot. ESC goes back.
  • config.txt documentation: https://www.raspberrypi.com/documentation/computers/config_txt.html.

[1] https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#eeprom-boot-flow [2] https://www.raspberrypi.com/software/operating-systems/ [3] https://github.com/raspberrypi/usbboot

cederom avatar Nov 10 '25 00:11 cederom

A solution is using https://github.com/mvp/uhubctl to control a USB HUB and turn the power of each USB port individually, this way we can flash the new firmware and physically turn OFF and ON the board to restart it the proper way

In the uhubctl page there are a list of supported HUBs, I got a low cost (less than U$ 50) RSHTECH with 16 USB ports, it means a single HUB is able to control up to 16 boards

acassis avatar Nov 11 '25 14:11 acassis

Thanks @acassis yes I know uhubctl utility and ported it to FreeBSD https://github.com/mvp/uhubctl/issues/640 / https://github.com/freebsd/freebsd-ports/pull/456 but this issue is about firmware flashing not usb port control :-)

Simple PoC with rpiboot is already reported above your reply. It allows booting the rPI from imgage provided over USB with no SD card involved that enables automation :-)

cederom avatar Nov 12 '25 01:11 cederom