Git Product home page Git Product logo

usbboot's Introduction

USB Device Boot Code

This is the USB device boot code which supports the Raspberry Pi 1A, 3A+, Compute Module, Compute Module 3, 3+ 4S, and 4, Raspberry Pi Zero and Zero 2 W. N.B. In regards to this document CM4 and CM4S have identical software support.

The default behaviour when run with no arguments is to boot the Raspberry Pi with special firmware so that it emulates USB Mass Storage Device (MSD). The host OS will treat this as a normal USB mass storage device allowing the file system to be accessed. If the storage has not been formatted yet (default for Compute Module) then the Raspberry Pi Imager App can be used to install a new operating system.

Since RPIBOOT is a generic firmware loading interface, it is possible to load other versions of the firmware by passing the -d flag to specify the directory where the firmware should be loaded from. E.g. The firmware in the msd can be replaced with newer/older versions.

From Raspberry Pi5 onwards the MSD firmware has been replaced with a Linux initramfs providing a mass-storage-gadget.

For more information run rpiboot -h.

Building

Linux / Cygwin / WSL

Clone this repository on your Pi or other Linux machine. Make sure that the system date is set correctly, otherwise Git may produce an error.

  • This git repository uses symlinks. For Windows builds clone the repository under Cygwin.
  • Instead of duplicating the EEPROM binaries and tools the rpi-eeprom repository is included as a (git submodule)[https://git-scm.com/book/en/v2/Git-Tools-Submodules]
sudo apt install git libusb-1.0-0-dev pkg-config build-essential
git clone --recurse-submodules --shallow-submodules --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
make
sudo ./rpiboot

sudo isn't required if you have write permissions for the /dev/bus/usb device.

macOS

From a macOS machine, you can also run usbboot, just follow the same steps:

  1. Clone the usbboot repository
  2. Install libusb (brew install libusb)
  3. Install pkg-config (brew install pkg-config)
  4. (Optional) Export the PKG_CONFIG_PATH so that it includes the directory enclosing libusb-1.0.pc
  5. Build using make
  6. Run the binary
git clone --recurse-submodules --shallow-submodules --depth=1 https://github.com/raspberrypi/usbboot
cd usbboot
brew install libusb
brew install pkg-config
make
sudo ./rpiboot

If the build is unable to find the header file libusb.h then most likely the PKG_CONFIG_PATH is not set properly. This should be set via export PKG_CONFIG_PATH="$(brew --prefix libusb)/lib/pkgconfig".

If the build fails on an ARM-based Mac with a linker error such as ld: warning: ignoring file /usr/local/Cellar/libusb/1.0.26/lib/libusb-1.0.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64 then you may need to build and install libusb-1.0 yourself:

wget https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26.tar.bz2
tar -xf libusb-1.0.26.tar.bz2
cd libusb-1.0.26
./configure
make
make check
sudo make INSTALL_PREFIX=/usr/local install

Running make again should now succeed.

Updating the rpi-eeprom submodule

After updating the usbboot repo (git pull --rebase origin master) update the submodules by running

git submodule update --init

Running

Compute Module 3

Fit the EMMC-DISABLE jumper on the Compute Module IO board before powering on the board or connecting the USB cable.

Compute Module 4

On Compute Module 4 EMMC-DISABLE / nRPIBOOT (GPIO 40) must be fitted to switch the ROM to usbboot mode. Otherwise, the SPI EEPROM bootloader image will be loaded instead.

Raspberry Pi 5

  • Disconnect the USB-C cable. Power must be removed rather than just running "sudo shutdown now"
  • Hold the power button down
  • Connect the USB-C cable (from the RPIBOOT host to the Pi 5)

Compute Module 4 Extensions

In addition to the MSD functionality, there are a number of other utilities that can be loaded via RPIBOOT on Compute Module 4.

Directory Description
recovery Updates the bootloader EEPROM on a Compute Module 4
recovery5 Updates the bootloader EEPROM on a Raspberry Pi 5
rpi-imager-embedded Runs the embedded version of Raspberry Pi Imager on the target device
mass-storage-gadget 32-bit mass storage gadget for BCM2711
mass-storage-gadget64 Mass storage gadget with 64-bit Kernel for BCM2711 and BCM2712
secure-boot-recovery Pi4 secure-boot bootloader flash and OTP provisioning
secure-boot-recovery5 Pi5 secure-boot bootloader flash and OTP provisioning
secure-boot-example Simple Linux initrd with a UART console.

Booting Linux

The RPIBOOT protocol provides a virtual file system to the Raspberry Pi bootloader and GPU firmware. It's therefore possible to boot Linux. To do this, you will need to copy all of the files from a Raspberry Pi boot partition plus create your own initramfs. On Raspberry Pi 4 / CM4 the recommended approach is to use a boot.img which is a FAT disk image containing the minimal set of files required from the boot partition.

Troubleshooting

This section describes how to diagnose common rpiboot failures for Compute Modules. Whilst rpiboot is tested on every Compute Module during manufacture the system relies on multiple hardware and software elements. The aim of this guide is to make it easier to identify which component is failing.

Product Information Portal

The Product Information Portal contains the official documentation for hardware revision changes for Raspberry Pi computers. Please check this first to check that the software is up to date.

Hardware

  • Inspect the Compute Module pins and connector for signs of damage and verify that the socket is free from debris.
  • Check that the Compute Module is fully inserted.
  • Check that nRPIBOOT / EMMC disable is pulled low BEFORE powering on the device.
    • On BCM2711, if the USB cable is disconected and the nRPIBOOT jumper is fitted then the green LED should be OFF. If the LED is on then the ROM is detecting that the GPIO for nRPIBOOT is high.
  • Remove any hubs between the Compute Module and the host.
  • Disconnect all other peripherals from the IO board.
  • Verify that the red power LED switches on when the IO board is powered.
  • Use another computer to verify that the USB cable for rpiboot can reliably transfer data. For example, connect it to a Raspberry Pi keyboard with other devices connected to the keyboard USB hub.

Hardware - CM4

  • The CM4 EEPROM supports MMC, USB-MSD, USB 2.0, Network and NVMe boot by default. Try booting to Linux from an alternate boot mode (e.g. network) to verify the nRPIBOOT GPIO can be pulled low and that the USB 2.0 interface is working.
  • If rpiboot is running but the mass storage device does not appear then try running the rpiboot -d mass-storage-gadget because this uses Linux instead of a custom VPU firmware to implement the mass-storage gadget. This also provides a login console on UART and HDMI.

Hardware - Raspberry Pi 5

  • Press, and hold the power button before supplying power to the device.
  • Release the power button immediately after supplying power to the device.
  • Remove any non-essential USB peripherals or HATs.
  • Use a USB-3 port capable of supplying at least 900mA and use a high quality USB-C cable OR supply additional power via the 40-pin header.

Software

The recommended host setup is Raspberry Pi with Raspberry Pi OS. Alternatively, most Linux X86 builds are also suitable. Windows adds some extra complexity for the USB drivers so we recommend debugging on Linux first.

  • Update to the latest software release using apt update rpiboot or download and rebuild this repository from Github.
  • Run rpiboot -v | tee log to capture verbose log output. N.B. This can be very verbose on some systems.

Boot flow

The rpiboot system runs in multiple stages. The ROM, bootcode.bin, the VPU firmware (start.elf) and for the mass-storage-gadget or rpi-imager a Linux initramfs. Each stage disconnects the USB device and presents a different USB descriptor. Each stage will appears as a new USB device connect in the dmesg log.

See also: Raspberry Pi4 Boot Flow

bootcode.bin

Be careful not to overwrite bootcode.bin or bootcode4.bin with the executable from a different subdirectory. The rpiboot process simply looks for a file called bootcode.bin (or bootcode4.bin on BCM2711). However, the file in recovery/secure-boot-recovery directories is actually the recovery.bin EEPROM flashing tool.

Diagnostics

  • Monitor the Linux dmesg output and verify that a BCM boot device is detected immediately after powering on the device. If not, please check the hardware section.
  • Check the green activity LED. On Compute Module 4 this is activated by the software bootloader and should remain on. If not, then it's likely that the initial USB transfer to the ROM failed.
  • On Compute Module 4 connect a HDMI monitor for additional debug output. Flashing the EEPROM using recovery.bin will show a green screen and the mass-storage-gadget enables a console on the HDMI display.
  • If rpiboot starts to download bootcode4.bin but the transfer fails then can indicate a cable issue OR a corrupted file. Check the hash of bootcode.bin file against this repository and check dmesg for USB error.
  • If bootcode.bin or the start.elf detects an error then error-code will be indicated by flashing the green activity LED.
  • Add uart_2ndstage=1 to the config.txt file in msd/ or recovery/ directories to enable UART debug output.

Secure Boot

Secure Boot requires a recent bootloader stable image e.g. the version in this repository.

Tutorial

Creating a secure boot system from scratch can be quite complex. The secure boot tutorial uses a minimal example OS image to demonstrate how the Raspberry Pi-specific aspects of secure boot work.

Additional documentation

Host Setup

Secure boot require a 2048 bit RSA asymmetric keypair and the Python pycrytodome module to sign the bootloader EEPROM config and boot image.

Install Python Crypto Support (the pycryptodomex module)

sudo apt install python3-pycryptodome

Create an RSA key-pair using OpenSSL. Must be 2048 bits

cd $HOME
openssl genrsa 2048 > private.pem

Secure Boot - configuration

Secure Boot - image creation

Secure Boot requires self-contained ramdisk (boot.img) FAT image to be created containing the GPU firmware, kernel and any other dependencies that would normally be loaded from the boot partition.

This plus a signature file (boot.sig) must be placed in the boot partition of the Raspberry Pi or network download location.

The boot.img file should contain:-

  • The kernel
  • Device tree overlays
  • GPU firmware (start.elf and fixup.dat)
  • Linux initramfs containing the application OR scripts to mount/create an encrypted file-system.

Disk encryption

Secure-boot is responsible for loading the Kernel + initramfs and loads all of the data from a single boot.img file stored on an unencrypted FAT/EFI partition.

There is no support in the ROM or firmware for full-disk encryption.

If a custom OS image needs to use an encrypted file-system then this would normally be implemented via scripts within the initramfs.

Raspberry Pi computers do not have a secure enclave, however, it's possible to store a 256 bit device specific private key in OTP. The key is accessible to any process with access to /dev/vcio (vcmailbox), therefore, the secure-boot OS must ensure that access to this interface is restricted.

It is not possible to prevent code running in ARM supervisor mode (e.g. kernel code) from accessing OTP hardware directly

See also:-

The secure boot tutorial contains a boot.img that supports cryptsetup and a simple example.

Building boot.img using buildroot

The secure-boot-example directory contains a simple boot.img example with working HDMI, network, UART console and common tools in an initramfs.

This was generated from the raspberrypi-signed-boot buildroot config. Whilst not a generic fully featured configuration it should be relatively straightforward to cherry-pick the raspberrypi-secure-boot package and helper scripts into other buildroot configurations.

Minimum firmware version

The firmware must be new enough to support secure boot. The latest firmware APT package supports secure boot. To download the firmware files directly.

git clone --depth 1 --branch stable https://github.com/raspberrypi/firmware

To check the version information within a start4.elf firmware file run

strings start4.elf | grep VC_BUILD_

Verifying the contents of a boot.img file

To verify that the boot image has been created correctly use losetup to mount the .img file.

sudo su
mkdir -p boot-mount
LOOP=$(losetup -f)
losetup -f boot.img
mount ${LOOP} boot-mount/

 echo boot.img contains
find boot-mount/

umount boot-mount
losetup -d ${LOOP}
rmdir boot-mount

Signing the boot image

For secure-boot, rpi-eeprom-digest extends the current .sig format of sha256 + timestamp to include an hex format RSA bit PKCS#1 v1.5 signature. The key length must be 2048 bits.

../tools/rpi-eeprom-digest -i boot.img -o boot.sig -k "${KEY_FILE}"

To verify the signature of an existing image set the PUBLIC_KEY_FILE environment variable to the path of the public key file in PEM format.

../tools/rpi-eeprom-digest -i boot.img -k "${PUBLIC_KEY_FILE}" -v boot.sig

Hardware security modules

rpi-eeprom-digest is a shell script that wraps a call to openssl dgst -sign. If the private key is stored within a hardware security module instead of a .PEM file the openssl command will need to be replaced with the appropriate call to the HSM.

rpi-eeprom-digest called by update-pieeprom.sh to sign the EEPROM config file.

The RSA public key must be stored within the EEPROM so that it can be used by the bootloader. By default, the RSA public key is automatically extracted from the private key PEM file. Alternatively, the public key may be specified separately via the -p argument to update-pieeprom.sh and rpi-eeprom-config.

To extract the public key in PEM format from a private key PEM file, run:

openssl rsa -in private.pem -pubout -out public.pem

Copy the secure boot image to the boot partition on the Raspberry Pi.

Copy boot.img and boot.sig to the boot filesystem. Secure boot images can be loaded from any of the normal boot modes (e.g. SD, USB, Network).

usbboot's People

Contributors

axelsimon avatar burtyb avatar connorfuhrman avatar dcousens avatar diegoherranz avatar dodain avatar dp111 avatar ghollingworth avatar katiefaith avatar maxnet avatar mennovf avatar miks avatar mozzbozz avatar mrpollo avatar nils-werner avatar pastudan avatar pelwell avatar peterharperuk avatar pls-no-hack avatar ptesarik avatar raymo111 avatar swarren avatar tdewey-rpi avatar timg236 avatar tmcolby avatar trejan avatar tvoverbeek avatar woju avatar xecdesign avatar yagop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usbboot's Issues

Overlay Subdirectory.

I am seeing a control transfer failure when trying to send an overlay:

$ sudo ./rpiboot -l -d ./boot/
Waiting for BCM2835/6/7
Sending bootcode.usb
Failed : 0x0Waiting for BCM2835/6/7
Second stage boot server
File read: config.txt
File read: start.elf
Waiting for BCM2835/6/7
Second stage boot server
File read: config.txt
File read: config.txt
File read: cmdline.txt
File read: kernel.img
File read: bcm2708-rpi-b-plus.dtb
File read: config.txt
File read: overlays/dwc2.dtbo
Failed control transfer

Looking at the log it seems to be sending config.txt every time that start.elf wants to read it. That makes sense to me, but perhaps the firmware could cache that file.

[Make] Libusb error

Hello,

Can't make because of libusb :

pierrearnoud@macbook-pro-de-pierre usbboot % make
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0
main.c:1:10: fatal error: 'libusb-1.0/libusb.h' file not found
#include <libusb-1.0/libusb.h>
         ^~~~~~~~~~~~~~~~~~~~~
1 error generated.

I have libusb insatlled

pierrearnoud@macbook-pro-de-pierre usbboot % brew info libusb
libusb: stable 1.0.24 (bottled), HEAD
Library for USB device access
https://libusb.info/
/opt/homebrew/Cellar/libusb/1.0.24 (22 files, 560.5KB) *
  Poured from bottle on 2021-05-30 at 18:06:35
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libusb.rb
License: LGPL-2.1-or-later
==> Options
--HEAD
	Install HEAD version
==> Analytics
install: 64,482 (30 days), 211,215 (90 days), 813,259 (365 days)
install-on-request: 6,988 (30 days), 19,139 (90 days), 77,925 (365 days)
build-error: 0 (30 days)

I'm working on MacBook Pro :
image

VisualStudio Code Error in Code

Hello,

I would like to Build (compile) the Programm but I get an error.

image

The Error Message says "The Identifier in ""msd_start_elf"" is not defined."
the same Error with msd_bootcode_bin, msd_bootcode_bin_len and msd_start_elf_len. Can maybe someone help me ?

Greetings Lukas

Selecting USB port message loop

When I use the option to look for CMs attached to USB port, the Rpiboot continues to output "Loading embedded: bootcode.bin".
I am currently using a raspberry pi 4 B to boot a CM3+ with CMIO.

Is there any way to not get these infinite messages and just like the usual blank waiting?

RpiBootStuck

rpiboot doesn't put pi in USB MSD mode

I have a pi that isn't put into USB MSD mode by rpiboot. It appears to run successfully, but afterwards no new block devices are present (in fact the pi doesn't show up in lsusb). git bisect shows this being introduced in commit ec9155c ie. with a build from before that commit it works.

This is the output of an rpiboot run which fails:

$ sudo ./rpiboot  -v
Waiting for BCM2835/6/7
Found device 1 idVendor=0x03f0 idProduct=0x154a
Found device 2 idVendor=0x04b3 idProduct=0x3025
Found device 3 idVendor=0x8087 idProduct=0x0024
Found device 4 idVendor=0x1d6b idProduct=0x0002
Found device 5 idVendor=0x1d6b idProduct=0x0003
Found device 6 idVendor=0x1d6b idProduct=0x0002
Found device 7 idVendor=0x8087 idProduct=0x0024
Found device 8 idVendor=0x1d6b idProduct=0x0002
... etc ...
Found device 1 idVendor=0x03f0 idProduct=0x154a
Found device 2 idVendor=0x04b3 idProduct=0x3025
Found device 3 idVendor=0x8087 idProduct=0x0024
Found device 4 idVendor=0x1d6b idProduct=0x0002
Found device 5 idVendor=0x1d6b idProduct=0x0003
Found device 6 idVendor=0x1d6b idProduct=0x0002
Found device 7 idVendor=0x8087 idProduct=0x0024
Found device 8 idVendor=0x1d6b idProduct=0x0002
libusb: error [udev_hotplug_event] ignoring udev action bind
Found device 1 idVendor=0x0a5c idProduct=0x2764
Device located successfully
Initialised device correctly
Found serial number 0
Sending bootcode.bin
libusb_bulk_transfer returned 0
Writing 50408 bytes
libusb_bulk_transfer returned 0
Successful read 4 bytes 
Waiting for BCM2835/6/7
Found device 1 idVendor=0x03f0 idProduct=0x154a
Found device 2 idVendor=0x04b3 idProduct=0x3025
Found device 3 idVendor=0x8087 idProduct=0x0024
Found device 4 idVendor=0x1d6b idProduct=0x0002
Found device 5 idVendor=0x1d6b idProduct=0x0003
Found device 6 idVendor=0x1d6b idProduct=0x0002
Found device 7 idVendor=0x8087 idProduct=0x0024
Found device 8 idVendor=0x1d6b idProduct=0x0002
libusb: error [udev_hotplug_event] ignoring udev action bind
Found device 1 idVendor=0x0a5c idProduct=0x2764
Device located successfully
Initialised device correctly
Found serial number 1
Second stage boot server
Received message GetFileSize: autoboot.txt
Cannot open file autoboot.txt
Received message GetFileSize: config.txt
Cannot open file config.txt
Received message GetFileSize: recovery.elf
Cannot open file recovery.elf
Received message GetFileSize: start.elf
File size = 433448 bytes
Received message ReadFile: start.elf
File read: start.elf
libusb_bulk_transfer returned 0
Received message GetFileSize: fixup.dat
Cannot open file fixup.dat
^C

And this is what dmesg has to say:

[  352.568470] usb 1-1.4: new high-speed USB device number 4 using ehci-pci
[  352.676870] usb 1-1.4: config index 0 descriptor too short (expected 55, got 32)
[  352.677244] usb 1-1.4: New USB device found, idVendor=0a5c, idProduct=2764
[  352.677249] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[  352.677252] usb 1-1.4: Product: BCM2710 Boot
[  352.677255] usb 1-1.4: Manufacturer: Broadcom
[  354.473346] usb 1-1.4: USB disconnect, device number 4
[  354.696477] usb 1-1.4: new high-speed USB device number 5 using ehci-pci
[  355.320478] usb 1-1.4: device descriptor read/64, error -71
[  355.537328] usb 1-1.4: New USB device found, idVendor=0a5c, idProduct=2764
[  355.537334] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=1
[  355.537337] usb 1-1.4: Product: BCM2710 Boot
[  355.537340] usb 1-1.4: Manufacturer: Broadcom
[  355.537343] usb 1-1.4: SerialNumber: Broadcom
[  356.265248] usb 1-1.4: USB disconnect, device number 5

I can use the old version for now. I'm happy to help out testing any changes that affect this.

Unable to usb boot raspberry pi zero v1.3

I got an error when I try to boot a pi zero from usb.
I am following this tutorial:
https://dev.webonomic.nl/how-to-run-or-boot-raspbian-on-a-raspberry-pi-zero-without-an-sd-card/comment-page-1

Since I do not understand what it is happening, I don’t know which information you need to understand the issue.

I start usbboot, then I plug the pi zero. All following logs are printed, then nothing happens anymore.
Execution trace

$  sudo ./rpiboot -v -d boot/
Boot directory 'boot/'
Loading: boot//bootcode.bin
Waiting for BCM2835/6/7/2711...
Loading: boot//bootcode.bin
Device located successfully
libusb: error [udev_hotplug_event] ignoring udev action bind
Initialised device correctly
Found serial number 0
Sending bootcode.bin
libusb_bulk_transfer sent 24 bytes; returned 0
Writing 52480 bytes
libusb_bulk_transfer sent 52480 bytes; returned 0
Successful read 4 bytes
Waiting for BCM2835/6/7/2711...
^C

In the same time, dmesg logged :

[ 2103.768199] usb 1-2: new full-speed USB device number 18 using xhci_hcd
[ 2103.909147] usb 1-2: New USB device found, idVendor=0a5c, idProduct=2763, bcdDevice= 0.00
[ 2103.909153] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2103.909155] usb 1-2: Product: BCM2708 Boot
[ 2103.909158] usb 1-2: Manufacturer: Broadcom
[ 2106.556630] usb 1-2: USB disconnect, device number 18

I thought it was a lack of power in the pi, so I plugged it simultaneously to the computer and to a power supply. The result was the same.

I tried with two raspberry pi zero V1.3 and two different usb wire with no changes.

I did those tests from two computers with same results:

manjaro 20.20
linux 5.8.18-1-MANJARO
linuxmint 4
LMDE 4
linux 4.19.0-12-amd64

I connected a monitor to the pi, it got no signal, so no boot seems to happend.
The "act" led is not blinking.

I made sure OTP usb boot bit was set adding program_usb_boot_mode=1 to /boot/config.txt in a raspbian. Then I booted the pi from that SD card.

Is this issue related to udev ?
Is it related to my raspbian image or to the initrd I generated ?

Stuck waiting for BCM2837 on Mac

Environment:
MacOS High Sierra (10.13.3)
libusb stable 1.0.22 (installed via homebrew)
CM3 with CM3IO board (USB Slave Boot Enable is EN).

make succeeds, but displays deprecation warnings:

$ make
cc -Wall -Wextra -g -o bin2c bin2c.c
./bin2c msd/bootcode.bin msd/bootcode.h
./bin2c msd/start.elf msd/start.h
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0
main.c:394:16: warning: comparison of array 'pathname' not equal to a null pointer is always true [-Wtautological-pointer-compare]
                if(overlay&&(pathname != NULL))
                             ^~~~~~~~    ~~~~
main.c:601:2: warning: 'libusb_set_debug' is deprecated [-Wdeprecated-declarations]
        libusb_set_debug(ctx, verbose ? LIBUSB_LOG_LEVEL_WARNING : 0);
        ^
/usr/local/include/libusb-1.0/libusb.h:1299:1: note: 'libusb_set_debug' has been explicitly marked deprecated here
LIBUSB_DEPRECATED_FOR(libusb_set_option)
^
/usr/local/include/libusb-1.0/libusb.h:89:49: note: expanded from macro 'LIBUSB_DEPRECATED_FOR'
#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated))
                                                ^
2 warnings generated.

Running sudo ./rpiboot appears to run as expected, but the pi is never detected - I see "Waiting for BCM2835/6/7" forever.

There doesn't appear to be anything in the syslog to show the pi appearing as a USB device.

License

It would be good to add an explicit license for this code.

main.c:620:2: warning: 'libusb_set_debug' is deprecated

Running this with the latest version of libusb on my Mac, I got the following warning (no error, through) when running make:

$ make          
cc -Wall -Wextra -g -o bin2c bin2c.c
./bin2c msd/bootcode.bin msd/bootcode.h
./bin2c msd/start.elf msd/start.h
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0
main.c:620:2: warning: 'libusb_set_debug' is deprecated [-Wdeprecated-declarations]
        libusb_set_debug(ctx, verbose ? LIBUSB_LOG_LEVEL_WARNING : 0);
        ^
/usr/local/include/libusb-1.0/libusb.h:1324:1: note: 'libusb_set_debug' has been explicitly marked deprecated here
LIBUSB_DEPRECATED_FOR(libusb_set_option)
^
/usr/local/include/libusb-1.0/libusb.h:89:49: note: expanded from macro 'LIBUSB_DEPRECATED_FOR'
#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated))
                                                ^
1 warning generated.

Version Number

After struggling to boot and mount my CM3+ on my Ubuntu system, I tried on booting it on my Windows system. Windows worked, Ubuntu did not.. Looking at the help section I realized I was using an old version of rpiboot on my Ubuntu system.. Might be worth having version number of the software displayed in the help section and also the first line you see when you try to boot a CM module.

the new msd/start4.elf performance seems slower then expected

Describe the bug
the new msd/start4.elf performance seems slower then expected

To Reproduce

# boot msd/start4.elf on a rpi4b
[root@amd-nixos:~]# time dd if=/dev/sdf of=/dev/null bs=4096
1940480+0 records in
1940480+0 records out
7948206080 bytes (7.9 GB, 7.4 GiB) copied, 718.837 s, 11.1 MB/s

real    11m58.853s

Expected behaviour
the exact same uSD card, now in a laptop with a built-in mmc reader

[root@system76:~]# time dd if=/dev/mmcblk0 bs=4096 of=/dev/null
1940480+0 records in
1940480+0 records out
7948206080 bytes (7.9 GB, 7.4 GiB) copied, 185.129 s, 42.9 MB/s

real    3m5.138s

Bootloader version and configuration

[clever@amd-nixos:usbboot]$ git rev-parse HEAD
ff86c6dedebdc34382406915c44ef7933b20a177

SD card boot (please complete the following information):

[root@system76:/sys/class/block/mmcblk0/device]# cat cid
035344534c30384780956a0dae00fb01

[root@system76:/sys/class/block/mmcblk0/device]# cat csd
400e00325b5900003b377f800a404001

[root@system76:/sys/class/block/mmcblk0/device]# cat manfid
0x000003

[root@system76:/sys/class/block/mmcblk0/device]# cat name
SL08G

[root@system76:/sys/class/block/mmcblk0/device]# cat serial
0x956a0dae

a relatively recent 8gig samsung uSD card

Additional context
and one minor nit-pick:
Bus 006 Device 087: ID 0a5c:0001 Broadcom Corp. Compute Module
the msd/start4.elf always claims to be a compute module, even if booting on an rpi4b

Duplicate Readmes

It's a bit confusing, with this repo having both a README.md and Readme.md. Github seems to default to displaying README.md, whereas all the useful info is in Readme.md.
It would be nice if these two files could be merged into one.

Raspberry Pi USB boot Setup fail on Win7 system

I'm run the rpiboot_setup.exe on win7 with CM4/IO board.
The setup was completed successfully.
But I find there has below information:
...
Installing BCM2710 driver...
Execute:"..."
Driver install returned -9
Installing BCM2711 driver...
Execute:"..."
Driver install returned -9
...
And I found that in Computer Device manager,
There has BCM2711 boost and shows the device are not installed.(Code28)

Support arbitrarily sized initrd

My initrd is 28MB and I get a message "Failed to write complete file to USB device". Smaller initrds transfer okay. (But doesn't boot due to #13.)

The 28MB initrd works fine from SD card or using netboot, so I don't see why it should not work with usbboot.

Possible to bootload custom kernels on CM3+ to avoid MSD for imaging eMMC?

I've read about the Pi boot process as it relates to SD cards as well as usbboot. I'd like to use usbboot to bring up a minimal system in a ramdisk so that I can access eMMC myself and implement the disk loader using a method other than MSD. Maybe someone already did this, if so please point to an example.

I'm trying to create a simpler process for imaging the CM3+ that doesn't involve disks showing up on a user's PC. I'd like to expand the usbboot process so that bootloading and imaging the eMMC could be done through the same mechanism.

A few questions:

  • Is it possible to use a different start.elf to bootload a Linux kernel using a ramdisk to get a minimal system started via usbboot? If so is there a list of other versions somewhere? I know this file is proprietary but I have found no docs explaining it.
  • Once a minimal Linux system is running is it possible to use the USB device port from Linux to present as a different kind of USB device? Like a USB serial port or just a raw endpoint that can be used via libusb on the host side?
  • Once this is up and running would it be possible to toggle some I/Os to enable to eMMC and read/write it from the booted kernel?

Thanks!

Newest commits do not work on Debian Jessie

As we pulled and make'd the latest commits yesterday on out up-to-date Debian Jessie PC, suddenly CM3-Modules couldn't be mounted anymore. After upgrading to Debian Stretch, everything worked fine again.

sudo ./rpiboot tried to send the bootcode three times and failed in an error at third time (smth. like "Answer was too short") after about a minute. Unfortunately we didn't save the output before upgrading to Stretch.

Last working commit on Debian Jessie (Apr 5, 2018):
c3ee230

First commit where error occurs (Apr 12, 2018)
1bb4c2d

If it is still interesting to support Debian Jessie, it should be easily reproducable on a machine with Debian Jessie and current updates.

Compilation errors in fmemopen.c

Getting when building rpiusbboot-git on an x86_64 archlinux in a clean, latest archlinux chroot.

In file included from main.c:13:
fmemopen.c: In function ‘seekfn’:
fmemopen.c:62:18: error: invalid operands to binary >= (have ‘fpos_t’ {aka ‘struct _G_fpos_t’} and ‘int’)
   62 |       if (offset >= 0) {
      |                  ^~
fmemopen.c:63:9: error: aggregate value used where an integer was expected
   63 |         pos = (size_t)offset;
      |         ^~~
fmemopen.c:70:18: error: invalid operands to binary >= (have ‘fpos_t’ {aka ‘struct _G_fpos_t’} and ‘int’)
   70 |       if (offset >= 0 || (size_t)(-offset) <= mem->pos) {
      |                  ^~
fmemopen.c:70:35: error: wrong type argument to unary minus
   70 |       if (offset >= 0 || (size_t)(-offset) <= mem->pos) {
      |                                   ^
fmemopen.c:71:9: error: aggregate value used where an integer was expected
   71 |         pos = mem->pos + (size_t)offset;
      |         ^~~
fmemopen.c:77:5: error: aggregate value used where an integer was expected
   77 |     case SEEK_END: pos = mem->size + (size_t)offset; break;
      |     ^~~~
fmemopen.c:78:21: error: incompatible types when returning type ‘int’ but ‘fpos_t’ {aka ‘struct _G_fpos_t’} was expected
   78 |     default: return -1;
      |                     ^
fmemopen.c:82:12: error: incompatible types when returning type ‘int’ but ‘fpos_t’ {aka ‘struct _G_fpos_t’} was expected
   82 |     return -1;
      |            ^
fmemopen.c:86:3: error: conversion to non-scalar type requested
   86 |   return (fpos_t)pos;
      |   ^~~~~~

Full log:

:: Synchronizing package databases...
 core is up to date
 extra is up to date
 community is up to date
:: Starting full system upgrade...
 there is nothing to do
==> Building in chroot for [extra] (x86_64)...
==> Synchronizing chroot copy [/var/lib/archbuild/extra-x86_64/root] -> [calil]...done
==> Making package: rpiusbboot-git r73.45c7237-1 (Wed Feb  5 01:07:21 2020)
==> Retrieving sources...
  -> Updating usbboot git repo...
Fetching origin
==> Validating source files with md5sums...
    usbboot ... Skipped
==> Making package: rpiusbboot-git r73.45c7237-1 (Wed 05 Feb 2020 01:07:30 AM CST)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Installing missing dependencies...
resolving dependencies...
looking for conflicting packages...

Packages (4) perl-error-0.17029-1  perl-mailtools-2.21-2  perl-timedate-2.31-1
             git-2.25.0-1

Total Installed Size:  37.65 MiB

:: Proceed with installation? [Y/n] 
checking keyring...
checking package integrity...
loading package files...
checking for file conflicts...
:: Processing package changes...
installing perl-error...
installing perl-timedate...
installing perl-mailtools...
installing git...
Optional dependencies for git
    tk: gitk and git gui
    perl-libwww: git svn
    perl-term-readkey: git svn and interactive.singlekey setting
    perl-mime-tools: git send-email
    perl-net-smtp-ssl: git send-email TLS support
    perl-authen-sasl: git send-email TLS support
    perl-mediawiki-api: git mediawiki support
    perl-datetime-format-iso8601: git mediawiki support
    perl-lwp-protocol-https: git mediawiki https support
    perl-cgi: gitweb (web interface) support
    python: git svn & git p4
    subversion: git svn
    org.freedesktop.secrets: keyring credential helper
    libsecret: libsecret credential helper [installed]
:: Running post-transaction hooks...
(1/4) Creating system user accounts...
Creating group git with gid 977.
Creating user git (git daemon user) with uid 977 and gid 977.
(2/4) Reloading system manager configuration...
  Skipped: Current root is not booted.
(3/4) Arming ConditionNeedsUpdate...
(4/4) Warn about old perl modules
==> Retrieving sources...
==> WARNING: Skipping all source file integrity checks.
==> Extracting sources...
  -> Creating working copy of usbboot git repo...
Cloning into 'usbboot'...
done.
==> Starting pkgver()...
==> Starting build()...
cc -Wall -Wextra -g -o bin2c bin2c.c
./bin2c msd/bootcode.bin msd/bootcode.h
./bin2c msd/start.elf msd/start.h
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0
In file included from main.c:13:
fmemopen.c: In function ‘seekfn’:
fmemopen.c:62:18: error: invalid operands to binary >= (have ‘fpos_t’ {aka ‘struct _G_fpos_t’} and ‘int’)
   62 |       if (offset >= 0) {
      |                  ^~
fmemopen.c:63:9: error: aggregate value used where an integer was expected
   63 |         pos = (size_t)offset;
      |         ^~~
fmemopen.c:70:18: error: invalid operands to binary >= (have ‘fpos_t’ {aka ‘struct _G_fpos_t’} and ‘int’)
   70 |       if (offset >= 0 || (size_t)(-offset) <= mem->pos) {
      |                  ^~
fmemopen.c:70:35: error: wrong type argument to unary minus
   70 |       if (offset >= 0 || (size_t)(-offset) <= mem->pos) {
      |                                   ^
fmemopen.c:71:9: error: aggregate value used where an integer was expected
   71 |         pos = mem->pos + (size_t)offset;
      |         ^~~
fmemopen.c:77:5: error: aggregate value used where an integer was expected
   77 |     case SEEK_END: pos = mem->size + (size_t)offset; break;
      |     ^~~~
fmemopen.c:78:21: error: incompatible types when returning type ‘int’ but ‘fpos_t’ {aka ‘struct _G_fpos_t’} was expected
   78 |     default: return -1;
      |                     ^
fmemopen.c:82:12: error: incompatible types when returning type ‘int’ but ‘fpos_t’ {aka ‘struct _G_fpos_t’} was expected
   82 |     return -1;
      |            ^
fmemopen.c:86:3: error: conversion to non-scalar type requested
   86 |   return (fpos_t)pos;
      |   ^~~~~~
fmemopen.c: In function ‘fmemopen’:
fmemopen.c:95: warning: ignoring #pragma unused  [-Wunknown-pragmas]
   95 |   #pragma unused(mode)
      | 
fmemopen.c:106:10: warning: implicit declaration of function ‘funopen’; did you mean ‘fdopen’? [-Wimplicit-function-declaration]
  106 |   return funopen(mem, readfn, writefn, seekfn, closefn);
      |          ^~~~~~~
      |          fdopen
fmemopen.c:106:10: warning: returning ‘int’ from a function with return type ‘FILE *’ {aka ‘struct _IO_FILE *’} makes pointer from integer without a cast [-Wint-conversion]
  106 |   return funopen(mem, readfn, writefn, seekfn, closefn);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fmemopen.c:94:52: warning: unused parameter ‘mode’ [-Wunused-parameter]
   94 | FILE *fmemopen(void *buf, size_t size, const char *mode) {
      |                                        ~~~~~~~~~~~~^~~~
main.c: In function ‘main’:
main.c:620:2: warning: ‘libusb_set_debug’ is deprecated: Use libusb_set_option instead [-Wdeprecated-declarations]
  620 |  libusb_set_debug(ctx, verbose ? LIBUSB_LOG_LEVEL_WARNING : 0);
      |  ^~~~~~~~~~~~~~~~
In file included from main.c:1:
/usr/include/libusb-1.0/libusb.h:1325:18: note: declared here
 1325 | void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, int level);
      |                  ^~~~~~~~~~~~~~~~
In file included from main.c:13:
fmemopen.c: In function ‘seekfn’:
fmemopen.c:87:1: warning: control reaches end of non-void function [-Wreturn-type]
   87 | }
      | ^
make: *** [Makefile:2: rpiboot] Error 1
==> ERROR: A failure occurred in build().
    Aborting...

Create a tag or release?

Hi there,

I'm a Alpine Linux packager, I'd like to package usbboot into our repositories but our policy is usually to stick to a specific version rather than fixing an arbitrary git commit.

Since the activity is pretty low as the software is quite stable enough, is there any chance that you create at least a tag so that we can stick to it?

requiring sudo is just plain wrong

A program that at runtime checks if it's running as root, rather than checking for the actual permissions that it requires. I don't think I've seen such bad practise any time before, to be honest.

I don't really see why the program would require to run as root. Root privileges are way too powerful. All that's needed appears to be access to some USB devices. So the proper solution is to ship udev rules for those vid/pid combinations, rather than forcing people to run code with way too high privileges.

Stuck in loop - Failed control transfer (-7,24)

Hello,

I'm trying to flash the CM4 on the official IO board.

The jumper has been set to 'Fit jumper to disable eMMC Boot' and I am using the latest usbboot.

If i try to run sudo ./rpiboot it gets stuck in this loop:

Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Failed control transfer (-7,24)
Failed to write correct length, returned -7
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Failed control transfer (-7,24)
Failed to write correct length, returned -7
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Failed control transfer (-7,24)
Failed to write correct length, returned -7

This issue is probably related to #82.

Output of sudo ./rpiboot -vv

Waiting for BCM2835/6/7/2711...
Found device 1 idVendor=0x1d6b idProduct=0x0003
Bus: 8, Device: 1 Path: 8
Found device 2 idVendor=0x045e idProduct=0x0719
Bus: 7, Device: 5 Path: 7-4
Found device 3 idVendor=0x03f0 idProduct=0x094a
Bus: 7, Device: 4 Path: 7-3
Found device 4 idVendor=0x17f6 idProduct=0x0862
Bus: 7, Device: 3 Path: 7-2
Found device 5 idVendor=0x05ac idProduct=0x1301
Bus: 7, Device: 2 Path: 7-1
Found device 6 idVendor=0x1d6b idProduct=0x0002
Bus: 7, Device: 1 Path: 7
Found device 7 idVendor=0x1d6b idProduct=0x0003
Bus: 6, Device: 1 Path: 6
Found device 8 idVendor=0x1d6b idProduct=0x0002
Bus: 5, Device: 1 Path: 5
Found device 9 idVendor=0x1d6b idProduct=0x0003
Bus: 4, Device: 1 Path: 4
Found device 10 idVendor=0x1d6b idProduct=0x0002
Bus: 3, Device: 1 Path: 3
Found device 11 idVendor=0x1d6b idProduct=0x0003
Bus: 2, Device: 1 Path: 2
Found device 12 idVendor=0x0a5c idProduct=0x2711
Bus: 1, Device: 8 Path: 1-6
Found candidate Compute Module...Loading embedded: bootcode4.bin
Device located successfully
Initialised device correctly
Found serial number 3
Sending bootcode.bin
libusb_bulk_transfer sent 24 bytes; returned 0
Writing 121944 bytes
libusb_bulk_transfer sent 121944 bytes; returned 0
Successful read 4 bytes
Waiting for BCM2835/6/7/2711...
Found device 1 idVendor=0x1d6b idProduct=0x0003
Bus: 8, Device: 1 Path: 8
Found device 2 idVendor=0x045e idProduct=0x0719
Bus: 7, Device: 5 Path: 7-4
Found device 3 idVendor=0x03f0 idProduct=0x094a
Bus: 7, Device: 4 Path: 7-3
Found device 4 idVendor=0x17f6 idProduct=0x0862
Bus: 7, Device: 3 Path: 7-2
Found device 5 idVendor=0x05ac idProduct=0x1301
Bus: 7, Device: 2 Path: 7-1
Found device 6 idVendor=0x1d6b idProduct=0x0002
Bus: 7, Device: 1 Path: 7
Found device 7 idVendor=0x1d6b idProduct=0x0003
Bus: 6, Device: 1 Path: 6
Found device 8 idVendor=0x1d6b idProduct=0x0002
Bus: 5, Device: 1 Path: 5
Found device 9 idVendor=0x1d6b idProduct=0x0003
Bus: 4, Device: 1 Path: 4
Found device 10 idVendor=0x1d6b idProduct=0x0002
Bus: 3, Device: 1 Path: 3
Found device 11 idVendor=0x1d6b idProduct=0x0003
Bus: 2, Device: 1 Path: 2
Found device 12 idVendor=0x0a5c idProduct=0x2711
Bus: 1, Device: 8 Path: 1-6
Found candidate Compute Module...Loading embedded: bootcode4.bin
Device located successfully
Initialised device correctly
Found serial number 3
Sending bootcode.bin
Failed control transfer (-7,24)
Failed to write correct length, returned -7
Waiting for BCM2835/6/7/2711...
Found device 1 idVendor=0x1d6b idProduct=0x0003
Bus: 8, Device: 1 Path: 8
Found device 2 idVendor=0x045e idProduct=0x0719
Bus: 7, Device: 5 Path: 7-4
Found device 3 idVendor=0x03f0 idProduct=0x094a
Bus: 7, Device: 4 Path: 7-3
Found device 4 idVendor=0x17f6 idProduct=0x0862
Bus: 7, Device: 3 Path: 7-2
Found device 5 idVendor=0x05ac idProduct=0x1301
Bus: 7, Device: 2 Path: 7-1
Found device 6 idVendor=0x1d6b idProduct=0x0002
Bus: 7, Device: 1 Path: 7
Found device 7 idVendor=0x1d6b idProduct=0x0003
Bus: 6, Device: 1 Path: 6
Found device 8 idVendor=0x1d6b idProduct=0x0002
Bus: 5, Device: 1 Path: 5
Found device 9 idVendor=0x1d6b idProduct=0x0003
Bus: 4, Device: 1 Path: 4
Found device 10 idVendor=0x1d6b idProduct=0x0002
Bus: 3, Device: 1 Path: 3
Found device 11 idVendor=0x1d6b idProduct=0x0003
Bus: 2, Device: 1 Path: 2
Found device 12 idVendor=0x0a5c idProduct=0x2711
Bus: 1, Device: 8 Path: 1-6
Found candidate Compute Module...Loading embedded: bootcode4.bin
Device located successfully
Initialised device correctly
Found serial number 3
Sending bootcode.bin
Failed control transfer (-7,24)
Failed to write correct length, returned -7

transfer error: device not responding

libusb: warning [darwin_transfer_status] transfer error: device not responding (value = 0xe00002ed)
Second stage boot server done
libusb: warning [darwin_close] USBDeviceClose: no connection to an IOService

RpiBoot - windows - fixed hardware-id

Hy,

I got an issue when i try to detect the drive letter after the rpiboot finishes.
I am using windows and the rpiboot.exe which comes with the installer.
(actually the sources here are not the same, these here are newer)

My motivation is to get more a unique identifier to
parallel flash multiple cm3 boards.

In windows 7, when rpiboot finishes, its always the last drive letter.

but the procedure gets confused sometimes, still to figure out for me...
its because, rpiboot and msd-drive detection are separate.

Network would be an option, as mentioned in the previous issue, but i want to try usb only first.

My only clue for an unique-id, which would improve it, is the Hardware id of the drive, but is always Rpi-MSD-0001
It does change when i manually edid the "Rpi-MSD" suffix into something else with a hex editor
in msd.elf.

-linux probably works but not windows

I can patch the msd.elf to change the suffix
(its in the file : )
own.Jungo...RPi.MSD.TASK.%s.R.W.on.off.on.off..

but i like to change the 0001 into 0002 and so on...
replacing the %s by 0001 does not help.

Is there a source of msd.elf (if its not too complicated to compile)?

Thanks for your help,

Martin

MSD stopped being exposed

This has been working for me, but at some point CM3 goes to state where MSD is no more exposed on secondary USB port. As matter of fact there seems to be no USB device exposed at all.
usbboot does not show any obvious error and second stage bootloader is loaded to the device successfully.
lsusb on host computer does not show anything connected on USB though once second stage bootloader is loaded.
I have now two CM3 in this state. Filesystem on CM3 itself seems to be still fine, as normal boot still works, however I can't get it anymore to MSD mode.
I can't really say how to get CM3 to this state either, as all I was doing was debugging u-boot boot
Any thoughts?
Or may be adding boot artefacts which would have option to reset emmc on CM3?

rpiboot program encounter Failed control transfer.

I have flashed eMMC via Raspberry Pi 4B with ./rpiboot, and it shows some error , does it matter?
pi@rpi8g:~/usbboot $ make

cc -Wall -Wextra -g -o bin2c bin2c.c
./bin2c msd/bootcode.bin msd/bootcode.h
./bin2c msd/start.elf msd/start.h
./bin2c msd/bootcode4.bin msd/bootcode4.h
./bin2c msd/start4.elf msd/start4.h
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0

pi@rpi8g:~/usbboot $ sudo ./rpiboot

Loading embedded: bootcode4.bin
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Sending bootcode.bin
Failed control transfer (-1,24)
Failed to write correct length, returned -1
Waiting for BCM2835/6/7/2711...
Loading embedded: bootcode4.bin
Second stage boot server
Loading embedded: start4.elf
File read: start4.elf
Second stage boot server done

never stops

i'm running this on a rpi3 to flash a CM3. running ./rpiboot never exits after killing the process the device /dev/sdX is there and working.

running ./rpiboot -v -l also shows that it can't find some file/files.

Non MSD boot on Pi4-CM

I cannot figure out how to boot a kernel from rpiboot.
As mentioned in README file, I've copied the boot partition and run rpiboot with -d option without any joy.
I had to include the bootcode4.bin from the msd directory, which is what seems the only bootcode available online.

Any suggestion or can anyone point out what I'm doing wrong?

In any case, this is the output of rpiboot:

sudo ./rpiboot -v -v -d boot
Boot directory 'boot'
Loading: boot/bootcode4.bin
Waiting for BCM2835/6/7/2711...
Loading: boot/bootcode4.bin
Device located successfully
libusb: error [udev_hotplug_event] ignoring udev action bind
Initialised device correctly
Found serial number 3
Sending bootcode.bin
libusb_bulk_transfer sent 24 bytes; returned 0
Writing 99540 bytes
libusb_bulk_transfer sent 99540 bytes; returned 0
Successful read 4 bytes 
Waiting for BCM2835/6/7/2711...
Loading: boot/bootcode4.bin
Device located successfully
Failed to open the requested device
Loading: boot/bootcode4.bin
Device located successfully
libusb: error [udev_hotplug_event] ignoring udev action bind
Initialised device correctly
Found serial number 1
Second stage boot server
Received message GetFileSize: config.txt
Loading: boot/config.txt
File size = 212 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer sent 212 bytes; returned 0
Received message GetFileSize: pieeprom.sig
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file pieeprom.sig
Received message GetFileSize: recover4.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recover4.elf
Received message GetFileSize: recovery.elf
libusb_bulk_transfer sent 0 bytes; returned 0
Cannot open file recovery.elf
Received message GetFileSize: start4.elf
Loading: boot/start4.elf
File size = 2230848 bytes
Received message ReadFile: start4.elf
File read: start4.elf
libusb_bulk_transfer sent 2230848 bytes; returned 0
Received message GetFileSize: fixup4.dat
Loading: boot/fixup4.dat
File size = 5429 bytes
Received message ReadFile: fixup4.dat
File read: fixup4.dat
libusb_bulk_transfer sent 5429 bytes; returned 0
Second stage boot server done

Pi0 does not exec kernel.img when using -d

It boots to the "rainbow screen of life" but then goes no further. From what I read that indicates kernel.img is not launching.

Files are requested and loaded, changes to config.txt do cause changes in what is loaded (as should be expected). Everything appears to fully load, and no errors in my best configuration (eg failed to transfer control, "Failed : 0x..." - which I have seen in some of my failed tests mentioned below).

A list of what I have tried so far

I have tried two different Pi0s (non-W) to ensure one was not defective.

I have tried every commit with no success. Every one including the first few that did not even get to stage 2 on a Pi0.

I have tried both stock Jessie boot files as well as custom kernels and a bare metal helloworld.

I have tried with and without a usb hub (the hub does get in the way a bit).

I have tried some older start.elf/bootcode.bin files (got 8 blinks indicating they were too old).

I wrote my own bootcode.bin that just blits data to the serial port. That works. That is the only thing I can get to work. This however does not init the arm, etc so its of limited functionality.

I am running out of ideas for things I can try to rule out anything on my end, with my gear, etc. I am starting to think the problem must be in start.elf not properly jumping to where it should jump to.

Unable to generate valid boot.img using tools/make-boot-image

I am facing to problem with the make-boot-image tool.
My final goal would be to generate a boot.img which I can upload using the rpiboot.exe tool.
First of all I started with the files from the imager subdirectory, I mounted the /imager/boot.img file to checkout the required files and configurations. I then copied the content of the boot.img file, using my mount point, to a new directory called ../secure-boot-files.
I then unmounted the /imager/boot.img file.
Next I called the following command for the usbboot toplevel directory:
sudo ./tools/make-boot-image -d secure-boot-files -o boot.img

The result is a 22MB boot.img file, while the original /imager/boot.img file has a filesize of approx. 42MB.
When I mount the 22MB boot.img file I get an empty directory, while mounting the /imager/boot.img gave me an list of familiar files(*.dtb etc).

What went wrong in my setup, for the files not to show up in the generated boot.img file?

Sending bootcode.bin repeatedly failing

Trying to flash a CM3 from a Pi B+ (Jessie), I found that the rpiboot was repeatedly failing

Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes 
Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes 
Waiting for BCM2835/6/7
Sending bootcode.bin
Failed to write correct length, returned 0
Waiting for BCM2835/6/7
Sending bootcode.bin
Failed to write correct length, returned 0
Waiting for BCM2835/6/7
Sending bootcode.bin
Failed to write correct length, returned 0
Waiting for BCM2835/6/7
Sending bootcode.bin

The -v option provided more information:

Sending bootcode.bin
libusb_bulk_transfer returned -7
Failed to write correct length, returned 0

From libusb.h, -7 is LIBUSB_ERROR_TIMEOUT and this corresponded with it taking 100 seconds per attempt.

After a couple of hours debugging (including trying from a different machine), I found the problem: the length field of boot_message was being set to zero. This in turn is due to the way fseek(f,SEEK_END) works on a file opened with the (somewhat non-portable) fmemopen() function: when opened with "r" as opposed to "rb", the end of the file is the location of the first null byte, i.e. the very beginning of the bootcode. Probably this behaviour depends on version or implementation of fmemopen, as I guess it must have worked OK for other people.

I would suggest adding at least a sanity check on the length, or maybe ditching the use of fmemread and passing pointer+size info around instead of file handles.

The work-around is to specify the directory explicitly i.e.

  sudo ./rpiboot -d msd

Booting multiple RPis in Parallel

Hi guys!
I'm using a non-SD card setup of 6 x RPi zero that booting with rpiboot and fetching the filesystem from NFS folder.
The issue here is that booting them serially with rpiboot takes a lot of time.
Is there a way using rpiboot on multiple RPis in parallel instead of using the loop flag (-l) that boots serially.

Thanks!

Raspberry Pi 4?

Hi,

Is RPi4 support for this feasible considering that it has an OTG USB Type-C port?

Thanks,

rpiboot is busy-waiting ?!?

On a fairly high-end i7-6500U based system, rpiboot is consuming 7 to 11 percent of CPU without doing something. What a nightmare. If you're waiting for a USB device to enumerate, you can actually register for events. I don't get why there should ever be any polling or busy-waiting/looping involved.

http://libusb.sourceforge.net/api-1.0/group__libusb__hotplug.html describes how to register a call-back for hot-plug event notification.

usbboot/libusb cannot parse endpoints on windows 7

Hy,

I cannot really explain the cause.

On some machines with windows 7 rpiboot fails.
Windows 10 works in my particular instance.

Here the output from "rpiboot -v"

Found device 4 idVendor=0x04f2 idProduct=0xb51c
Bus: 1, Device: 5 Path: 1-9
Found device 5 idVendor=0x0a5c idProduct=0x2764
Bus: 1, Device: 19 Path: 1-1.3
Device located successfully
libusb: error [parse_endpoint] invalid extra ep desc len (0)
libusb: error [raw_desc_to_config] parse_configuration failed with error -1
libusb: warning [winusbx_claim_interface] auto-claimed interface 0 (required to
claim 1 with WinUSB)
Failed to claim interface

In the above log-messages, the messages prefixed by "libusb:"
are showing that the endpoint cannot be parsed and thus cannot send bootcode.bin.

Ignoring the error (compile by vs-2012) does not help.

I could be a driver issue, but it could also be solved by the app.
I dont know, a direction would be appreciated.

(I am not a driver expert and looking into libusb is a bit ... on most machines i obeserved, it does work)

i have also a usb-tree good-bad diff...

From the usb-treeview on both machines, left side results in good cmboot, right side bad -.

good_bad

Observations from the diff:
-configuration desriptor has more data bigger ( bad has 0x55, good 0x32 )
-bad reports eventually a empty interface as third interface
-good has appearantly a out/out interface, bad has out/in, bad might be the winner here
-endpoint adresses are not the same (at least meant for the out endpoint), even...

Maybe this might be interesting because some machines dont work.
-and they all got usb3 only ( intel usb 3.0 extensible Hostcontroller )

I know this is very specific and is not really an issue of rpiboot itself.

Thanks Martin

-update
It might also be a libusb issue, since i wrote myself an example only using winusb (https://github.com/madwizard-thomas/winusbnet)

and this one works always finding the endpoints
(see txt, its a c# program, converted from usbboot/main.c)

rpiboot.txt

Unknown issue preventing flashing

I am trying to flash a CM3 using an IO board. I have built the latest rpiboot:

$> sudo ./rpiboot
Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7
Second stage boot server
File read: start.elf
Second stage boot server done
$> lsblk | tail -n 3
sdg                    8:96   1   3.7G  0 disk
├─sdg1                 8:97   1  41.8M  0 part
└─sdg2                 8:98   1   3.6G  0 part

The issue is dd falsely claiming the transfer is working:

$> sudo dd if=base.img of=/dev/sdg bs=4MiB status=progress
1577058304 bytes (1.6 GB, 1.5 GiB) copied, 1.00206 s, 1.6 GB/s
442+1 records in
442+1 records out
1854418944 bytes (1.9 GB, 1.7 GiB) copied, 1.18432 s, 1.6 GB/s
$> sync # completes in under a second

in dmesg:

[52248.793936] usb 1-6: new high-speed USB device number 24 using ehci-pci
[52248.932326] usb-storage 1-6:1.0: USB Mass Storage device detected
[52248.932672] scsi host6: usb-storage 1-6:1.0
[52249.958182] scsi 6:0:0:0: Direct-Access     RPi-MSD- 0001                  PQ: 0 ANSI: 2
[52249.958828] sd 6:0:0:0: Attached scsi generic sg6 type 0
[52249.960029] sd 6:0:0:0: [sdg] 7634944 512-byte logical blocks: (3.91 GB/3.64 GiB)
[52249.960784] sd 6:0:0:0: [sdg] Write Protect is off
[52249.960788] sd 6:0:0:0: [sdg] Mode Sense: 0f 00 00 00
[52249.961597] sd 6:0:0:0: [sdg] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[52249.967401]  sdg: sdg1 sdg2
[52249.970137] sd 6:0:0:0: [sdg] Attached SCSI removable disk

Please let me know and I'll provide any necessary info.

bootcode.bin broken for CM1

Commit d7b97b3 introduced a regression on the CM1. It looks like the device crashes after downloading bootcode.bin. This is with current master:

[12142.048382] usb 3-1: new full-speed USB device number 5 using xhci_hcd
[12142.189371] usb 3-1: New USB device found, idVendor=0a5c, idProduct=2763
[12142.192112] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[12142.194877] usb 3-1: Product: BCM2708 Boot
[12142.197646] usb 3-1: Manufacturer: Broadcom
# ./rpiboot
Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes
[12145.072263] usb 3-1: USB disconnect, device number 5
[12146.448271] usb 3-1: new high-speed USB device number 6 using xhci_hcd
[12146.568294] usb 3-1: device descriptor read/64, error -71
[12146.796286] usb 3-1: device descriptor read/64, error -71
Waiting for BCM2835/6/7

The device appears dead afterwards. Switching to d7b97b3^ fixes the issue.

Since this seems to be caused by the closed-source bootcode.bin, it can't be fixed by the community but only by the Foundation.

"Failed to write complete file to USB device" when using custom hardware

Hi

in an effort to streamline the process of programming multiple CMs we designed a custom pcb following the official IO-Boards usb circuit.
flash adapter

flasher3

When booting the CMs as a mass storage device it works as intended. Currently we are using 16x flash pcbs at once and some command line magic to make it all happen.

Now we tried to boot the CMs with the directory option
sudo ./rpiboot -d /outputdir

This fails with following output:

philip@Dell:~/usbboot$ sudo ./rpiboot -v -d /media/philip/ext4_Entwicklung/scriptexecutor/output
Waiting for BCM2835/6/7
Device located successfully
Initialised device correctly
Found serial number 0
Sending bootcode.bin
libusb_bulk_transfer returned 0
Writing 50216 bytes
libusb_bulk_transfer returned 0
Successful read 4 bytes
Waiting for BCM2835/6/7
Device located successfully
Initialised device correctly
Found serial number 1
Second stage boot server
Received message GetFileSize: autoboot.txt
Cannot open file autoboot.txt
Received message GetFileSize: config.txt
File size = 47885 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer returned 0
Received message GetFileSize: recovery.elf
Cannot open file recovery.elf
Received message GetFileSize: start.elf
File size = 2855972 bytes
Received message ReadFile: start.elf
File read: start.elf
libusb_bulk_transfer returned 0
Received message GetFileSize: fixup.dat
File size = 6669 bytes
Received message ReadFile: fixup.dat
File read: fixup.dat
libusb_bulk_transfer returned 0
Received message GetFileSize: recovery.elf
Cannot open file recovery.elf
Received message GetFileSize: config.txt
File size = 47885 bytes
Received message ReadFile: config.txt
File read: config.txt
libusb_bulk_transfer returned -7
Failed to write complete file to USB device

If i switch the exact CM to the official IO-Board and execute the exact command it works as expected.

Tested on Ubuntu 17.10

Loop/wait - Waiting for BCM2835/6/7/2711... hangs/loops - no error messages/diagnostics.

Hello all,

the above is happening on a CM4 Lite, 8GB using a SYNOLOGY SNV3400-400G NVM SSD.
The above NVME SSD has been used in othe Pi instances, ergo it is functional.
Some details -
CM4
Hardware : BCM2835
Revision : d03140
Serial : 1000000084d13d6a
Model : Raspberry Pi Compute Module 4 Rev 1.0

root@raspberrypi:/Transit/rpi-usbboot-master# uname -a
Linux raspberrypi 5.10.39-v8+ #1421 SMP PREEMPT Tue May 25 11:04:26 BST 2021 aarch64 GNU/Linux

root@raspberrypi:/Transit/rpi-usbboot-master# vcgencmd bootloader_version
Apr 29 2021 17:11:25
version c2f8c388c4ee37ad709ace403467d163e8dd91ce (release)
timestamp 1619712685
update-time 1622810466
capabilities 0x0000001f

In the usbboot directory, when I issue "./rpiboot -d nvme" I receive the error mentioned in the title line.
I have issued the rpiboot commad with the -v switch, alas nothing.
As a result of the above issues, I cannot boot the CM4 with the NVME SSD.

Any pointers/thoughts most welcome. Any further information you need, please let me know.

Regards,

Ry

[question] Possible to make rpiboot return the /dev/sd? or find it otherwise - reliably

Hi there,

I want to script an image update process for my CM4, and hoping you can point out how to get the /dev/sd? that will appear after ./rpiboot is executed.

Can it be returned somehow, or have a shell method to find it reliably? I'd hate for another drive to be added ad-hoc to the machine and accidentally it's overwritten by a hardcoded /dev/sdd in my dd command.

Cheers

Mass programming usage?

Hi

I'm brain storming a few ideas on how to create a mass programming method to write out the flash on multiple CMs at a time.

So far I've been using a Linux PC with rpi boot and a series of bash scripts to parition, format and untar the two partitions, this makes the whole process a lot quicker than using winimage/dd to write the whole 4Gbyte flash.

I'm wondering if there's a way to gang up multiple CMs and have rpi-boot listen on a specific USB bus/port id, couple this with a few udev rules and that would make a half-decent programming station.

So would it be possible to create a version of this that only responds/listens to a specific USB instance?

For the purposes of the enquiry let's assume a Linux only environment if that makes it easier.

make: *** [rpiboot] Error 1

Hi,

First of all i follow this link for installation.

When i install usbboot in my mac, i got this error:

cc -Wall -Wextra -g -o bin2c bin2c.c
./bin2c msd/bootcode.bin msd/bootcode.h
./bin2c msd/start.elf msd/start.h
cc -Wall -Wextra -g -o rpiboot main.c -lusb-1.0
main.c:394:16: warning: comparison of array 'pathname' not equal to a null pointer is always
      true [-Wtautological-pointer-compare]
                if(overlay&&(pathname != NULL))
                             ^~~~~~~~    ~~~~
main.c:417:9: warning: implicit declaration of function 'fmemopen' is invalid in C99
      [-Wimplicit-function-declaration]
                        fp = fmemopen(msd_bootcode_bin, msd_bootcode_bin_len, "r");
                             ^
main.c:417:7: warning: incompatible integer to pointer conversion assigning to 'FILE *'
      (aka 'struct __sFILE *') from 'int' [-Wint-conversion]
                        fp = fmemopen(msd_bootcode_bin, msd_bootcode_bin_len, "r");
                           ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:420:8: warning: incompatible integer to pointer conversion assigning to 'FILE *'
      (aka 'struct __sFILE *') from 'int' [-Wint-conversion]
                                fp = fmemopen(msd_start_elf, msd_start_elf_len, "r");
                                   ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:601:2: warning: 'libusb_set_debug' is deprecated [-Wdeprecated-declarations]
        libusb_set_debug(ctx, verbose ? LIBUSB_LOG_LEVEL_WARNING : 0);
        ^
/usr/local/include/libusb-1.0/libusb.h:1299:1: note: 'libusb_set_debug' has been explicitly
      marked deprecated here
LIBUSB_DEPRECATED_FOR(libusb_set_option)
^
/usr/local/include/libusb-1.0/libusb.h:89:49: note: expanded from macro 'LIBUSB_DEPRECATED_FOR'
#define LIBUSB_DEPRECATED_FOR(f) __attribute__((deprecated))
                                                ^
5 warnings generated.
Undefined symbols for architecture x86_64:
  "_fmemopen", referenced from:
      _check_file in main-6a807a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [rpiboot] Error 1

I already install lib usb that i directly download from here

When i do make here what i got

/Library/Developer/CommandLineTools/usr/bin/make  all-recursive
Making all in libusb
  CC       libusb_1_0_la-core.lo
  CC       libusb_1_0_la-descriptor.lo
  CC       libusb_1_0_la-hotplug.lo
  CC       libusb_1_0_la-io.lo
  CC       libusb_1_0_la-strerror.lo
  CC       libusb_1_0_la-sync.lo
  CC       os/libusb_1_0_la-poll_posix.lo
  CC       os/libusb_1_0_la-threads_posix.lo
  CC       os/libusb_1_0_la-darwin_usb.lo
  CCLD     libusb-1.0.la
Making all in doc
make[2]: Nothing to be done for `all'.
make[2]: Nothing to be done for `all-am'.

Then install

Making install in libusb
 .././install-sh -c -d '/usr/local/lib'
 /bin/sh ../libtool   --mode=install /usr/bin/install -c   libusb-1.0.la '/usr/local/lib'
libtool: install: /usr/bin/install -c .libs/libusb-1.0.0.dylib /usr/local/lib/libusb-1.0.0.dylib
libtool: install: (cd /usr/local/lib && { ln -s -f libusb-1.0.0.dylib libusb-1.0.dylib || { rm -f libusb-1.0.dylib && ln -s libusb-1.0.0.dylib libusb-1.0.dylib; }; })
libtool: install: /usr/bin/install -c .libs/libusb-1.0.lai /usr/local/lib/libusb-1.0.la
libtool: install: /usr/bin/install -c .libs/libusb-1.0.a /usr/local/lib/libusb-1.0.a
libtool: install: chmod 644 /usr/local/lib/libusb-1.0.a
libtool: install: ranlib /usr/local/lib/libusb-1.0.a
 .././install-sh -c -d '/usr/local/include/libusb-1.0'
 /usr/bin/install -c -m 644 libusb.h '/usr/local/include/libusb-1.0'
Making install in doc
make[2]: Nothing to be done for `install-exec-am'.
make[2]: Nothing to be done for `install-data-am'.
make[2]: Nothing to be done for `install-exec-am'.
 ./install-sh -c -d '/usr/local/lib/pkgconfig'
 /usr/bin/install -c -m 644 libusb-1.0.pc '/usr/local/lib/pkgconfig'

I need rpiboot for flashing compute module for my project. Is there something that i miss?

having problem with rpiboot-help

have a 5 Ninjas Raspberry Slice, and followed the process of upgrading to a CM3 from CM1. I diid the upgrade about 4 months back, and not being an expert I was very pleased cause everything worked fine. However, over the last few weeks I found the system was slow to boot, and yesterday tried to use the device and nothing would load. So I thought go through the flashing and loading LibreElec again. Thats when my problems started and had no success.

This is what appears in Terminal when i write the command :- $ Sudo ./rpiboot

Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7
Second stage boot server
File read: start.elf

The slice then appears on my iMac and I can successfully install LibreELEC using the app LibreELEC USB- SD Creator. Files are clearly showing on the slice. I then elect the slice, switch off etc. However if I attach the device back to the iMac to ensure I can still see the device it is no longer there. As if the information has not been stored on the CM3.

So I then went back through the process but used this command. $ sudo ./rpiboot -v
This is what appears.

colins-iMac-2:usbboot colinbeynon$ sudo ./rpiboot -v
Waiting for BCM2835/6/7
Device located successfully
Initialised device correctly
Found serial number 0
Sending bootcode.bin
libusb_bulk_transfer returned 0
Writing 51992 bytes
libusb_bulk_transfer returned 0
Successful read 4 bytes
Waiting for BCM2835/6/7
Device located successfully
Failed to open the requested device
Device located successfully
Initialised device correctly
Found serial number 1
Second stage boot server
Received message GetFileSize: autoboot.txt
Cannot open file autoboot.txt
Received message GetFileSize: config.txt
Cannot open file config.txt
Received message GetFileSize: recovery.elf
Cannot open file recovery.elf
Received message GetFileSize: start.elf
File size = 433616 bytes
Received message ReadFile: start.elf
File read: start.elf
libusb_bulk_transfer returned 0
Received message GetFileSize: fixup.dat
Cannot open file fixup.dat
libusb: error [submit_control_transfer] control request failed: no connection to an IOService
Second stage boot server done
libusb: warning [darwin_release_interface] USBInterfaceClose: no connection to an IOService

Is there a problem with the CM3, or am i doing something wrong.

Buildroot.elf still obsolete

Continuation of raspberrypi/tools#44 : buildroot.elf is still dated Oct 28 2014

It was suggested that buildroot.elf would be replaced with the standard start.elf from firmware-next, so that the Pi Zero could boot as a USB Device without an SD card, in the same way that it can now boot as a USB Host with only bootcode.bin on an SD card.

can this lead to the pi turning off?

I'm working with this code, or some variant via the ClusterHAT and I'm seeing behavior across several pi-zero's 1.2 &1.3 (no wifi or headers). The pi's respond to ping over gadget mode, but not ssh or other commands. Sometimes they wake after a time. Other-times not. A Power cycle works

I have to run the tool twice to make the device switch to storage mode

After the first run:

andrei@carbonA rpi-usbboot $ sudo ./rpiboot 
Waiting for BCM2835/6/7
Sending bootcode.bin
Successful read 4 bytes

... nothing detected. After re-running it:

andrei@carbonA rpi-usbboot $ sudo ./rpiboot 
Waiting for BCM2835/6/7
Second stage boot server
File read: start.elf

... correctly detected.

[Request] Support booting from SD1

As discussed in the forum it would be nice to be able to boot from an external SD card connected to GPIO34-39.

An improvement on this would be to be able to set the width of the data bus so 8 bit is also supported, using pins GPIO34-43

Circular loop between raspberrypi/usbboot title or description and raspberrypi/tools/usbboot readme.md

This git repo title/description says:

Raspberry Pi USB booting code, moved from tools repository

The raspberrypi tools repository readme.md
https://github.com/raspberrypi/tools/blob/master/usbboot/Readme.md
Says:

Please note, this code has now moved to
https://github.com/raspberrypi/usbboot.git

While I love these circular loops jokes, I can imagine that this was not done on purpose. Maybe fix this project title/description?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.