[Tutorial] Odroid C4 rootfs on USB drive [deprecated as of kernel 6.6]

WARNING: as of kernel 6.6 there are issues that invalidate this tutorial. Changes in that kernel prevent the rootfs from being served of the usb drive.

When using a board like the Odroid C4 as a (production) server, you want to limit the usage of the sdcard as much as possible. There are (for me) two reasons for that:

  • sdcards have limited read / write cycles: so especially on a server that runs 24/7 the sdcard will quickly wear down and fail.
  • performance of sdcards is (very) low: when running a server, disk speed is important. sdcards will slow down your whole system.

As the Odroid C4 requires an sdcard (or eMMC) to boot from (it lacks build in SPI flash memory that you can use to boot from), you still need the sdcard for booting (which is okay as this is a one time event and not a continues read / write event). But you want the rootfs NOT on the sdcard, you want that to come from a USB drive (as the Odroid C4 doesn’t have SATA ports and only USB ports).
There are several guides on the internet describing how to achieve this, but not all of them are working (obsolete) or are not working with DietPi (as DietPi made the decision to ‘abandon’ the separate boot and rootfs partition, and not only has one partition: the rootfs partition)

This guide will help you in running you Odroid C4 with DietPi from a USB drive.

pre-requisites

  • (ext4) formatted usb drive.
  • rsync installed.
  • some basic linux sysadmin knowledge between chair and keyboard.

Install Odroid C4 with DietPi following the DietPi instructions until you have a configured and running setup that you can log into using ssh.

Instructions

  1. ssh into your Odroid as root user
  2. insert the usb drive
  3. get the UUIDs for the attached disks (both USB drive and sdcard):
    lsblk -f
  4. mount the usb drive (assuming it is sda1, otherwise replace with correct one):
    mkdir -p /mnt/usb
    mount /dev/sda1 /mnt/usb
  5. copy the entire sdcard contents into the usb drive:
    rsync -axv / /mnt/usb/
  6. empty the boot directory on the USB drive (!), and create (future) sdcard mount directory:
    rm /mnt/usb/boot -rf
    mkdir -p /mnt/usb/sdcard
    ln -s /mnt/sdcard/boot /mnt/usb/boot
  7. edit fstab (on USB drive!) to load the correct mountpoints after booting from the USB drive:
    nano /mnt/usb/etc/fstab
    > under section ‘# PHYSICAL DRIVES …’ replace the entry for the / mount point and add the /mnt/sdcard mount point
    UUID=[... your usb drive UUID ...] / ext4 noatime,lazytime,rw 0 1
    UUID=[... your sdcard UUID ...] /mnt/sdcard ext4 noatime,lazytime,rw,nofail,noauto,x-systemd.automount
  8. edit the dietpiExt.txt:
    nano /boot/dietpiEnv.txt
    > change the entry for rootdev to hold the UUID for your USB drive
    rootdev=UUID=[... your usb drive UUID ...]
    > add rootdelay=30 to the variable extraargs
    extraargs=rootdelay=30 net.ifnames=0
  9. reboot your device and keep fingers crossed:
    reboot now

What have we just done?
So we still need the sdcard for initiating the bootprocess, for that we require the /boot directory.
Upon boot we set the root directory to the USB drive (and by doing that we ‘overwrite’ the boot directory with the (empty) one on the USB drive), we work around this by using a bind mount point: the /boot directory on the USB drive (which we made empty) is mounted from the /boot directory of the sdcard.
This way, we only have one /boot directory: the one on the sdcard. Every change made by scripts / installs / configurations etc. made on the /boot directory will be available on actual boot as the /boot directory after booting is actually the /boot directory on the sdcard.
Because USB drives take time to initialize we need to tell the kernel that before it loads, it should wait (e.g.) 10 seconds before trying to load the rootfs. This should be enough time for the USB drive to ‘spin up’.
As we do not want to change (and compile) the /boot/boot.cmd file to add the rootdelay=10 parameter, we use the DietPi built-in dietpiEnv.txt to add the bootdelay as extra argument passed to the kerel startup parameters. By doing it this way we make sure that we never get into trouble when for some reason an upgrade changes the boot.cmd (and clears out your changes). That said, assuming that the dietpiEnv.txt will never change / overwrite on upgrades.

So there you have it: Odroid C4 booting from your sdcard and faster then ever running from your USB drive.

Feel free to comment and / or share your experiences with this instruction!

6 Likes

20230122:

  • changed bind mount method to more common symlinking of the boot directory
  • changed extraargs variable as this is already set so adding it overwrote it’s initial set value
  • changed the rootdelay value to 30 seconds, as I was seeing that the spin-up of the USB drive was not constant and in some cases 10 seconds was not enough. As this delays the boot only, 30 seconds for me is acceptable (being a server), when using it for another setup feel free to find the optimal value for your setup

20230224:
Still working correct and no adjustments made after 20230122

For anybody stumbling on this tutorial: never mind all the replies below as these are not relevant / related to the tutorial. They do add however some good background info if you can filter that out.

I am able to boot from USB drive on Odroid C4 following your instructions,
Only thing is after booting from USB all the dietpi utilities are lost.
Not able to run dietpi-config or dietpi-software.

@Pratham23
can you share ls -la /boot/dietpi

If you have a working petitboot SD in your C4 then just:

DL the 2023/02/04 DietPi C4 image and write it to your drive (mine is ssd 120g mounted in a usb-3 enclosure).

Plug it in to your C4 and boot and select it and finish the OS install.

Nice and easy now!

I dont get any sound with XFCE and dmsg show panfrost errors…

Same with me, No sound with any of the desktops on C4.

How do you get petitboot working on C4. I dont have emmc only sd card support so far not able to get petitboot successfully working on C4

Once I had petitboot running I did the netboot install of debian 11. No sound. I tried deb 12 and had some issues. Went back to 11 and after a few months, a new kernel came out and sound started working!! The desktop still has some glitches where the screen will go black but you can click on stuff and it will refresh properly. Running firefox and watching youtube and browsing is good. I run kodi and a chrome app for tubi as there is no arm support for the video decryption on any browsers :frowning:

See Multi boot and USB booting with ODROID-C4 - ODROID for tips on getting petitboot running. Mostly just write the image to an sd, insert it and go. See “Part #4”. Im running 20220315. I went to http://ppa.linuxfactory.or.kr/images/petitboot/odroidc4/ to see if there is a newer version but its down/gone? Read through the entire thread and you may find another site where its hosted. Or search the odroid forums for it. I can provide it. Tobetter is still active on the site.

Did this to mine
Move the Raspberry PI root file system to a USB drive - PragmaticLinux
the rpi root filesystem is the same as DietPi and Debian and all flavors thereof

Works…

Also look into zram-tools and log2ram to lower writes to the SD/USB cards and stuff

@WarHawk actually it won’t as the guide you linked to is obsolete and although it holds some good background information is deprecated.
The assumption in this guide is that there are 2 partitions: a boot partition (that stays on the sdcard) and the rootfs partition that you can move to the usb disk. But this is not the case anymore hence the need for a new instruction :slight_smile:

it was decided sometime ago to only have 1 partition that holds both the boot and root files. This means that the instruction you linked to doesn’t work anymore.

Yes, depends on SBC used. on Raspberry Pi, it’s 2 partitions. On modern NanoPi R5/6 it’s 8. On systems running Armbian we have a single one.

Anyway latest C4 image should support USB boot ootb No boot partition on new Odroid HC4 image - #10 by MichaIng

1 Like

I left the /boot on the SD card, the rootfs (/) on the USB or the SSD…this way on boards that do not have an EEPROM that can be flashed to tell the SBC to boot from another device (such as the USB or SD)

Never understood why they did that…if the partition get’s corrupted it screws up the boot…if it had 2, it would be easier to scan/fix the fat32 partition that contained the kernel and boot parameters…and make it much easier to move the root partition to a faster device

@Joulinar but that is for the HC4 and not the C4, there is a difference in these two. I think (not sure) that the HC4 has a SPI where the C4 doesn’t have that.
Although you could get it to work with petitboot, but that is not as clean as the instruction here imo as that requires an external ‘tool’ (petitboot), so adds maintenance / secutiry / etc.

Only benefit for petitboot I see is if i needed multiple images to boot from, but for me I only need armbian/dietpi so petitboot makes the setup to ‘complex’ and adds no value

or I am missing something that it does add for my use case

@Ruud
this is the statement of @MichaIng

Btw, our recent Odroid C4 image supports petitboot, so no need to erase or reflash the SPI, and it can boot directly from USB that way.

As far as i can see, the boot partition is ‘static’ with the exception of the dietpi scripts residing there.
So only writes to the sdcard on updates and on some dietpi scripts writing their (temp) state to a file (which could be on the boot directory: never looked into this).

So the when the sdcard ‘crashes’ it is as simple as restoring an image of the crashed on onto a new one.
Only thing to remember here is to create a backup of the /boot periodically (which should always be done)

Yes, i know, and as said that ‘requires’ petitboot which I do see use cases for but I do not see any added value for my specific use case (I have no use for a bootmanager as I only have one image to boot from).
So the instruction provided here is IMO the easiest and cleanest one without having to find out how to install and maintain petitboot :slight_smile:

but as said, maybe i am missing something :slight_smile:

@Ruud it would be possible to make this on HC4, erasing petitboot before doing it?

Hi, theoretically it should :slight_smile:

I checked back today on that URL and its up and the 20220315 appears to be the latest for C4. If you need one for HC4 then its there under the HC4 folder(go to parent dir) and the latest is 20221228 :slight_smile:

What a waste of time … Use stock Armbian, run armbian-install, wait few moments and you are done.