Canonical is now sharing a minimal filesystem for ARM based called Ubuntu Core. See here: https://wiki.ubuntu.com/Core
This image contains the APT software so you can install and customize your filesystem from a minimal installation. This is mainly for developers who want to run a custom filesystem on an embedded device.
Except specified otherwise, most instructions and information provided in this wiki is applicable to any ARM platform.
Configuring a boot partition e.g. Pandaboard
Here are a few steps I followed in order to get to a shell prompt on the serial console on my Pandaboard ES2.1:
- If you don't already have one, prepare an SD Card with 2 partitions: one for the boot and one for the rootfs. See here for detailed instructions: http://omappedia.org/wiki/SD_Configuration
- Open a terminal and follow the instructions below.
- Create a temporary folder:
- Create the boot script file boot.script with the following content:
fatload mmc 0:1 0x80000000 uImage
setenv bootargs rw vram=32M fixrtc mem=1G@0x80000000 root=/dev/mmcblk0p2 console=ttyO2,115200n8 rootwait
- Generate the boot.scr file:
mkimage -A arm -T script -C none -n "Boot Image" -d boot.script boot.scr
- Download the 12.04 release from Canonical:
- Download the MLO, u-boot.bin and kernel:
wget -O MLO http://ports.ubuntu.com/ubuntu-ports/dists/precise/main/installer-armhf/current/images/omap4/netboot/MLO
wget -O u-boot.bin http://ports.ubuntu.com/ubuntu-ports/dists/precise/main/installer-armhf/current/images/omap4/netboot/u-boot.bin
wget -O uImage http://ports.ubuntu.com/ubuntu-ports/dists/precise/main/installer-armhf/current/images/omap4/netboot/uImage
- Copy files over to the boot partition:
cp MLO u-boot.bin uImage boot.scr /media/boot
- Untar the filesystem onto the SDCard:
sudo tar xvfz $TMPDIR/<ubuntu core tarball>.tar.gz
rm -rf $TMPDIR
- Alternatively, you can create your environment with
- Ubuntu 11.10, by downloading the following files instead of the one mentioned above:
- Ubuntu 12.10, by downloading the following files instead of the one mentioned above:
Tuning the Filesystem
By default, the Ubuntu Core has no login prompt or serial console. You can get it to work with the following steps:
Getting a Terminal on the same serial port as for the console
- If you have a "console" bootarg in your u-boot you can simply add 2 files to read the "console=" from /proc/cmdline file and do similarly to the linaro-overlay-minimal Linaro package:
- On the SD Card rootfs partition, go to the init folder:
- Create a new file with the extention of ".conf". It could be "serial-auto-detect-console.conf" for instance with the following content:
# serial-auto-detect-console - starts getty on serial console
# This service starts a getty on the serial port given in the 'console' kernel argument.
start on runlevel 
stop on runlevel [!23]
exec /bin/sh /bin/serial-console
- Secondly, create a shell script that will parse the kernel command line, read the "console" argument and launch the TTY:
This file shall be called the same name as in its invokation in the 'exec' line of the "serial-auto-detect-console.conf" file. Therefore, you need to create in our case a file named "/bin/serial-console" with 'r+x' (read and execute) rights:
for arg in $(cat /proc/cmdline)
case $arg in
case $tty in
# check for service which do something on this port
if [ -f /etc/init/$PORT.conf ];then continue;fi
# 8bit serial is default
[ -z $BITS ] && BITS=8
[ 8 -eq $BITS ] && GETTY_ARGS="$GETTY_ARGS -8 "
[ -z $SPEED ] && SPEED='115200,57600,38400,19200,9600'
GETTY_ARGS="$GETTY_ARGS $SPEED $PORT"
exec /sbin/getty $GETTY_ARGS
Login in "root" without the need of a password
- On the SD Card rootfs partition, edit the file /etc/shadow and remove the '*' character in between the semi-colons. You should get something like:
Getting network up and running
In most cases, you'll just need to look at your Linux Desktop PC settings and mimic those for your board.
The following steps will describe the configuration when using a DHCP server.
Network configuration files for 'DHCP' client
A few files on your target filesystem need to be taken care of. You can edit them from a Linux PC, this is the easiest way as not even "vi" is installed on the Ubuntu Core Filesystem. Steps are as follow:
- Edit your /etc/network/interfaces file and add the bottom 2 lines:
iface lo inet loopback
iface eth0 inet dhcp
- If you are behind a firewall inside a 'Corporate Network', the following 2 files may need to be edited to according to your Coporate settings:
- Edit your /etc/resolv.conf file and have something similar to this:
Remove the "<>" symbols and replace by your own corporate DHCP and DNS servers adresses.
nameserver <IP address of your DNS server 1>
nameserver <IP address of your DNS server 2>
In your /etc/environment file, add something similar to this using your own corporate proxy server address and port number:
In your /etc/apt/apt.conf.d/proxy, add similar to this using your own corporate proxy server address and port number:
Proxy <corporate apps address>:<port number>;
Proxy::<ubuntu corporate address> "DIRECT";
Just copy your similar file in your system and that should work.
Boot your Panda with network
- Re-insert your SD Card into the Pandaboard
- Boot the board with the network cable attached.
- You should have an IP address after you run the following command line:
In order to avoid this step, it's simpler to just add 'ip=dhcp' in the bootargs. The system will just request an IP address at boot time. In this case, your bootargs would look like it:
bootargs quiet rw vram=32M fixrtc mem=1G@0x80000000 root=/dev/mmcblk0p2 console=ttyO2,115200n8 rootwait ip=dhcp
- Finally verify you can use APT command:
should run fine.
Configuring APT to fetch all packages
- By default, many Ubuntu and TI packages are not installable, and hardware acceleration is not available. In order to fetch all Ubuntu and TI repositories (What's this ?), you need to add the following lines to /etc/apt/sources.list :
# Ubuntu repositories
deb http://ports.ubuntu.com/ubuntu-ports/ precise universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ precise-updates universe multiverse
deb http://ports.ubuntu.com/ubuntu-ports/ precise-security universe multiverse
# TI release PPA
deb http://ppa.launchpad.net/tiomap-dev/release/ubuntu precise main
deb-src http://ppa.launchpad.net/tiomap-dev/release/ubuntu precise main
apt-get dist-upgrade --yes
apt-get install ubuntu-omap4-extras u-boot-tools --yes --force-yes
- Note that during TI package installation, a confirmation message will appear, before upgrading the kernel to 3.4.
- For more details, see TI release PPA
- Check content or create file /etc/flash-kernel.conf:
- Update the boot script file /boot/boot.script with the following content:
fatload mmc 0:1 0x80000000 uImage
fatload mmc 0:1 0x81600000 uInitrd
setenv bootargs ro elevator=noop console=ttyO2,115200n8 mem=1G@0x80000000 root=/dev/mmcblk0p2 fixrtc
bootm 0x80000000 0x81600000
- Note: you can add e.g. "ip=dhcp" option, but do not set any vram option.
- Now ensure that new boot.script is taken into account, run:
Adding a User Interface
- First you need to install Xorg:
- And now a window manager. A light WM is OpenBox and it can be installed with the following command line:
apt-get install openbox obconf openbox-themes
Note: if this command fails, see Configuring APT to fetch all packages
- PVR driver seems to have issues with the HW mouse cursor (blinking cursor). Hence you may disabled it in /usr/share/X11/xorg.conf.d/99-omap.conf/ file:
Identifier "Video Device"
Option "Debug" "false"
Option "HWCursor" "false"
Note: on former Ubuntu distribution, the configuration file was /etc/share/X11/xorg.conf.d/99-pvr.conf and the option was "SWCursor" "true"
- Last but not least, start X:
- You are now ready to right-click on your mouse and open an X-Terminal.
Kernel and Bootloaders, do it yourself instead of using prebuilt binaries
So now, the basic system is up to date, you have a working minimal Ubuntu environment. As you have certainly noticed, so far you have been using pre-built binaries downloaded from the Ubuntu archive. So now it is time to get into the real stuff, and rebuild your own kernel and bootloaders and start customizing it!
First let's start with u-boot. Some decent efforts have been made by various people in the OMAP community to ensure that all the necessary patches are available in mainline boot. So in general, you just need to checkout a recent u-boot commit , build and put the binaries on SD boot partition... Nevertheless because u-boot is under active development, sometimes a random commit from the mainline tree might not work. As such it is recommended to use the most recent stable u-boot release (git tag) unless you really know what you are doing.
At the time of this writting, the most recent u-boot released version is v2011.12. So the following instructions will get you a working set of bootloaders for Panda and Panda ES (I tested on Rev A1 and Rev EB3):
git clone git://git.denx.de/u-boot.git
git checkout -b v2011.12 v2011.12
<set ARCH and CROSS_COMPILE environment variables>
That will generate the following files:
u-boot.img is exactly the same as u-boot.bin, but a u-boot header has been appended (using mkimage). Nowadays , with current version of u-boot it is expected to use u-boot.img, as this filename is hardcoded in the initial bootloader (MLO).
So now you can copy the 2 files (MLO and u-boot.img) onto the SD boot partition to replace the pre-built bootloaders, and you should be able to boot again, and verify that you are using your own bootloaders (check the boot traces).
Linaro is also maintaining its own stable version of u-boot which is being used for Linaro and Canonical releases. The git tree is located here http://git.linaro.org/gitweb?p=boot/u-boot-linaro-stable.git. As usual you should start by using the most recent tag/branch. In general Linaro tree might get a few more patches which are in the process of being upstreamed, but the differences with mainline tend to decrease over time.
Similarly to u-boot, there is some good support for Panda and Panda ES with the mainline kernel. As of this writting mainline kernel is at v3.3-rc1. If you checkout a recent mainline, you should be able to compile with the default OMAP defconfig, and it should boot:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git checkout -b v3.3-rc1 v3.3-rc1 <or just use 'master' if you know what you are doing>
<set ARCH and CROSS_COMPILE environment variables>
Alternatively, you might want to build the kernel modules as well:
The default omap2plus_defconfig is the kernel configuration that works on any OMAP2+ boards. There are default settings, that you might want to change. For example, you can enable USB EHCI and that will bring support for the USB host on the Panda. Of course there are tons of other settings that you can change, it is now time to start customization!
Chroot'ing into the Ubuntu Core Filesystem
One solution to customize your Ubuntu Core Filesystem is to do it from the Linux PC. Using a 'chroot' is sometimes quite convinient as you can run commands as you normally do on the ARM target. Here are some quick steps to get running:
Chroot configuration on the Linux PC
- Verify that on your Linux PC you have the 'qemu-user-static' Ubuntu package installed.
This can be done with the following command line (on your Linux PC):
- Have your SD Card mounted on your Linux PC and go to your rootfs Ubuntu Core folder, generally:
- Copy the qemu for arm file:
cp /usr/bin/qemu-arm-static usr/bin/
- If not done yet, have your network settings properly configured:
mv etc/resolv.conf etc/resolv.conf.saved
cp /etc/resolv.conf etc/resolv.conf
- Then, mount sys, proc and dev:
for m in `echo 'sys dev proc'`; do sudo mount /$m ./$m -o bind; done
- Finally, chroot into your target filesystem:
sudo LC_ALL=C chroot . /bin/bash
You are now in your 'chroot' which means you can run commands like if you were on your target ARM device.
Using the 'chroot'
- The first step is to verify the network connection is fine. You can run:
- You are now ready to install any new package in your Ubuntu Core Filesystem using APT tools.
Getting out of the 'chroot'
- Un-mount the target filesystem:
Make sure your at the / target FS and run the following commands:
for m in `echo 'sys dev proc'`; do sudo umount ./$m; done
- Go back to your original network settings:
mv etc/resolv.conf.saved etc/resolv.conf
- I created some helper scripts and was thinking it might be useful for everyone to share: https://github.com/DavidBercovitz/ubuntu-core
- This script should help you create everything from scratch without having to type all the basic commands. I found it particularly useful for automation.
Some useful links
Canonical Ubuntu Core wiki: http://www.canonical.com/engineering-services/ubuntu-core
Ubuntu Core Is Getting Ready For Oneiric: http://victorpalau.net/2011/08/26/ubuntu-core-is-getting-ready-for-oneiric/