Making Devuan 2.0 Work On The Odroid XU4

I’m posting this from a clean, new, install of Devuan 2.0 onto a uSD card with no dependence on a prior installation. I do use any pre-existing system with ‘gparted’, the graphical partition editor, available and with “dd” available.

The big “issue” is just that the images supplied by Devuan expect to be install on an mmc memory card, NOT on a uSD card. In prior attempts, I floundered on not knowing that. (A notice to that effect on the Devuan download page would have been helpful…)

Essentially, you need to make a uSD card that has the right, signed, bootloader in the first 512 bytes, AND that has the “right” /boot contents AND that has /etc/fstab adjusted accordingly AND that has /etc/network/interfaces “adjusted” AND that has had boot.ini properly fixed. Line up all those Just Right, and you can make it go. Miss it (or not know you need to futz with it…) and it doesn’t go.

OK, you start with installing either an Armbian or an Ubuntu image onto a uSD card. These use different file system layouts and different /boot contents so directions for one do not match the other. Ubuntu uses a FAT /boot partition (and is likely closer to what Devuan 2.0 image expects) while Armbian has it all in a big ext4 / partition. I used Armbian as my starting point since FAT doesn’t handle things like symbolic links AND screws up dates. Microsoft, just say no…

So right out the gate, you need a system image with a proper bootloader segment and a /boot that works (including a kernel image, etc.). I got mime from Armbian:

I used a Debian download of “Buster”, since Devuan is based on Debian so that’s likely the closest you can get. Ideally, you would check the kernel level used by the Devuan port and match that in an Armbian port, but for minor numbers it usually doesn’t matter.

Install that to a uSD card. (yes, uncompress it first… unxz IIRC. Then dd if=FOO of=Be/Very/Carefull). This gives a uSD image that will work. It also has some start-up tasks to do… so boot your XU4 using that uSD card. This will expand the file system, ask for password changes, and a bit more. While likely not necessary, I logged in as root (passwd default is 1234 IIRC) and did an “apt-get update” and “apt-get upgrade”. This gets you the latest firmware and kernel images too.

At this point there are several ways to do the next step. You need to save the /boot contents of this image as the boot sectors expect just that stuff. I chose to put the uSD card into a USB adapter, launch gparted, shrink the (now just expanded…) system partition to make a few hundred kB of free space. Then made an ext3 file system on that space. This is where the /boot contents are to be saved. So, using gparted, I shrank the systems partition enough to make an added partition to copy /boot contents into and save them.

The new Devuan chip file layout showing the /boot save area.

The new Devuan chip file layout showing the /boot save area.

At this point, mount the chip (I use /SD/Devuan2 as mount point) and copy /SD/Devuan2/boot into the new file system area that I mounted as /SD/NewBoot.

Then unmount the boot save area.

Now you want to nuke that whole Armbian copy area. I did this via the simple expedient of making a new ext4 file system on that partition in gparted.

Re-mount that /SD/Devuan2 partition.

Take your (un-compressed) tar ball image of Devuan 2.0 and extract it into that uSD partition. (tar xvf FOO …) I had the partition mounted as /SD/Devuan2. So now move /SD/Devuan2/boot to /SD/Devuan2/OLDboot (or whatever… you don’t really need this at all, but it’s an easy way to set it side. IFF you try “rm -rf” realize that there are symbolic links to other parts of the operating system in /boot and you WILL be removing things outside that partition… (Don’t Ask! Really. Just don’t….) )

Now you make a new /SD/Devuan2/boot directory (check premissions and owner match), and copy the contents of the saved /SD/NewBoot (that I mounted as /SD/NewBoot IIRC or something like that) back into /SD/Devuan2/boot. (it is critically important to keep clear /boot that you booted our working system using, /SD/Devuan2/boot (or whatever mount point you used) where you will put your new working copy, and /SD/NewBoot (or wherever you mounted the saved stuff…) You DO NOT want to accidentally blow away your active working /boot when trying to move /SD/NewBoot stuff into /SD/Devuan2/boot…

I use tar to do that move. Why? Because “cp -r” can change time stamps or potentially follow symbolic links and more and, frankly, while you CAN sort out all the cp flags, I just know tar really well. So I do a (cd /foo; tar cf – .) | (cd /bar; tar xvf -) which says “Change to directory /foo, and make a tar format stream of bytes that start in the current working directory “.” putting them into a pipe “-” that goes to the next () command… which changes to the new directory /bar and extracts it verbosely “xv” from the pipe into that file system. Be aware that if /bar is bogus, you will NOT do the ‘cd’ and you will extract into wherever you are and that can be catastrophic if you are sitting in /foo at that time. (Again, don’t ask… far too many don’t asks…)

At this point, you ought to have the bootloader segments from Armbian in the first 512 bytes of the uSD card, some more stuff after that and at about the end of the 4 GB point, a / file system that is almost all Devuan 2.0, but with the Armbian /boot stuff in your /boot.

BUT you are not done.

This will not boot. Why? Because the “UUID” (universal unit ID) of the uSD is what was in the Armbian install, but reformat of the file system changed that. So you need to do a “file -s /dev/uSD1” and find out what it is, or just use the LABEL that you put on it in gparted. This goes into the new boot.ini file. So I changed the line from setenv rootdev “UUID=xxxx” to:

setenv rootdev “LABEL=SD_Devuan2”

Now booting will find the new Devuan partition and boot the kerneal it finds in that /boot.

Yes, you have a working bootable system, but it is broken in a couple of subtle ways. First off, you have a wrong /etc/fstab that says /boot is on a FAT file system when it isn’t. You need to comment out that line. The /etc/network/interfaces file expects eth0 to work (since Armbian passes the “net.ifnames=0” parameter) but you will have some enx{your MAC number) so that needs to be put in the /etc/network/interfaces file.

Once booted into the new system, the “ip a” command will give you the interface name:

chiefio@devuan:~$ ip a
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet scope host lo
       valid_lft forever preferred_lft forever
3: enx001e0251aa27:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:1e:06:31:aa:27 brd ff:ff:ff:ff:ff:ff
    inet brd scope global enx001e0631aa27
       valid_lft forever preferred_lft forever

That “enx001e0251aa27” (or whatever it will be in your system) needs to be put in /etc/network/interfaces,.

chiefio@devuan:~$ cat /etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
# source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto enx001e0251aa27
iface enx001e0251aa27 inet dhcp

# auto eth0
# iface eth0 inet static
#	address
#	netmask

# allow-hotplug wlan0
# iface wlan0 inet dhcp
#	wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

# allow-hotplug wlan1
# iface wlan1 inet dhcp
#	wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

That makes networking work.

Now you can boot, and have a working network. But boot will fail on a broken fsck as long as the /boot is in /etc/fstab as on FAT.

chiefio@devuan:/boot$ cat /etc/fstab
## bootfs
#/dev/mmcblk0p1    /boot         vfat   defaults                  0    1

Note this says /boot is on mmcblk0 that would be the mmc card. All the real stuff is on mmcblk1 that is the uSD card… So I put a “#” in front of it to just comment it out. The boot process mounts /dev/mmcblk1p1 as root / anyway so you need not specify it:

chiefio@devuan:/boot$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev              952428       0    952428   0% /dev
tmpfs             204384     504    203880   1% /run
/dev/mmcblk1p1   7159288 3798076   2977828  57% /

I’m pretty sure that’s everything I did. If anyone gets stuck, just poke me and maybe I’ll remember some other bit / have advice ;-)

Subscribe to feed

About E.M.Smith

A technical managerial sort interested in things from Stonehenge to computer science. My present "hot buttons' are the mythology of Climate Change and ancient metrology; but things change...
This entry was posted in Uncategorized. Bookmark the permalink.

6 Responses to Making Devuan 2.0 Work On The Odroid XU4

  1. Sandy McClintock says:

    Phenomenal intestinal fortitude
    Give yourself a pat on the back. ;)

  2. E.M.Smith says:


    It’s just what Systems Programmers do every single day. But yeah, after a year of on-and-off whacking on this, I’m really glad I found the magic cookie

    It is like a combination lock. Any one thing out of place, you are screwed. Line up everything Just So, and it works. So you just keep whacking at it until you find out all the things that are “just so” and it works.

    I’ve regularly told folks: “There’s nothing I do that special. I have ONE special thing I do. I don’t give up. If it takes a week, a month, a year, or several years: You just keep whacking at it.”. That’s really true. You KNOW there is some combination that works, so just keep trying until you find it.

    What I’ve seeen so many times is one hour into it, someone says “I can’t do this” and quits. All it would take is keeping at it for a day, or a week, or a month… and they could do it.

    “Never give up. Never surrender!!”

    (to quote Galaxy Quest ;-)

  3. E.M.Smith says:

    Now comes the long process of finding little things that need fixing or configuring or are just different and you want to “put it baaack….”

    Plugging in a USB stick gives a ~”can’t do it not authorized” nag. Answer was here:

    CD to here:

    cd /usr/share/polkit-1/actions

    edit this:

    vi org.freedesktop.udisks2.policy 

    And in the first big block headed by:

       <action id="org.freedesktop.udisks2.filesystem-mount">

    Change this:


    To This:


    Then it does the automount prompt / dialogue box.

  4. E.M.Smith says:

    mounting ntfs type microsoft files doesn’t work. Look like I don’t have the loadable kernel modules in place. This is an example of one of those “kernel level” issues.

    root@devuan2:/# mount /SG2/ms
    modprobe: ERROR: ../libkmod/libkmod.c:586 kmod_search_moddep() could not open moddep file '/lib/modules/4.14.200-odroidxu4/modules.dep.bin'
    modprobe: FATAL: Module fuse not found in directory /lib/modules/4.14.200-odroidxu4
    ntfs-3g-mount: fuse device is missing, try 'modprobe fuse' as root
    root@devuan2:/# modprobe fuse
    modprobe: ERROR: ../libkmod/libkmod.c:586 kmod_search_moddep() could not open moddep file '/lib/modules/4.14.200-odroidxu4/modules.dep.bin'
    modprobe: FATAL: Module fuse not found in directory /lib/modules/4.14.200-odroidxu4
    root@devuan2:/# ls /lib/modules

    It is looking for the ntfs module so the kernel can read those files, but it is the upgraded “200” kernel so looks in 4.14.200 while I have modules for the older minor number “48” (both are 4.14 major release number kernels). So I need to find where I have a set of 4.14.200 modules and add them all; or worse case stick a module from the 4.14.48 directory into the 4.14.200 directory and hope they didn’t make any changes to that module / interface between those two minor kernel release levels.

    I don’t remember copying over the /lib/modules and /lib/headers from the Armbian original install so I’ll likely need to put that back on some uSD card, expand it, apt-get update; apt-get upgrade (again…) and then suck out those bits that I forgot. Odd, since I remembered to do it on the first Devuan 2.0 I got running on my multi-system uSD card. (But that one doesn’t have the newest kernel so won’t be .200 IIRC). You would think I’d have remembered ;-)

    It is likely also why my cifs files are not mounting (shared from the Netgear router / USB stick). I do have working NFS after doing the “apt-get install nfs-kernel-server ” putting an entry in /etc/exports, then doing “service nfs-kernel-server restart”.

    root@devuan2:/# mount /Netgear/ext
    mount error: cifs filesystem not supported by the system
    mount error(19): No such device
    Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)
    root@devuan2:/# mount /Shared/ext
    root@devuan2:/# df
    Filesystem                   1K-blocks     Used  Available Use% Mounted on
    [...]   10380544  1759872    8093440  18% /Shared/ext

    Which is another old USB stick I’ve got stuck in the RPi M2 that’s the PiHole / DNS. It also provides a shared file scratch space where I can keep commonly needed config copies, tools, etc. and swap bits of data easily between various machines. It’s a nice way to put those old cheap USB sticks you have laying around to some kind of good use ;-)

    NFS not being a module but being built into the kernel.

  5. E.M.Smith says:

    Yup, mounted the Armbian image as a disk and looked in it. Not 200. So the apt-get update / upgrade will be needed to get the 200 modules.

    root@devuan2:/Arc/ext/UnpackWIP/XU4# mntdd Armbian_20.08.1_Odroidxu4_buster_legacy_4.14.195.img 
    Disk Armbian_20.08.1_Odroidxu4_buster_legacy_4.14.195.img: 1.2 GiB, 1233125376 bytes, 2408448 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0xa15ea617
    Device                                                Boot Start     End Sectors  Size Id Type
    Armbian_20.08.1_Odroidxu4_buster_legacy_4.14.195.img1       8192 2408447 2400256  1.1G 83 Linux
    Look at the start point. Use that in a command to mount
    the disk partition such as:
    mount -o loop,offset=0 dd_disk.img /mnt/dd_image
    mntdd2 blocksize offset image mountpoint defaults to /mnt
    root@devuan2:/Arc/ext/UnpackWIP/XU4# mntdd2 512 8192 Armbian_20.08.1_Odroidxu4_buster_legacy_4.14.195.img /SD/temp
    first do a mntdd to get the block size and count, then
    call this command with them as $1 and $2
    disk image is $3 and mount point $4
    Ready?: (Ctl-C to exit) 
    root@devuan2:/Arc/ext/UnpackWIP/XU4# df
    Filesystem                   1K-blocks       Used  Available Use% Mounted on
    /dev/loop0                     1148472     974348      97736  91% /SD/temp
    root@devuan2:/Arc/ext/UnpackWIP/XU4# ls /SD/temp/lib/modules

    Now almost certainly the 4.14.195 modules would be close enough. But, it’s only a few minutes to spin the image onto a uSD card, boot, update / upgrade, and get the .200 modules.

  6. E.M.Smith says:

    OK, to get cifs to work I needed to do:

    apt-get install cifs-utils

    so now my Netgear USB stick mounts (as the Netgear only shares on CIFS thinking the whole world is Micro$oft…)

    // 7224824 514340 6710484 8% /Netgear/ext

    Yes, I go out of my way to have both CIFS and NFS file sharing up and running… No, I don’t need either of them ;-)

    Oh, and I shut off IPv6 networking as I don’t run it on my network and it just causes problems on an almost 100% IPv4 network behind a NATing firewall, so:

    root@XU4devuan2:/usr/share/polkit-1/actions# ifconfig
    enx001e0631aa27: flags=4163  mtu 1500
            inet  netmask  broadcast
            inet6 fe80::21e:6ff:fe31:aa27  prefixlen 64  scopeid 0x20

    had that inet6 line go away via editing /etc/sysctl.conf:

    root@XU4devuan2:/etc# vi sysctl.conf

    Sticking in: net.ipv6.conf.all.disable_ipv6 = 1
    just about anywhere. I did it in the top few lines…
    and then doing:

    root@XU4devuan2:/etc# sysctl -p
    net.ipv6.conf.all.disable_ipv6 = 1

    So now I’m no longer spewing ipV6 packets into a network that doesn’t use them.

Comments are closed.