RootfsFromScratch

Revision 29 as of 2009-12-19 09:45:46

Clear message

This page describe the process to build a root filesystem for an armel target (ARM based) device from scratch using a builder script.

Using the builder script

A script that automates this process in Ubuntu jaunty (9.04) was created by the Ubuntu mobile team, it can be downloaded

Download Script HERE

  • Warning /!\ Starting with Ubuntu karmic a massively improved version of the script is available in the Ubuntu archive in the rootstock package, please use this instead of the bare script if you are on a Karmic (9.10) system

Newer versions of the script and a bzr branch can be found on launchpad in Project Rootstock

  • Warning /!\ Note: this script requires at least the most recent debootstrap version from Ubuntu jaunty.

You will need to install on your Ubuntu machine:

The following example will create a tarball of xubuntu-desktop based image for your target device (i.e. a beagleboard):

sudo ./build-arm-rootfs --fqdn beagleboard --login ubuntu --password temppwd --imagesize 2G --seed xubuntu-desktop

The following example will create a tarball of ubuntu-desktop based image for your target device:

sudo ./build-arm-rootfs --fqdn ubuntu --login ubuntu --password ubuntu --imagesize 3G --seed ubuntu-desktop

The options --fqdn (or -f), --login (or -l) and --password (-p) are required for the initial setup. Calling the script with --help shows you all the additional options that can be used to change the setup of the created rootfs.

  • Warning /!\ Recommendation: Don't pick a serious password if you plan to install this rootfs on other systems as well, rather pick something trivial and change your user password after the first login.

Building a qemu-only image

In case you want to just create an image for usage with qemu instead of building a rootfs tarball, the build-armel-rootfs script has the --notarball option, just call it like below and you will get a qemu image for usage with qemu-system-arm

sudo ./build-arm-rootfs --fqdn qemu-test --login qemu --password qemupwd --notarball

Settings

It is usually not necessary to set any additional options, things like the locale, keyboard setup and timezone will be automatically determined from the building host and will just be set accordingly in your target system, use the script options if you want any of these settings to differ from the build machine.

Typical images (example settings):

To build a xubuntu-desktop image use the following options:

--imagesize 2G --seed xubuntu-desktop

For an ubuntu-desktop image (a similar size is needed if you want a kubuntu image):

--imagesize 3G --seed ubuntu-desktop

A typical remote development comandline environment if you run an armel board headless (note that you should edit /etc/network/interfaces and set up your network device on first login for this):

--imagesize 3G --seed build-essential,openssh-server

A very light desktop (lxde):

--seed lxde,gdm

Creating qemu image from rootfs.tgz

If you don't want to use the --notarball option as described above but want to manually create a qemu Image from a tgz file containing a roofs you can do the following:

After creating the arm rootfs using the builder script, you will get two files:

  • build-arm-rootfs-<datetime>.log (contains the build log)

  • armel-rootfs-<datetime>.tgz (the rootfs)

To create qemu image from this rootfs file:

  • 1) Create the blank image file using dd. In this example, I made a 1GB image. You can change count=3072 for 3GB or count=2048 for 2GB image file.
     dd if=/dev/zero of=ubuntu-arm.img bs=1MB count=1024
    2) Create linux filesystem on the newly created image:
     sudo mke2fs -F -m 0 -b 1024 ubuntu-arm.img
    3) Loop mount the new image:
     mkdir myqemu
     sudo mount -t ext2 -o loop ubuntu-arm.img myqemu
    4) Extract the rootfs tarball inside the mounted dir (use -p to preserve permissions):
     cd myqemu
     sudo tar zxpf ../armel-rootfs-200904151837.tgz
     cd ..
     sudo umount myqemu
    5) Now you are set and ready to use the ubuntu-arm.img, see "Using a qemu image" below for the right command

Using a qemu image

If you created your qemu image and want to start a work environment (to compile packages or build applications), grab the kernel from:

qemu kernel

and start qemu with the following command (indeed, you need to adjust the rootfs img name to whatever your image is called)

sudo qemu-system-arm -M versatilepb -kernel ./vmlinuz-2.6.28-versatile -hda arm-rootfs.img -m 256 -append "root=/dev/sda mem=256M ro"

In the booted image you can then log in with the user and password you defined during image creation.

  • Warning /!\ To be able to copy files from or to the host system it is helpful to install openssh-server on the host and use the scp command inside qemu.

Connect your emulated machine to a real network

When no option is specified QEMU uses a non privileged user mode network stack that gives the emulated machine access to the world. But you probably want to make your emulated machine accessible from the outside. It is possible by using the tap mode and bridging the tap interface with the network interface of the host machine.

The first thing to do is to active a bridge on your host machine. For that you have to modify the /etc/network/interfaces file as follow:

Before:

auto eth0
iface eth0 inet dhcp

After:

auto br0
iface br0 inet dhcp
  bridge_ports eth0
  bridge_maxwait 0

Then you need to install the bridge-utils package and restart your network interface:

# apt-get install bridge-utils
# ifdown eth0
# ifup br0

Create a script call /etc/qemu-ifup that will be executed upon the start of QEMU:

echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /sbin/ifconfig $1 0.0.0.0 promisc up
echo "Adding $1 to br0..."
sudo /usr/sbin/brctl addif br0 $1
sleep 2

As you probably don't want to execute QEMU as root, you need to create a qemu user group and authorize the brctl and ifconfig commands for users of the qemu via sudo. You need to add the following lines to /etc/sudoers (edit the file using visudo):

...
Cmnd_Alias QEMU = /usr/sbin/brctl, /sbin/ifconfig
%qemu ALL=NOPASSWD: QEMU

Tap networking requires that the tun module is loaded:

$ sudo modprobe tun

To load it automatically on boot, edit /etc/modules and add a line that says "tun" so that the file looks like this:

# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

lp
tun

Finally you can start your emulated machine using the following command

$ qemu-system-arm -M versatilepb -kernel ./vmlinuz-2.6.28-versatile -hda arm-rootfs.img -m 256 -append "root=/dev/sda mem=256M ro" -net nic,macaddr=00:16:3e:00:00:01 -net tap

You don't need to give a MAC address if you are emulating only one machine, as QEMU will use a default one. However if you have more than one emulated machine (don't forget QEMU can also emulate other architectures than ARM), you will have to specify a unique MAC address for each machine. I advise you to select an address from the range 00:16:3e:xx:xx:xx, which has been assigned to Xen.

Bugs and Problems

If you run into any problems, please contact "ogra" in #ubuntu-arm on irc.freenode.net or send a mail to ogra@ubuntu.com

If you run into an error please keep the log of your failed build

A known issue is that language-pack handling is not implemented yet, please install the packages for your language manually post install.