I was inspired by Otto's blog series of getting Debian Linux on the RIoTboard: Linux on the RIoTBoard Part 1: U-Boot. However I need Ubuntu instead.


Following are the steps to get a current Linux kernel (4.1) with Ubuntu 14.04 (should work with a more current version one too).



I used Ubuntu 14.04 x86_64 to implement these instructions (actually it was a Virtual machine on VirtualBox).


Install Build dependencies:

sudo apt-get install git build-essential fakeroot kernel-package u-boot-tools lzop zlib1g-dev libncurses5-dev gcc-4.7-arm-linux-gnueabihf
sudo ln -s arm-linux-gnueabihf-gcc-4.7 /usr/bin/arm-linux-gnueabihf-gcc

Please note the specific install of gcc 4.7.  This is because the current version (as of 09/2015) in 14.04 of gcc 4.8 has a bug when building the Linux Kernel.  Feel free to try 4.9 or a fixed 4.8.

The following is needed to chroot to arm based rootfs.

sudo apt-get install qemu-user-static

This is needed to help in the steps to create an sdcard image.

sudo apt-get install qemu-utils kpartx


Environment Variables

Here are environment variables used in the scripts that follow.

export ARCH=arm
export CROSS_COMPILE=/usr/bin/arm-linux-gnueabihf-
export RIOT_PATH=~/riotboard
export RIOT_OUTPUT=$RIOT_PATH/output
mkdir -p $RIOT_OUTPUT



Here are the steps to build version 2015.07 of U-boot:

tar xjf u-boot-2015.07.tar.bz2
cd u-boot-2015.07
make riotboard_defconfig
cp u-boot.imx $RIOT_OUTPUT/.

If you prefer to use the latest U-Boot or a different version see: SourceCode < U-Boot < DENX



The boot.scr is used by U-Boot to give it the boot arguments to pass to the kernel as well as were to find the kernel and DTB.

Please note this script is very basic and needs to know where you will be booting from.  Change the DEVICE= line if you will be booting from eMMC or MicroSD instead.  My eMMC is busted so I have to boot from uSD or SD.

mkdir -p $RIOT_PATH/bootscript
cd $RIOT_PATH/bootscript
# Device 0=SD, 1=MicroSD, 2=eMMC
cat <<EOF > bootscript
setenv bootargs console=ttymxc1,115200 nosmp video=mxcfb0:dev=hdmi,1280x720M@60,bpp=32 video=mxcfb1:off fbmem=10M vmalloc=400M rootwait root=/dev/mmcblk0p1
mmc dev $DEVICE
ext4load mmc $DEVICE:1 10800000 /boot/zImage
ext4load mmc $DEVICE:1 16800000 /boot/imx6dl-riotboard.dtb
bootz 10800000 - 16800000
mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "boot script" -d bootscript boot.scr
cp boot.scr $RIOT_OUTPUT/.



I decided to use a specific released version (i.e. v4.1) of the kernel rather than the tip.  Feel free to change the tag to switch to a different version or remove the -b option if you want to build the tip.  I have not fully tested 4.1 but so far seems to work ok on the RIoTboard.

For detail on each step below see Otto's blog.

git clone -b v4.1
cd linux
make imx_v6_v7_defconfig
# Do this next step if you need to change kernel config.
make menuconfig
# this next step will take a long time.  You can try -j option to parallelize.
make bzImage
mkdir -p $RIOT_OUTPUT/boot
sudo cp arch/arm/boot/zImage $RIOT_OUTPUT/boot/zImage
make dtbs
sudo cp arch/arm/boot/dts/imx6dl-riotboard.dtb $RIOT_OUTPUT/boot/imx6dl-riotboard.dtb
make modules
make modules_install INSTALL_MOD_PATH=$RIOT_OUTPUT
make headers_install INSTALL_HDR_PATH=$RIOT_OUTPUT/usr
tar -czf linux-kernel.tgz boot lib usr
rm -rf boot lib usr


Root Filesystem

For the rootfs I decided to start from the official ubuntu release and customize it as opposed to building it completely like Otto showed in his blog for Debian.  You can browse here: Index of /ubuntu-core/releases if you would like to pick a different ubuntu release.  If you do, make sure to use an armhf one and update the customizations below in case they are different for your distro.

Unlike other steps above I am going to break this one down:

Get a starting rootfs

mkdir -p $RIOT_OUTPUT/rootfs
sudo tar --numeric-owner -xzpf ubuntu-core-14.04-core-armhf.tar.gz -C $RIOT_OUTPUT/rootfs

Customize the rootfs

We will chroot to the arm rootfs to make some of the customizations.

# to enable arm emulation
sudo cp /usr/bin/qemu-arm-static $RIOT_OUTPUT/rootfs/usr/bin/
# to enable dns lookups to work
sudo cp /etc/resolv.conf $RIOT_OUTPUT/rootfs/etc
sudo chroot $RIOT_OUTPUT/rootfs

Do your customizations.  Feel free to adjust the stuff below to your needs.  Please note not all of what I am doing below needs to be done from chroot (e.g the file editing and creations).

# setup a locale
locale-gen en_US en_US.UTF-8
# Install any packages you want that are not in the core rootfs from
apt-get -y install openssh-server ntpdate
# Create users. The following adds usr/pw: ubuntu/ubuntu
PASSWD=`openssl passwd -crypt ubuntu`
/usr/sbin/useradd ubuntu -m -s /bin/bash -p $PASSWD
# The stuff below can be done outside of chroot. Just make sure to adjust destination files if you do.
# Enable the user to sudo without the need for pw.
echo -e 'ubuntu\tALL=(ALL)\tNOPASSWD: ALL' >> /etc/sudoers
# Configure your network
cat <<EOF >> /etc/network/interfaces
auto eth0
iface eth0 inet dhcp
# Set the hostname
echo riotboard > /etc/hostname
# Enable login from the serial console
cat <<EOF > /etc/init/serial-console.conf
# serial-console - getty
# This service maintains a getty on console from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]

stop on runlevel [!2345]

exec /sbin/getty -L 115200 ttymxc1 vt100
#setup fstab to mount the rootfs
echo '/dev/mmcblk0p1  /  auto  errors=remount-ro  0  1' >> /etc/fstab

Clean up apt, exit chroot and remove the chroot setup files

# Clean up apt
apt-get clean
# Clean up files we added to enable chroot and dns
sudo rm $RIOT_OUTPUT/rootfs/usr/bin/qemu-arm-static
sudo rm $RIOT_OUTPUT/rootfs/etc/resolv.conf


Bundle up the rootfs:

cd $RIOT_OUTPUT/rootfs
sudo tar -czpf ubuntu-trusty.tgz *
sudo mv ubuntu-trusty.tgz $RIOT_OUTPUT/.


Create SD Card Image

Now we create the SD Card image that we will write to an SD card.  You could even write this to the eMMC device (don't forget to change the boot script to load from device 2 if you do this).  If you prefer you can use /dev/sdX instead of sdcard.img below if you want to write direct to the SD card instead of an image first.

# Create a file to hold the disk image
qemu-img create sdcard.img 3600M
# Partition the disk image leaving some room (10mb) for u-boot in front of the first partition.
sfdisk --force -uM sdcard.img << EOF
# create devices from the disk image
sudo kpartx -av sdcard.img
# format the partition. Make sure to use the correct device from the previous command.
mkfs.ext4 -j /dev/mapper/loop0p1
# create a mount point
sudo mkdir -p /mnt/sdcard
# Mount the partition we formatted.
sudo mount -t ext4 /dev/mapper/loop0p1 /mnt/sdcard
# Unpack the root fs and kernel
sudo tar --numeric-owner -C /mnt/sdcard -zxpf ubuntu-trusty.tgz
sudo tar --numeric-owner -C /mnt/sdcard -zxpf linux-kernel.tgz
# Copy the boot script to the top level
sudo cp boot.scr /mnt/sdcard/boot.scr
# Unmount and clean up devices
sudo umount /mnt/sdcard
sudo kpartx -dv sdcard.img
# put u-boot 2 blocks into the disk image.  Don't leave out the notrunc option.
dd if=u-boot.imx of=sdcard.img bs=512 seek=2 conv=notrunc

Now you can use dd or whatever tool you want to write the disk image to an SD card. Eg: sudo dd if=sdcard.img of=/dev/sdd bs=1m


Boot your SD Card

Plug the SD Card into the SD card slot.  Set the switches 2,4,5,7 to OFF and the rest to ON to boot from SD.

If you are using a MicroSD, make sure to change the boot script to use device 1 instead of 0 and set the dip switches to 2,4,5,8 OFF and the rest ON.



See Otto's blog post mentioned above for how to use the MfgTool to write the above files to the eMMC flash from Windows as well as more detailed explanations to some of the stuff above..