Development With Ubuntu

From OMAPpedia

Jump to: navigation, search

Here is a collection of tips which can be useful for people developing root filesystems or applications with Ubuntu.


[edit] Boot Ubuntu desktop / netbook on NFS

At least if you boot your root filesystem directly (without going through a standard Ubuntu initramfs), you probably noticed:

The system hangs during the boot sequence. It's because of NetworkManager that reinitializes the network interface that you used for NFS.

A quick workaround is just to disable NetworkManager, for example by renaming the corresponding upstart configuration file:

sudo mv /etc/init/network-manager.conf /etc/init/network-manager.conf.disabled

Of course, this is shouldn't be done in a user environment, because users will need NetworkManager (to connect to their wired and wireless networks). However, this can make your life easier if you are involved in product test or development.

[edit] Extract the contents of a uInitrd file

This can be useful to study boot scripts and analyze the early boot process in Ubuntu:

First, remove the U-boot header:

dd if=uInitrd of=initrd skip=64 bs=1

The initrd is a compressed cpio archive. Let's extract this archive...

On Maverick and beyond, it is compressed with lzma:

lzcat initrd | cpio -id

On Lucid and earlier versions, it is compressed with gzip

zcat initrd | cpio -id

Note: the U-boot header added to the initrd file is currently 64 bytes. This could change, and this can be different in other U-boot files. Here's a tip to find the actually U-boot header size. You can find the original image size with:

> mkimage -l uInitrd
Image Name:   Ubuntu Initrd
Created:      Wed Oct  6 05:09:47 2010
Image Type:   ARM Linux RAMDisk Image (gzip compressed)
Data Size:    5978226 Bytes = 5838.11 kB = 5.70 MB
Load Address: 0x00000000
Entry Point:  0x00000000

The header size is the uInitrd file size minus the data size listed by mkimage.

[edit] Modify an existing uInitrd file

First, extract the contents of the uInitrd file to an initrd directory by following the above instructions.

Then, run the following commands:

cd initrd
<make changes: for example by adding "set -x" in some scripts to debug them>
find . | cpio -H newc -o | lzma -c > ../initrdnew.lzma
cd ..
mkimage -A arm -O linux -T ramdisk -C none -a 0 -e 0 -n initramfs -d ./initrdnew.lzma ./uInitrdnew

Replace lzma by gzip if your initramdisk was initially compressed with gzip (in Ubuntu Lucid and earlier versions, for example).

Note that the newc format for cpio is mandatory. If you don't use it, Linux won't be able to extract this archive.

[edit] Use ccache for your builds

Using ccache during your builds on Ubuntu is simple; just install ccache on your machine:

$ sudo apt-get install ccache

...and add it first to your $PATH:

$ export PATH="/usr/lib/ccache:$PATH"

OR alternatively, if you want to use ccache for all compilations, you can softlink the desired binaries:

$ sudo cp ccache /usr/local/bin/
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/gcc
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/g++
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/cc
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/arm-none-linux-gnueabi-gcc
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/arm-none-linux-gnueabi-g++
$ sudo ln -s /usr/local/bin/ccache /usr/local/bin/arm-none-linux-gnueabi-cc

This will work as long as /usr/local/bin comes before the path to gcc (which is usually in /usr/bin). After installing you may wish to run "which gcc" to make sure that the correct link is being used.

[edit] Create a cross chroot environment

There are many wikis/blogs about this already, but I often find it cumbersome to get the exact instructions that work... and since I am using that often I am putting my own instructions here. At least I won't need to search them anymore, and at best it will be useful for others.

So basically here the purpose is to create an ARM root FS and be able to 'start' it from a desktop/laptop (x86) using QEMU user emulation. Clearly reading the following links will provide information about what this is all about:

So here are the exact instructions that worked like a charm for me.

First install the required packages:

sudo apt-get install debootstrap schroot binfmt-support qemu qemu-user-static 

then create the 'foreign' root fs with:

sudo debootstrap --arch armel --variant buildd --foreign oneiric /var/chroot/oneiric_armel

or if you prefer to go with armhf...

sudo debootstrap --arch armhf --variant buildd --foreign precise /var/chroot/precise_armhf

Note: If you are behind a proxy, you may want to consider using:

sudo debootstrap --arch armhf --variant buildd --foreign precise /var/chroot/precise_armhf

This will take a few minutes, it will download all the .deb files that need to be install and unpack them.

Now, we need to finalize the packages installation in the target root FS.

First, copy the QEMU binary in the chroot (this is what will make sure that you can run an ARM executable on your desktop using emulation):

sudo cp /usr/bin/qemu-arm-static /<your chroot>/usr/bin/

Now you can enter your chroot and run the 'second stage deboostrap' that will finalize the packages installation and configuration.

sudo chroot /<your chroot>/
/debootstrap/debootstrap --second-stage

Now you need to create a valide 'sources.list' file in your chroot

<edit> /<your chroot>/etc/apt/sources.list

and add something like this (customize it as you want, and make sure that you use the right ubuntu release name)

deb oneiric main restricted universe multiverse
deb-src oneiric main restricted universe multiverse

Now you are all set! You can chroot in your ARM root FS and install packages, or do anything you want (like doing 'native' compilation). To enter the chroot, just run:

sudo chroot /<your chroot>/
apt-get update
apt-get install <anything>

As you will notice you would be identfied as 'root', that can be fine most of the time. However if you plan to use the chroot as a 'working' environment, you might prefer to create standard users. You can do it with 'adduser' command and manage users/groups in the chroot as if you were on a 'different' computer. But there is a better mechanism...based on 'schroot'. You can read to get more information, but basically it allows to seemlessly chroot using privileges from the current computer. And as a convenience, 'schroot' will also mount your regular '$HOME' folder so that you get all your 'stuff', including things like SSH or PGP keys...

In order to use schroot, you need to create a configuration file, e.g.

sudo <edit> /etc/schroot/chroot.d/arm.conf   # it can be any file with .conf extension

and add something like that

[<config name>]
description=Ubuntu ARM chroot
directory=/<your chroot path>/
root-users=<your login>
users=<your login>

What this does is:

So now to log as 'root' you can run:

schroot -c <config name> -u root

And to log as standard user, you can run:

schroot -c <config name> -u <your login>

Using <your login> you should find this very convenient to build/develop from your PC as if you were on a real ARM device!

[edit] Other notes for developers

Personal tools