Introduction
Flashing an operating-system image to the Compute Module 5 is slightly different from what you may be used to with a traditional Raspberry Pi. With a regular Raspberry Pi, the usual procedure is to write Raspberry Pi OS to a microSD card using Raspberry Pi Imager, insert the card into the Pi, and boot. The CM5, however, does not have a microSD card slot. The operating system is installed on the module's onboard eMMC storage instead.
To do this, the CM5 is connected to a computer through the USB interface on the IO board and placed into USB boot mode. The host computer can then detect the CM5 storage, allowing Raspberry Pi Imager to write the selected operating-system image directly to it. This extra step makes the first installation a little less straightforward than with a conventional Raspberry Pi, but once the CM5 is set up, the boot process is essentially the same as you would expect from a Raspberry Pi.
Installing the tools on the host computer
For the host computer, I decided to use my Raspberry Pi 400. The tool required to flash the CM5 over USB is rpiboot. According to the official documentation, rpiboot can be installed using apt:
me@raspberrypi:~ $ sudo apt install rpiboot Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: rpiboot 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 76.7 MB of archives. After this operation, 108 MB of additional disk space will be used. Get:1 http://archive.raspberrypi.org/debian bullseye/main armhf rpiboot armhf 20221215~105525 [76.7 MB] Fetched 76.7 MB in 26s (2,934 kB/s) Selecting previously unselected package rpiboot. (Reading database ... 174846 files and directories currently installed.) Preparing to unpack .../rpiboot_20221215~105525_armhf.deb ... Unpacking rpiboot (20221215~105525) ... Setting up rpiboot (20221215~105525) ... me@raspberrypi:~ $
Flashing
Next, a jumper needs to be placed on J2 on the IO board. This disables eMMC boot mode and allows the eMMC to be accessed and written to over USB. No jumper was included with the kit, but luckily I have a well-stocked junk box, so finding a suitable one was no problem.

Finaly connect the IO board to the host computer over USB.

Now on the host computer mount the eMMC with the rpiboot command.
me@raspberrypi:~ $ rpiboot RPIBOOT: build-date Dec 15 2022 version 20221215~105525 7aa7e758 Waiting for BCM2835/6/7/2711...
Unfortunately nothing happend. Also it shows that his rpiboot version is already quite old, from 2022. After some reading at the usbboot troubleshooting guide I decided to try a newer version, by downloading and compiling it from github.
me@raspberrypi:~ $ wget https://github.com/raspberrypi/usbboot/archive/refs/heads/master.zip --2026-09-02 20:33:31-- https://github.com/raspberrypi/usbboot/archive/refs/heads/master.zip Resolving github.com (github.com)... 140.82.121.4 Connecting to github.com (github.com)|140.82.121.4|:443... connected. HTTP request sent, awaiting response... 302 Found Location: https://codeload.github.com/raspberrypi/usbboot/zip/refs/heads/master [following] --2026-09-02 20:33:32-- https://codeload.github.com/raspberrypi/usbboot/zip/refs/heads/master Resolving codeload.github.com (codeload.github.com)... 140.82.121.10 Connecting to codeload.github.com (codeload.github.com)|140.82.121.10|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 126933862 (121M) [application/zip] Saving to: ‘master.zip’ master.zip 100%[==================================>] 121.05M 8.46MB/s in 14s 2026-09-02 20:33:53 (8.87 MB/s) - ‘master.zip’ saved [126933862/126933862]
me@raspberrypi:~ $ unzip master.zip Archive: master.zip 3090a13e58b7f55c4941c56134501e1934744137 creating: usbboot-master/ creating: usbboot-master/.github/ creating: usbboot-master/.github/ISSUE_TEMPLATE/ inflating: usbboot-master/.github/ISSUE_TEMPLATE/bug_report.yml inflating: usbboot-master/.github/ISSUE_TEMPLATE/config.yml inflating: usbboot-master/.github/ISSUE_TEMPLATE/feature_request.md ...........long list of files ..................... usbboot-master/tools/rpi-otp-private-key -> ../rpi-eeprom/tools/rpi-otp-private-key usbboot-master/tools/rpi-sign-bootcode -> ../rpi-eeprom/tools/rpi-sign-bootcode me@raspberrypi:~ $ me@raspberrypi:~ $ cd usbboot-master/ me@raspberrypi:~/usbboot-master $ ls bin2c.c docs main.c msd rpi-imager-embedded test bootfiles.c eeprom-erase Makefile Readme.md secure-boot-example tools bootfiles.h firmware mass-storage-gadget recovery secure-boot-msd win32 decode_duid.c fmemopen.c mass-storage-gadget64 recovery5 secure-boot-recovery decode_duid.h LICENSE mass-storage-gadget64-cm3 rpi-eeprom secure-boot-recovery5 me@raspberrypi:~/usbboot-master $
Install nescesary libraries:
me@raspberrypi:~ $ me@raspberrypi:~/usbboot-master $ sudo apt install git libusb-1.0-0-dev pkg-config build-essential Reading package lists... Done Building dependency tree... Done Reading state information... Done build-essential is already the newest version (12.9). git is already the newest version (1:2.30.2-1+deb11u5). pkg-config is already the newest version (0.29.2-1). The following additional packages will be installed: libusb-1.0-doc The following NEW packages will be installed: libusb-1.0-0-dev libusb-1.0-doc 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 263 kB of archives. After this operation, 1,861 kB of additional disk space will be used. Do you want to continue? [Y/n] Get:1 http://mirror.truenetwork.ru/raspbian/raspbian bullseye/main armhf libusb-1.0-0-dev armhf 2:1.0.24-3 [70.8 kB] Get:2 http://ftp.tsukuba.wide.ad.jp/Linux/raspbian/raspbian bullseye/main armhf libusb-1.0-doc all 2:1.0.24-3 [192 kB] Fetched 263 kB in 9s (30.5 kB/s) Selecting previously unselected package libusb-1.0-0-dev:armhf. (Reading database ... 174898 files and directories currently installed.) Preparing to unpack .../libusb-1.0-0-dev_2%3a1.0.24-3_armhf.deb ... Unpacking libusb-1.0-0-dev:armhf (2:1.0.24-3) ... Selecting previously unselected package libusb-1.0-doc. Preparing to unpack .../libusb-1.0-doc_2%3a1.0.24-3_all.deb ... Unpacking libusb-1.0-doc (2:1.0.24-3) ... Setting up libusb-1.0-doc (2:1.0.24-3) ... Setting up libusb-1.0-0-dev:armhf (2:1.0.24-3) ... me@raspberrypi:~/usbboot-master $
And build the program:
me@raspberrypi:~/usbboot-master $ make cc -Wall -Wextra -g -o rpiboot main.c bootfiles.c decode_duid.c `pkg-config --cflags --libs libusb-1.0` -DGIT_VER="\"\"" -DPKG_VER="\"local\"" -DBUILD_DATE="\"2026/09/02\"" -DDEFAULT_MSG_DIR=\"/usr/share/rpiboot/mass-storage-gadget64/\" me@raspberrypi:~/usbboot-master $
Try again, and success!
me@raspberrypi:~/usbboot-master $ sudo ./rpiboot -d mass-storage-gadget64 RPIBOOT: build-date 2026/09/02 pkg-version local Please fit the EMMC_DISABLE / nRPIBOOT jumper before connecting the power and USB cables to the target device. If the device fails to connect then please see https://rpltd.co/rpiboot for debugging tips. Loading: mass-storage-gadget64/bootfiles.bin Using mass-storage-gadget64/bootfiles.bin Waiting for BCM2835/6/7/2711/2712... Sending bootcode.bin Successful read 4 bytes Waiting for BCM2835/6/7/2711/2712... Second stage boot server File read: mcb.bin File read: memsys00.bin File read: memsys01.bin File read: rp1c0fw1.bin File read: memsys02.bin File read: rp1c0fw2.bin File read: memsys03.bin File read: bootmain Loading: mass-storage-gadget64/config.txt File read: config.txt Loading: mass-storage-gadget64/boot.img File read: boot.img Second stage boot server done me@raspberrypi:~/usbboot-master $
This can also be checked with lsblk, which nicely shows the eMMC drive (sda).
me@raspberrypi:~ $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 1 29.1G 0 disk mmcblk0 179:0 0 14.8G 0 disk ├─mmcblk0p1 179:1 0 256M 0 part /boot └─mmcblk0p2 179:2 0 14.6G 0 part /
Now with the use of the Raspberry Pi Imager I was able to flash the CM5.



Bottom line
Flashing the CM5 is not difficult once you know the correct procedure, but there is one important pitfall. The version of rpiboot available through apt on my Raspberry Pi 400 was too old to work with the CM5. Installing the latest version from the Raspberry Pi usbboot GitHub repository solved the problem, and the CM5 eMMC was then successfully detected as a USB mass-storage device and could be flashed with Raspberry Pi Imager.
In short: fit the jumper on J2, connect the CM5 to the host via USB, use the latest rpiboot, and then flash the eMMC with Raspberry Pi Imager.