Setup a new Ubuntu or Debian system on the Utilite

This is a guide to setup a recent Ubuntu system on a Utilite ARM computer, to replace the official Ubuntu 12.04 OS.


  • You need to prepare a [kernel with cgroups](/?p=1073 "Building a new Linux kernel for your Utilite Computer") support.
  • An ARM bootable microSD or USB. You can use the official Ubuntu 12.04 [Linux Utilite Image]( "Linux Utilite Image") on the removable device.
  • Backup any data you have on the original system!


  1. Boot from microSD or USB.
  2. Update the system and install debootstrap:

    $ sudo apt-get update
    $ sudo apt-get install debootstrap

  3. Mount the SATA root filesystem on /mnt:
    $ sudo mount /dev/sda2 /mnt
  4. Clear the filesystem:

    Make sure you save any data you need, before doing this!.

    $ sudo rm -fr /mnt/*

Installation of an Ubuntu or Debian base system

  1. Use debootstrap to install the Ubuntu base system:
    $ sudo debootstrap --foreign --arch=armhf trusty /mnt

    You can use vivid instead of trusty if you are feeling adventurous.

    For a Debian system use this command instead:

    $ sudo debootstrap --foreign --arch armhf jessie /mnt

    You can use stretch or sid instead of jessie if you are feeling lucky.

  2. Chroot into the new system:

    $ sudo mount -o bind /dev /mnt/dev
    $ sudo mount -o bind /dev/pts /mnt/dev/pts
    $ sudo mount -t sysfs /sys /mnt/sys
    $ sudo mount -t proc /proc /mnt/proc
    $ sudo cp /proc/mounts /mnt/etc/mtab
    $ sudo chroot /mnt

  3. Second stage debootstrap:

    After you enter the chroot jail, we need to complete the second stage of the base setup:

    # /debootstrap/debootstrap --second-stage

Installing additional packages

  1. Setup the correct timezone:
    # dpkg-reconfigure tzdata
  2. Add repositories in /etc/apt/sources.list.
  • For Ubuntu:

    deb trusty main restricted universe multiverse
    deb trusty-security main restricted universe multiverse
    deb trusty-updates main restricted universe multiverse
    deb trusty-backports main restricted universe multiverse
    deb-src trusty main restricted universe multiverse
    deb-src trusty-security main restricted universe multiverse
    deb-src trusty-updates main restricted universe multiverse
    deb-src trusty-backports main restricted universe multiverse

  • For Debian:
    deb jessie main contrib non-free
    deb jessie-updates main contrib non-free
    deb jessie/updates main contrib non-free
    deb-src jessie main contrib non-free
    deb-src jessie-updates main contrib non-free
    deb-src jessie/updates main contrib non-free
  • Run update after adding the repositories:
    # apt-get update
  1. Install additional software.
  • We need to create a fake /sbin/initctl to prevent apt from breaking:
    # dpkg-divert --local --rename --add /sbin/initctl
    # ln -s /bin/true /sbin/initctl
  • Install the software you need:
    # apt-get -y install language-pack-en ssh isc-dhcp-client net-tools man lsof less
  • Remove the fake /sbin/initctl:
    # rm /sbin/initctl
    # dpkg-divert --local --rename --remove /sbin/initctl
  1. Setup users:
    # passwd root
    # useradd -m -s /bin/bash utilite
    # passwd utilite
    # usermod -a -G adm,cdrom,sudo,dip,plugdev utilite
  2. Setup a kernel:

    Now you need to deploy the [kernel we prepare earlier](/?p=1073#toc-deploy-the-tarball "Building a new Linux kernel for your Utilite Computer") and reboot.

Choose a role for your system

  1. After you reboot you may find that networking is not working. If you are in a dhcp enabled network run dhclient to get an IP address:

    # dhclient

  2. Upgrade the system to the latest upgrades:
    # apt-get update
    # apt-get -y dist-upgrade
  3. Check the available roles
  • On Ubuntu you may want to install tasksel (already installed on Debian):

    # apt-get install tasksel

  • See the available roles on Ubuntu:

    # tasksel --list-tasks
    i server Basic Ubuntu server
    i openssh-server OpenSSH server
    u dns-server DNS server
    u lamp-server LAMP server
    u mail-server Mail server
    u postgresql-server PostgreSQL database
    u print-server Print server
    u samba-server Samba file server
    u tomcat-server Tomcat Java server
    u cloud-image Ubuntu Cloud Image (instance)
    u virt-host Virtual Machine host
    u ubuntustudio-graphics 2D/3D creation and editing suite
    u ubuntustudio-audio Audio recording and editing suite
    u edubuntu-desktop-gnome Edubuntu desktop
    u kubuntu-active Kubuntu Active
    u kubuntu-desktop Kubuntu desktop
    u kubuntu-full Kubuntu full
    u ubuntustudio-font-meta Large selection of font packages
    u lubuntu-desktop Lubuntu Desktop
    u lubuntu-core Lubuntu minimal installation
    u mythbuntu-frontend Mythbuntu frontend
    u mythbuntu-backend-master Mythbuntu master backend
    u mythbuntu-backend-slave Mythbuntu slave backend
    u ubuntustudio-photography Photograph touchup and editing suite
    u ubuntustudio-publishing Publishing applications
    u ubuntu-gnome-desktop Ubuntu GNOME desktop
    u ubuntu-desktop Ubuntu desktop
    u ubuntu-usb Ubuntu desktop USB
    u ubuntustudio-video Video creation and editing suite
    u xubuntu-desktop Xubuntu desktop
    u edubuntu-dvd-live Edubuntu live DVD
    u kubuntu-active-live Kubuntu Active Remix live CD
    u kubuntu-live Kubuntu live CD
    u kubuntu-dvd-live Kubuntu live DVD
    u lubuntu-live Lubuntu live CD
    u ubuntu-gnome-live Ubuntu GNOME live CD
    u ubuntustudio-dvd-live Ubuntu Studio live DVD
    u ubuntu-live Ubuntu live CD
    u ubuntu-usb-live Ubuntu live USB
    u xubuntu-live Xubuntu live CD
    u manual Manual package selection

  • See the available roles on debian:

    $ tasksel --list-tasks
    i desktop   Debian desktop environment
    u gnome-desktop GNOME
    u xfce-desktop  Xfce
    u kde-desktop   KDE
    u cinnamon-desktop  Cinnamon
    u mate-desktop  MATE
    i lxde-desktop  LXDE
    u web-server    web server
    u print-server  print server
    u ssh-server    SSH server
    u laptop    laptop

  1. Choose a role.

    If you would like a Desktop system, I suggest you choose something light like lubuntu-desktop or lxde-desktop.

  • Installing Lubuntu (Ubuntu):

    # tasksel --task-packages lubuntu-desktop | xargs apt-get -y install

    I prefer this method rather than the [TUI]( "Text-based User Interface") of tasksel, so as to have better overview and control of the process. Keep an eye on it every now and then, because it will ask you about keyboard-configuration and other questions. Select the default settings if you are unsure.

  • Installing LXDE Desktop (Debian):

    # apt-get install task-lxde-desktop network-manager

    For Desktop systems it may be a good idea to install network-manager as well.

  • Add the vivante GPU module on startup:

    # echo vivante >> /etc/modules

After you finish you can reboot your system and start playing.



Building a new Linux kernel for your Utilite Computer.

The Utilite computer comes with an aging Ubuntu 12.04. If you try to upgrade it to to 14.04 or later, you will end up with a broken system because of their dependency, either fully or partially, on the systemd init system. The problem is that the stock kernel does not support cgroups which is a mandatory dependency for systemd. Type these commands on your Utilite, to verify the missing feature:

$ sudo mount /dev/sda1 /boot
$ /usr/src/linux-kernel/scripts/extract-ikconfig /boot/uImage-cm-fx6 | grep CGROUPS
# CONFIG_CGROUPS is not set

There is also another important feature: fhandle. A systemd Linux system without an fhandle enabled kernel, will fail to enable the swap space during boot.

Most modern distros, with a few notable exceptions, have switched to this new initialization system. So if we want to use a recent version of Ubuntu, Debian or most other distros, we need to recompile the kernel with cgroups support.


  • A standard x86-based PC with Linux installed (I use Ubuntu 15.04 at present). This is going to be our build station.
  • A Utilite ARM Computer. This is our target.

Prepare the cross-compile toolchain

The necessary packages are available on recent Ubuntu releases and Debian unstable.

First let’s install all necessary and optional packages on our build station:

$ sudo apt-get -y install build-essential gcc-arm-none-eabi gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf libncurses5 libncurses5-dev libncursesw5 libncursesw5-dev lzop git u-boot-tools pkg-config

Download the kernel sources

  1. You can download the sources from here:
    $ wget
  2. Then extract the tarball and change into the kernel source root:
    $ tar xvzf master.tar.gz
    $ cd linux-kernel-3.0-master/

Building the kernel

  1. Prepare the environment:
    $ export ARCH=arm
    $ export CROSS_COMPILE=arm-linux-gnueabihf-
  2. Prepare the configuration for utilite:
    $ make utilite_defconfig
  • Check if cgroups and fhandle are enabled:
    $ grep CGROUPS .config
    # CONFIG_CGROUPS is not set
    $ grep FHANDLE .config
    # CONFIG_FHANDLE is not set
  • Since cgroups and fhandle, are not enabled we need to enter menuconfig to enable it:
    $ make menuconfig

    Navigate to General Setup and go down to Control Group support. Press the space bar and you will see an asterisk ([*]). That means the Control Group support feature is enabled to be compiled in the kernel. Now do the same with the open by fhandle syscalls option. Press exit and Yes to save your new configuration.

  • Make sure cgroups and fhandle are now enabled:

    $ grep CGROUPS .config
    $ grep FHANDLE .config

    Good. Let’s proceed with the build.

  1. Build the kernel and prepare a U-boot compatible image (uImage):

    $ make
    $ make uImage

    This will take some time depending on how powerful your build station is. Go for coffee, watch some movie, read a comic

Prepare the tarball

Now we need to package the kernel and modules together.

  1. Install the modules in the rootfs directory:
    $ mkdir -p rootfs/boot
    $ INSTALL_MOD_PATH=./rootfs make modules_install

    Ignore this error after make modules_install:

    make[1]: *** No rule to make target 'rootfs/lib/firmware/./', needed by 'rootfs/lib/firmware/ti_3410.fw'.  Stop.
    Makefile:1130: recipe for target '_modinst_post' failed
    make: *** [_modinst_post] Error 2
  2. Copy the image and prepare the tarball:
    $ cp arch/arm/boot/uImage rootfs/boot/uImage-cm-fx6
    $ cp arch/arm/boot/zImage rootfs/boot/zImage-cm-fx6
    $ cd rootfs
    $ tar cvzf ../linux-utilite-kernel-3.0.tar.gz .
    $ cd ..

Deploy the tarball

Now we are ready to deploy the kernel to the Utilite computer.

  1. Copy the kernel to the Utilite computer:
    $ scp linux-utilite-kernel-3.0.tar.gz utilite@utilite-desktop:
  2. Now connect to the Utilite and mount the boot partition:
    $ sudo mount /dev/sda1 /boot
  3. Backup the existing files and remove the old image and modules:
    $ tar cvzf linux-utilite-original-kernel.tar.gz /boot/ /lib/modules/3.0.35-cm-fx6-6.3/
    $ sudo rm /boot/uImage-cm-fx6
    $ sudo rm -fr /lib/modules/3.0.35-cm-fx6-6.3

    If something goes wrong you can boot from a microSD or a USB drive and restore the original kernel.

  • Deploy the kernel:

    Make sure the /boot directory is mounted on the /dev/sda1 filesystem before running the following command.

    $ sudo tar xvzf linux-utilite-kernel-3.0.tar.gz -C /
    $ sudo chown -R root:root /lib/modules/3.0.35-cm-fx6-6.4
    $ sudo depmod 3.0.35-cm-fx6-6.4

    The errors caused by tar are produced because FAT filesystem like /dev/sda1, do not support the ownership attribute. You can safely ignore them. chown is used to set the owneship of the modules to the root user, since the tarball was packaged under a normal user account and inherited its permissions.

  • You can now reboot the Utilite and see if everything works as expected. If not, you can boot with a microSD or a USB flash drive and restore the original kernel and modules.

    After we have successfully prepared a cgroups enabled kernel, we can move on to setup a new Ubuntu or Debian system on the Utilite.


    • [1]

    Adding USB boot support on the Utilite nettop

    More than a year or so, I have been the proud owner of a first generation Utilite ARM appliance. But the harsh Cyprus summer, hit it hard and the microSD circuit stop working. I could no longer boot alternative systems on microSD cards. All I was left with, was the stock system with an aging Ubuntu 12.04 ARM port.

    Enter the U-Boot

    Das U-Boot is a boot loader that targets mostly embedded systems. Many ARM appliances, including the Utilite, are using U-Boot to boot their OS.

    I entered the U-Boot environment to do some checks about the mmc issue. To do that just press the ‘any‘ key when you see the following message:

    Hit any key to stop autoboot:

    Then type the following command in your U-boot terminal:

    CM-FX6 # mmc info
    Card did not respond to voltage select!

    That message does not look very healthy! When I tried to insert a microSD card, I got this message repeatedly, in the U-Boot terminal:

    EHCI timed out on TD - token=0x80008c80

    The keyboard stopped responding and I had no other option than to force restart. I think now we have enough evidence to say that the microSD circuitry went FUBAR. At this point you should probably contact CompuLab for a replacement.

    But this is not what I did. The appliance has 3 USB ports available, so why not use them? This will have the added benefit of USB devices being more accessible, than the hard to access microSD slot.

    Well, the original U-Boot image that the Utilite was shipped with, did not had USB boot support. This has long changed and the nice folks at CompuLab have built a newer version that supports booting from USB storage devices.

    Upgrading U-Boot

    First download the most recent U-Boot updater on your Utilite appliance:

    $ wget

    Check the MD5 sum:

    $ echo a79e492f3eb626c770c5185cda0edfec ; md5sum utilite-updater.tar.bz2 
    a79e492f3eb626c770c5185cda0edfec  utilite-updater.tar.bz2

    Extract the archive:

    $ tar xvjf utilite-updater.tar.bz2

    Run the updater:

    $ sudo ./ 
    CompuLab CM-FX6 (Utilite) boot loader update utility 2.2 (Feb 8 2015)
    >> Checking for utilities... 
    >> ...Done 
    >> Checking that board is CM-FX6 (Utilite)... 
    >> ...Done 
    Please input firmware file path (or press ENTER to use "cm-fx6-firmware"): 

    Just press ‘Enter’ after the above prompt. Then answer ‘Yes’ (y) to the following questions:

    >> Looking for boot loader image file: cm-fx6-firmware 
    >> ...Found 
    >> Looking for SPI flash: mtd0 
    >> ...Found 
    >> Current U-Boot version in SPI flash: U-Boot 2014.10-cm-fx6-2.1 (Jan 19 2015 - 11:28:10) 
    >> New U-Boot version in file:      U-Boot 2014.10-cm-fx6-2.1 (Jan 19 2015 - 11:28:10) (500K) 
    >> Proceed with the update? 
    1) Yes
    2) No
    #? <strong>y</strong>  
    ** Do not power off or reset your computer!!! 
    >> Erasing SPI flash... 
    Erasing 4 Kibyte @ bf000 -- 100 % complete 
    >> ...Done 
    >> Writing boot loader to the SPI flash... 
    >> ...Done 
    >> Checking boot loader in the SPI flash... 
    >> ...Done 
    >> Boot loader update succeeded!
    ** Resetting U-Boot environment will override any changes made to the environment! 
    >> Reset U-Boot environment (recommended)? 
    1) Yes
    2) No
    #? y
    >> U-boot environment will be reset on restart. 
    >> Done!

    Then reboot the appliance:

    $ sudo reboot

    It is a good idea to keep a backup of the original U-Boot configuration for future reference:

    $ sudo fw_printenv > utilite.uboot.orig

    Enhancing the USB boot setup

    If you study the above U-Boot setup you will find that the USB config works only if you have an option boot.scr script under the first partition of your USB. This excludes USB drives with only the uImage file. That means that you cannot even boot the Utilite SSD installer if you burn it on USB, since it does not have a boot.scr script.

    I’ve been playing around with the U-Boot environment and I came out to this configuration:

    setenv bootcmd run setupmmcboot;mmc dev ${storagedev};if mmc rescan; then run trybootsrz;fi;run setupusbboot;if usb start; then if run loadscript; then run bootscript;else run usbbootargs;if run loadkernel; then run doboot;else setenv bootargs;fi;fi;fi; run setupsataboot;if sata init; then run trybootsmz;fi;run setupnandboot;run nandboot;
    setenv usbroot /dev/sdb2
    setenv usbrootdelay=1
    setenv usbbootargs=setenv bootargs root=${usbroot} rootdelay=${usbrootdelay}

    If you don’t want to configure the above commands manually, you can download my custom U-boot environment updater and the patch I prepared:

    Download the U-Boot environment update shell script:

    $ wget
    $ chmox +x

    Download the U-boot custom configuration:

    $ wget

    Now load the custom configuration into the U-Boot environment:

    $ sudo ./ setup-usb-boot-utilite.uboot

    If something goes wrong you can restore your original configuration using the original configuration we saved earlier:

    $ sudo ./ utilite.uboot.orig

    The U-Boot environment updater will also create a backup file, with the current U-Boot environment configuration, just before the update:

    $ ls *.bak

    Test with the Utilite SSD installer

    Now it is time to test our new configuration.

    First download the SSD installer:

    $ wget

    Check the MD5 sum:

    $ echo 82eeb54c4d5245c60fd82c3e983d10e9 ; md5sum cl-installer_utilite-2_kernel-6.3_2014-12-17.img.xz
    82eeb54c4d5245c60fd82c3e983d10e9  cl-installer_utilite-2_kernel-6.3_2014-12-17.img.xz

    Extract it:

    $ unxz cl-installer_utilite-2_kernel-6.3_2014-12-17.img.xz

    This will extract a cl-installer_utilite-2_kernel-6.3_2014-12-17.img image file in the working directory.

    Now comes the tricky part. We will load the image in a USB device. Make sure you choose the correct device! The dd tool we are using below, is a heartless beast that will chew the data out of every device you select in its of= flag. If by mistake you give your internal disk instead of the USB, you will lose your partitions and data! You have been warned!

    So after you select a USB (one that does not have any data you need) insert it in your Linux workstation. Then try the following check to find out the device name of the USB drive:

    $ dmesg | tail -n20
    [61425.197050] mce: [Hardware Error]: Machine check events logged
    [71124.693498] compiz[1853]: segfault at 80000000 ip 0000000080000000 sp 00007ffc438c50a8 error 14
    [73897.971544] usb 1-2: new high-speed USB device number 10 using xhci_hcd
    [73898.105247] usb 1-2: New USB device found, idVendor=0951, idProduct=1665
    [73898.105254] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [73898.105257] usb 1-2: Product: DataTraveler 2.0
    [73898.105260] usb 1-2: Manufacturer: Kingston
    [73898.105262] usb 1-2: SerialNumber: 50E54951351BBE70A9455C5B
    [73898.106083] usb-storage 1-2:1.0: USB Mass Storage device detected
    [73898.106370] scsi host8: usb-storage 1-2:1.0
    [73899.187591] scsi 8:0:0:0: Direct-Access     Kingston DataTraveler 2.0 PMAP PQ: 0 ANSI: 6
    [73899.187848] sd 8:0:0:0: Attached scsi generic sg2 type 0
    [73900.521857] sd 8:0:0:0: [sdb] 15335424 512-byte logical blocks: (7.85 GB/7.31 GiB)
    [73900.522528] sd 8:0:0:0: [sdb] Write Protect is off
    [73900.522531] sd 8:0:0:0: [sdb] Mode Sense: 23 00 00 00
    [73900.523124] sd 8:0:0:0: [sdb] No Caching mode page found
    [73900.523126] sd 8:0:0:0: [sdb] Assuming drive cache: write through
    [73900.562834]  sdb: sdb1 sdb2
    [73900.565248] sd 8:0:0:0: [sdb] Attached SCSI removable disk
    [73903.203134] EXT4-fs (sdb2): mounted filesystem with ordered data mode. Opts: (null)

    So the device name is sdb and it has two partitions: sda1 and sda2. Check if these partitions have been mounted automatically:

    $ mount | grep sdb
    /dev/sdb2 on /media/theodotos/rootfs type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)
    /dev/sdb1 on /media/theodotos/boot type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)

    They are mounted. We need to unmount them before dumping the image on the device:

    $ sudo umount /dev/sdb1 /dev/sdb2

    Now we are ready to run dd (device dump) against the USB drive:

    $ sudo dd if=~/Downloads/cl-installer_utilite-2_kernel-6.3_2014-12-17.img of=/dev/sdb bs=1M

    You are not going to see any progress bar during the device dump. Just be patient and let the utility take its time.

    After dd finishes and returns back to the shell, safely remove the USB drive and try it on Utilite. If you reboot the appliance you should see the LXDE desktop of the Utilite installer. Unplug it and you are back to your Ubuntu, on the internal drive.