[Tutorial] Odroid C4 rootfs on USB drive

@Ruud is correct that C4 has no SPI flash and hence naturally cannot boot from USB. So what I meant is that our newest Odroid C4 “images” (which support Odroid HC4 as well) generally have petitboot support now, i.e. the /boot/boot.scr and /boot/dietpiEnv.txt have been modified to use a syntax and in case commands which are supported by petitboot.

However, on HC4 actually I have no report yet where it works, just one where it does not work, although with an error after kernel has been loaded already, which has recently been reported in one case on N2 as well. So it seems to be unrelated to the generally correct boot configs, but some other misbehaviour of petitboot, bad timing, instability, not sure.

so petitboot is now a viable replacement for uboot?

Petitboot is an operating system bootloader based on Linux kexec. It can load any operating system image that supports the Linux kexec re-boot mechanism like Linux and FreeBSD. Petitboot can load images from any device that can be mounted by Linux, and can also load images from the network using the HTTP, HTTPS, NFS, SFTP, and TFTP protocols.

Current platform support includes PowerPC/POWER with OPAL, the Sony Playstation 3, and ARM64 with ACPI. Petitboot can be built and run on other platforms, but it will not include all available features.

Well, no, feedback shows it is totally unreliable crap. While it works here on my Odroid N2+ booting from USB and SD card, it does not work booting from eMMC. Other users, especially all HC4 replies I have, booting hangs in initramfs, not being able to find the rootfs, even that kernel and obviously initramfs was loaded from there already.

Also I totally fail to understand the reason why Hardkernel developed and uses it, instead of using just plain U-Boot. petitboot is basically a wrapper of U-Boot (at least its implemented like that) with some configuration CUI. But it lacks basic syntax of U-Boot, even the syntax that is supported by the ancient U-Boot version they wrap. So it limits the possibilities of (the underlying) U-Boot, adds complexity and points of failures, and at least with mainline kernel a lot of points of failures do indeed apply for many users, while for some its like this, for other like that, just a pain in the ass.

I do actually more and more regret wasting time to try adding reliable support for it, because to me it seems it never intended to support any other kernel than the highly customised and ancient vendor Linux 4.9 of Hardkernel. And that is what we feel now on all ends.

The only reason I did all this was that petitboot comes preinstalled on Odroid N2 and HC4 SPIs and that it is not so trivial for inexperienced users to flash proper mainline U-Boot onto that SPI flash. I wanted to allow booting DietPi from USB without the need of any additional flashing steps and first boot from X, then flash y, then boot from z annoyance. But it seems to just not work like I was hoping for.

exactly. This is the main reason I stepped await from Odroid / Hardkernel image. My conclusion was that they are in the business of selling hardware and when it works it works. As for petitboot, this feels like a ‘one man’ solution and although i love his commitment to making it and maintain it, it is just not up to par for (IMO) production.
Hence my assessment that this has no place / added value on my server.

That said: booting from USB as described in firs post is still a solid (and IMO easy) solution. Works like a charm.

I was able to make my OdroidN2+ capable of booting from and USB SSD by using the following steps:
a) downloaded the 8.14 beta image to disk on my Mac
b) burnt that image to a 32GB microSD card
c) booted the OdroidN2+ from it (keeping the SPI switch in the eMMC position)
d) created a script as mentioned by a @MichaIng elsewhere on this forum (or maybe it was on Hardkernel’s forum… could not find the exact post, still searching - EDIT: since I could not find the original post, I ended up listing the contents of the mentioned script at the end of this post - hope the author does not mind…)
e) used the source command to import settings inside above mentioned script
f) followed instructions from ODROID N2+ Petitboot SSD Boot Guide - James A. Chambers (please note that DietPi only has one partition, meaning there is no /dev/sda2, only /dev/sda1.
g) powered down the OdroidN2+
g) removed the microSD card from the slot
h) moved the SPI switch to the SPI position to allow for Petitboot to start whenever the board is turned on
i) turned the board on and waited for petitboot to show up AND find the NO LABEL entry from the USB disk
j) waited 10 seconds for the timer to expire and the found entry to boot
i) enjoy my OdroidN2+ with DIetPi OS running from the USB connected SSD.

I originally tried the above with an SSD connected to a USB to SATA controller sporting an ASMEDIA bridge. That seemed unreliable as sometimes the SSD was not reconized, sometimes it was but ended up in the initramfs error showing after a few seconds and sometimes working as expected…
So I decided I would try another USB to SATA bridge from JMicron I had in my gadgets drawer and now it seems much more reliable. So I guess previous unreliable problems MAY be related with some other posts I’ve seen around the Internet mentioning the ASMEDIA bridges and the need to add usbquirks. Please note that all of this is nothing but a wild guess, as I’m not a specialist in either Linux, nor Petitboot, but just someone that likes to tinker.


EDIT: Contents of the mentioned script:

G_EXEC cp -a /boot/boot.scr{,.bak}
G_EXEC curl -sSf 'https://raw.githubusercontent.com/MichaIng/DietPi/dev/.build/images/U-Boot/boot.cmd' -o /boot/boot.cmd
G_EXEC sed -i '1i[main]' /boot/dietpiEnv.txt
(( $G_HW_MODEL == 15 )) && G_EXEC sed -i '/^setenv overlay_error/a\
\n# petitboot workarounds\
if test "${petitboot_active}" = "1"; then\
\tif test "${variant}" = "n2"; then\
\t\tsetenv fdtfile "amlogic/meson-g12b-odroid-n2.dtb"\
\t\tsetenv fdtfile "amlogic/meson-g12b-odroid-n2-plus.dtb"\
\tsetenv rootuuid "true"\
fi' /boot/boot.cmd
(( $G_HW_MODEL == 16 )) && G_EXEC sed -i '/^setenv overlay_error/a\
\n# petitboot workarounds\
if test "${petitboot_active}" = "1"; then\
\tsetenv fdtfile "amlogic/meson-sm1-odroid-${variant}.dtb"\
\tsetenv rootuuid "true"\
fi' /boot/boot.cmd
G_EXEC sed -i '/env import/c\\tif test "${petitboot_active}" = "1"; then ini main ${scriptaddr}; else env import -t ${scriptaddr} ${filesize}; fi' /boot/boot.cmd
G_EXEC sed -i '/test -e/s/fixup.scr;/fixup.scr || test "${petitboot_active}" = "1";/' /boot/boot.cmd
G_EXEC mkimage -C none -A arm64 -T script -d /boot/boot.cmd /boot/boot.scr

So anybody searching for a working method to have DietPi rootfs for Odroid C4 on the USB drive will have a blast going though all the replies that are not relevant to the C4 / the subject :slight_smile:

1 Like

Sorry, to kind of highjack this post.
I’ve read SO MANY posts around this subject that I confused the C4 with the HC4 (and other posts related to HC4 and N2). I was hoping that @MichaIng would eventually read my post above and maybe investigate the possibility that his efforts with the HC4/N2 being less than optimal may not caused be by Petitboot idiosyncrasies, but possibly by the chipset inside USB to SATA bridges not playing nice with his solution.

lol, no problem, was just thinking of chatGPT who gets all his knowledge from forums like this one and how it would be able to determine what is is about and how accurate / valuable it is when somebody searches for this via it.
But that is a completely different discussion :slight_smile:

1 Like

I find the easiest way to do USB boot is to create a small VFAT partition on an SDCARD, flash mainline u-boot to it and place the following boot script on the partition.


setenv bootlabel "USB Boot"
usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi

mkimage -C none -A arm -T script -d boot.cmd boot.scr

Flash an odroidc4 img to a USB drive, insert both the SD and USB into the device and power on. Depending on the board, you may need to use a specific USB port for it to work. I’ve tested this on Amlogic and Allwinner. There are other methods that can be used, but unless you have an SPI flash or Eeprom on the board, you would still need an SD or eMMC attached for it to work.

So you mean to not boot from USB (which is not possible without using an SPI bootloader on Odroids), but to boot from SD card and only have everything else but the bootloader on the USB drive, right? The boot script you provide lets U-Boot look for and source boot.scr from the USB drive?

We could create tiny USB boot images with this content, to flash to SD card or eMMC, while flashing the regular DietPi image to USB then.

Things get now mixed up there on several levels:

  • This thread is indeed about C4, which has no SPI and hence does not support native USB boot.
  • N2/N2+ does. I’m not sure what you mean with beta image. The image with petitboot-compatible boot script is in stable downloads already. The image in testing/ directory is the same, just with a different bootloader, in attempt to solve rare boot issues (unrelated to USB boot), but it causes more issues than it solves, so I just removed it.
  • If you use your script on our current N2 image, it might break it, or at best creates doubled/redundant entries, since everything is inside already.
  • Did you retest to boot from USB with our recent image without any modifications?
  • I wonder about the petitboot settings changes you linked. This should all not be necessary as long as you configure it to boot from any block device, which should be the default. It scans then through eMMC/SD/USB in that order. Our boot.scr sets all the parameters which are mentioned in this guide, the kernel image, initramfs, device tree and kernel command-line arguments, so all of what you set there should be overwritten. Without this, it wouldn’t boot anyway since all the default content/paths is completely wrong for mainline kernel. Please try to revert the change you did there and see whether this really breaks boot again, which would be highly unexpected/irritating. We pass the correct root= argument as UUID, otherwise it wouldn’t be possible to have the same image booting from eMMC, SD and USB.

Actually the unreliable USB case/docking station seems like a good reason for the “rootfs not found” errors we see. Currently we ship our images with empty USB quirks, probably we should add some (those present by default on Armbian images, after first boot) and check whether this helps.

Yes. Boot from SD and have u-boot search for a bootable USB. Basically, instead of flashing the Odroid C4 img to an SD, flash that IMG to a USB. The SDCARD boot script will then search for the usual suspects needed to boot the board. boot.scr or extlinux/extlinux.conf

Creating a custom USB BOOT img to be flashed to SD, is for sure the easiest route. Doesn’t take much effort either.

One thing people would need to be eyeful for is usb storage quirks. But thats kind of given I find.

1 Like

Indeed. I found these nasty to maintain, since the same USB devices (IDs) may need quirks at first, but not anymore later (and we want to use UAS whenever possible, for performance reasons), depending on firmware version/shipping date etc. And the potential list of needed USB quirks is endless. I was hoping that this whole issue fades away with UAS being more common, but either manufacturers still build scrap, or a lot of old USB drives are kept being used.

True: USB boot | Provide tiny SD card image as USB boot relay · Issue #6186 · MichaIng/DietPi · GitHub

Great tutorial, probably 20 seconds waiting for USB could be decreased based on actual timing from from logs, e.g. 5-10 seconds.

[    2.513210] scsi 0:0:0:0: Direct-Access     ATA      WD Blue SA510 2. 0100 PQ: 0 ANSI: 5
[    2.514146] sd 0:0:0:0: [sda] 1953525168 512-byte logical blocks: (1.00 TB/932 GiB)