Zynthian on Compute Module 4 + nvme drive boot: it works!

A bit tricky, but that’s really cool !
I had to switch to kernel 5.10 using rpi-update as it seems that 4.19 kernel doesn’t have the needed module for handling nvme drives. For now I didn’t experienced any issue with that, but I didn’t test it extensively too …!



Excellent! Which video device is that?

Hi Chris.
I can’t find it in the store anymore. Maybe it’s out of stock. I’ve got it (display alone without any accessory) for 32$.
It’s a Noname 7inch 1024x600 display with HDMI input and USB for touch function. Quiet happy with it.

How to do it:
My CM4 has an onboard emmc module, so that’s trickier then with one without emmc. I assume you know how to access remotely to your zynthian and have a basic knowledge of some bash command line tool.

Write Zynthian image to emmc

  1. Disable emmc boot on the cm4-IO board by placing a jumper on the header close to the CM4.
  2. Connect a micro usb to USB cable between the cm4-IO board and your computer.
  3. Power the cm4-IO board. The emmc drive will appear as an external USB drive.
  4. Burn the Zynthain image to that drive using your favorite tool. Mine’s USBimager, wich is lightweight, FOSS, and it runs on Win, Mac, Linux.
  5. Remove the drive (unmount it)
  6. Power off the cm4-IO board
  7. Remove jumper

Setup Zynthian / Update kernel version

  1. plug all your hardware to the cm4-IO board
  2. Power on and wait until the Zynthian setup process finish
  3. Enable USB host:

nano /boot/config.txt

and be sure you have:


  1. Using webconf, setup your hardware. Reboot, you should have hopefully a working Zynthian running from the emmc.
  2. Update kernel to 5.10:


  1. Reboot. Verify: uname -r => 5.10.39-v7l+ You can now access to your nvme drive: use lsblk command to identify it.

nvme drive setup

  1. create with fdisk command a 256Mb partition of type FAT32 and a second one big enough for housing the zynthian root file system (30Gb is ok) of type ext4. Save your changes, then exit fdisk.

mmcblk0 179:0 0 14.6G 0 disk
|-mmcblk0p1 179:1 0 256M 0 part /boot
|-mmcblk0p2 179:2 0 14.3G 0 part /
mmcblk0boot0 179:32 0 4M 1 disk
mmcblk0boot1 179:64 0 4M 1 disk
nvme0n1 259:0 0 238.5G 0 disk
|-nvme0n1p1 259:1 0 256M 0 part
|-nvme0n1p2 259:2 0 238.2G 0 part

  1. Format the partitions:

mkfs -f vfat /dev/nvme0n1p1
mkfs -f ext4 /dev/nvme0n1p2

  1. Create mount points:

mkdir /mnt/boot
mkdir /mnt/root

  1. Mount nvme partitions:

mount /dev/nvme0n1p1 /mnt/boot
mount /dev/nvme0n1p2 /mnt/root

  1. Copy filesystem:

rsync -avx / /mnt/root
rm -r /mnt/root/boot

Customize startup

  1. nvme module has to be loaded on an early stage to mount the root file system, so we use intramfs:

nano /etc/initramfs-tools/modules



at the end of the file.

  1. create initramfs:

update-initramfs -c -k uname -r

Be carefull, they are backticks around uname -r

  1. Update config.txt:

nano /boot/config.txt

add at the end

initramfs initrd.img-5.10.39-v7l+

  1. copy /boot partition on the nvme drive:

rsync -avx /boot /mnt/boot

  1. identify nvme partitions UUID with blkid commad.

/dev/nvme0n1p1: SEC_TYPE=“msdos” UUID=“5E2E-A6ED” TYPE=“vfat” PARTUUID=“da93a86c-01”
/dev/nvme0n1p2: UUID=“8369e8b4-5f56-4285-97a0-d67c93cb52cf” TYPE=“ext4” PARTUUID=“da93a86c-02”
/dev/mmcblk0p1: LABEL_FATBOOT=“boot” LABEL=“boot” UUID=“592B-C92C” TYPE=“vfat” PARTUUID=“2fed7fee-01”
/dev/mmcblk0p2: LABEL=“rootfs” UUID=“706944a6-7d0f-4a45-9f8c-7fb07375e9f7” TYPE=“ext4” PARTUUID=“2fed7fee-02”
/dev/nvme0n1: PTUUID=“da93a86c” PTTYPE=“dos”
/dev/mmcblk0: PTUUID=“2fed7fee” PTTYPE=“dos”

so on my nvme drive, boot partition is da93a86c-01 and root partition is da93a86c-02

  1. Modify kernel command line parameter:

nano /mnt/boot/cmdline.txt

modify the root= argument:


  1. To ensure this modification persist if ever you change your hardware configuration or switch from stable to testing branc or vice versa:
    Create scripts directory

mkdir /mnt/root/var/zynthian/zynthian-my-data/scripts

create post install script:

nano /mnt/root//var/zynthian/zynthian-my-data/scripts/update_zynthian_sys.sh

and add the following:

echo “initramfs initrd.img-5.10.39-v7l+” >> /boot/config.txt
echo “dtoverlay=dwc2,dr_mode=host” >> /boot/config.txt
echo “dwc_otg.lpm_enable=0 console=tty1 root=PARTUUID=da93a86c-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait” > /boot/cmdline.txt

Make it executable

chmod a+x /mnt/root/var/zynthian/zynthian-my-data/scripts/update_zynthian_sys.sh

  1. Modify fstab:

nano /mnt/root/etc/fstab

set the right PARTUUID:

PARTUUID=da93a86c-01 /boot vfat defaults 0 2
PARTUUID=da93a86c-02 / ext4 defaults,noatime 0 1

  1. Umount mount points:

umount /mnt/boot
umount /mnt/root

  1. Power off zynthian

Tell the bootloader to boot on the nvme drive

You will need the usbboot utility (Github link) installed on an another computer.

  1. Once installed you have to told the bootloader to modify the boot order. In usbbot/nvme/boot.conf change:




  1. From usbboot/nvme directory create a new eeprom:


  1. Write eeprom on cm4:
    repeat step 1. 2. 3. go in usbboot directory and run:

./rpiboot -d nvme

  1. repeat step 6. 7. reboot, cross fingers

root@zynthian:~# lsblk
mmcblk0 179:0 0 14.6G 0 disk
|-mmcblk0p1 179:1 0 256M 0 part
|-mmcblk0p2 179:2 0 14.3G 0 part
mmcblk0boot0 179:32 0 4M 1 disk
mmcblk0boot1 179:64 0 4M 1 disk
nvme0n1 259:0 0 238.5G 0 disk
|-nvme0n1p1 259:1 0 256M 0 part /boot
|-nvme0n1p2 259:2 0 238.2G 0 part /

with the help of
RBPI nvme documentation
RBPI forum post


Love to see one of these on a board with audio in/out that you could mount 3 to a 1U :smiley:

@MrBroccoli would say “in an eurorack format” :rofl:

For sure this compute module opens a lot of exciting perspectives. BUT:
I’ve started to look here and there what’s the deal with designing PCBs with high speed differential lines (USB, Gb ethernet, PCIE nvme drive). And, ouch, what an headache: line impedance calculation, line length matching and so on, far beyond my knowledge and skills. At my own ultra slow rhythm, maybe in 10 years :wink:

1 Like

At least the most complex design aspects are taken care of on the compute module.

Finding an open source host PCB design that is close to your design goals, which you might be able to modify, would be a real time saver.
The previous post on First Compute Module Host w HiFi Output
that outputs audio through a hifiberry-dac driver is one example.

This more basic board selling for $130, has a “Customize Board” feature on the sales page, using Upverter.

This guy seems to be monitoring compute module developments in this database.
Jeff Geerling 's blog

You may have seen his Mar. 23 article:
The Raspberry Pi can boot off NVMe SSDs now
(His boot benchmarks show little difference fiom SD card)

Update on this little Compute4 Module sized “Backpack” board with 40 pin gpio:
EU approved, they are offering some copies for early users, (it has a known headphone distortion)

---- A hardly related curiosity ----

I was just looking at the hobby board line at Sparkfun, that includes little MicroMod processor modules using M.2 format connector similar to what NVMe boards use (‘E’ keyed with non standard mount spacing). Not sure when it’s a cost effective approach, perhaps when doing in context benchmark comparison tests for a new product design. (Looks like their connector uses a ‘universal’ GPIO format). Available processors:

They have 7 different special purpose Carrier Boards that accommodate these processor modules. (One enables the RP2040 to output HDMI)
(You can get 5 - M.2 carrier sockets there for $6.95)

Give it a little time . . .

I’m sure the world can wait for my multi synth rendition of chopsticks. . .

quick question… does your config.txt get overwritten when you do a zyn update via web config?

I can’t tell because I’ve done all the system updates when zynthian was running on the emmc.
I’m on testing branch, I can give a try when new commits will be published.

But I’m experiencing a really strange and randomly issue:

that means first try to boot on device 6 (Nvme drive), if it fails, try to boot on device 1 (eemc or sd card for cm4 without emmc).
I can reboot a couple of times and everything goes well, but sometimes it boots on the emmc, where zynthian initial install is still there.

Looking at /boot/config.txt (on nvme drive):

initramfs initrd.img-5.10.39-v7l+

is not there anymore.

Looking at /boot/cmdline.txt (on nvme drive):


has been changed to emmc

:thinking: :thinking: :thinking:

I made a

chmod a-w /boot/cmdline.txt
chmod a-w /boot/config.txt

dirty trick, but hopefully, it will work, let’s see …

the “Tofu” carrier board has a publicly available schematic: https://tofu.oratek.com/_assets//TOFU-schematics.pdf
and the RaspberryPi foudation even provide the Kicad files for the cm4-IO board:

And this is the second part of a YT tut for cm4 carrier board design provided by DigiKey:

Here I realize that it’s not so easy business …

1 Like

I know why ! Each time you change the hardware configuration (I’ve switched a couple of time the audio config to see if they are some troubles with the Behringer UMC204HD USB sound card) this rewrites config.txt and cmdline.txt.

Now let’s try to fix it …

Edit: How to has been updated, thanks @Baggypants & @jofemodo

Try this


Hi @Baggypants , thank you, I was remembering having read this but I couldn’t find it anymore.
At least my hack on steps 22 and 26 work when doing hardware change with webconf but unfortunately it doesn’t survive when switching from stable to testing or vice versa. So I will consider this and update the howto when it will be ready.

1 Like

This works!!! thanks… I have been needing this fix for too long :smiley:

oh, another note…

If you are emmc or net booting or don’t need the sdcard after boot, add this to /boot/config.txt to eliminate the mmc0 errors:


I’ve had a trainee work on that in my company to create a board based on CM3 module, and to be honest, it may be easier than you think. We used Kicad, which has in intergrated tool in the routing to build those impedance matched lines. So without any calculation our board was done and working perfectly. You may try it, based on mentioned projects, and don’t think about it too much to get it working.

1 Like

Indeed kicad really does seem to have this sort of thing in hand… Not that I’m about to set cursor to schematic any time soon.

Yes, I confirm, I’ve updated the how to.