ELCE 2012 slides: porting Linux to new ARM SoC

We are just returning from Barcelona, Spain, after participating to the 2012 edition of the Embedded Linux Conference Europe. My colleague Thomas Petazzoni has delivered the below presentation:

Your New ARM SoC Linux Support Check-List

Since Linus Torvalds raised warnings about the state of the ARM architecture support in the Linux kernel, a huge amount of effort and reorganization has happened in the way Linux supports ARM SoCs. From the addition of the device tree to the pinctrl subsystem, from the new clock framework to the new rules in code organization and design, the changes have been significant over the last one and half year in theARM Linux kernel world.

Based on the speaker’s experience on getting the new Marvell Armada 370 and Armada XP SoC supported in the mainline Linux kernel, we will give an overview of those changes and summarize the new rules for ARM Linux support. We aim at helping developers willing to add suppot for new ARM SoCs in the Linux kernel by providing a check-list of things to do.

Thomas Petazzoni is an embedded Linux engineer and trainer at Free Electrons since 2008. He has been involved with multiple projects around the Linux kernel, especially the mainlining of Marvell Armada 370/XP SoCs support. He is also a major contributor to the Buildroot embedded Linux build system with more than 1100 patches merged.

The presentation slides and their sources are now available here. We have also shot a video of Thomas’ talk and it should be available in the next weeks. Stay tuned!

Do not hesitate to contact us if you are looking for engineers to port Linux to new hardware.

Free Electrons at the Libre Software Meeting

In a previous post, we detailed all the talks of the Embedded Systems and Open Hardware track of the Libre Software Meeting, taking place in Geneva in early July.

Free Electrons will have a quite important presence at this event, with three talks and one tutorial given by Free Electrons engineers. You’ll find below the descriptions of the talks given by Free Electrons. Both my colleague Maxime Ripard and myself will be present at Libre Software Meeting, and we will be happy to meet you there to discuss Embedded Linux and Android topics!

A look through the Android Stack

Android has established itself in the past years as a major player in the mobile market, outperforming any other mobile systems.

To do so, Google relied both on well established open-source components, such as the Linux Kernel, and munching them together in a brand new userspace environment. This talk will detail the most important components of Android userspace and the interactions between them that allow developers to face a consistent API for their applications.

This talk will be given on Tuesday 9th July 2012, at 14:00, by Maxime Ripard, embedded Linux and Android engineer at Free Electrons. Maxime is also teaching our newest training course on Android system development.

Buildroot: a nice, simple and efficient embedded Linux build system

Started in late 2001 by uClibc developers, Buildroot has grown over its 10 years history from a testing tool for the uClibc C library to a complete, vendor-neutral, embedded Linux build system. Until early 2009, the project was mostly unmaintained and the quality slowly decreased, frustrating many Buildroot users. Fortunately, since early 2009, Peter Korsgaard took over the maintainership of Buildroot, and the project has considerably evolved since then: stable releases are published every three months, the user and developer community has grown significantly, the existing features have been cleaned up, many other new features have been added, the project is no longer uClibc-specific and the quality has been vastly improved. Buildroot now offers a nice, simple and efficient mechanism to build small to medium sized embedded Linux systems, such as the ones found in many industrial systems or highly dedicated systems. Many users are amazed about how easy it is to get started with Buildroot, especially compared to other build systems. This presentation will show how Buildroot can be used to build embedded Linux systems, highlighting the new features and improvements made over the last few years, and detailing how the simplicity of Buildroot allows you to focus on developing the applications for your system. A quick overview of the future Buildroot developments will also be provided.

This talk will take place on Wednesday 10th July at 17:00 and will be given by Thomas Petazzoni, embedded Linux engineer at Free Electrons, and long time Buildroot contributor.

Linux kernel on ARM: consolidation work

In Spring 2011, Linus Torvalds asked the ARM Linux maintainers to clean up the contents of arch/arm/ in the Linux kernel code by doing more consolidation between ARM sub-architectures.

More than a year later, a lot of work has been accomplished in this area, especially thanks to the introduction of the device tree for the ARM architecture, the pinctrl subsystem and the clock framework into the Linux kernel.

Through this talk, we will present the challenges the ARM architecture creates in terms of Linux kernel support, and then describe from a technical point of view how the device tree, the pinctrl subsystem and the clock subsystem work and how they can improve the consolidation between different ARM sub-architectures.

The talk will be designed to be accessible to an audience having only a moderate knowledge of kernel programming and internals, and will therefore provide enough context for such audience to understand the issues that those different mechanisms are striving to solve.

This talk will take place on Thursday 11th July at 10:00 and will be given by Thomas Petazzoni, embedded Linux engineer at Free Electrons.

Tutorial on using Buildroot, a nice, simple and efficient embedded Linux build system

Started in late 2001 by uClibc developers, Buildroot has grown over its 10 years history from a testing tool for the uClibc C library to a complete, vendor-neutral, embedded Linux build system. Until early 2009, the project was mostly unmaintained and the quality slowly decreased, frustrating many Buildroot users. Fortunately, since early 2009, Peter Korsgaard took over the maintainership of Buildroot, and the project has considerably evolved since then: stable releases are published every three months, the user and developer community has grown significantly, the existing features have been cleaned up, many other new features have been added, the project is no longer uClibc-specific and the quality has been vastly improved. Buildroot now offers a nice, simple and efficient mechanism to build small to medium sized embedded Linux systems, such as the ones found in many industrial systems or highly dedicated systems. Many users are amazed about how easy it is to get started with Buildroot, especially compared to other build systems.

This workshop follows the Buildroot presentation proposed in the same topic. During one half-day participants will be introduced on how to efficiently use Buildroot for their own projects:

  • Basic usage of Buildroot: generate the first system, boot it on a hardware platform
  • Add packages to Buildroot
  • Customize Buildroot for real-life projects: how to integrate project specific patches, configuration and customization

Participants are invited to come with their own laptop, installed with a sufficiently recent GNU/Linux distribution. Participants are recommended to attend the Buildroot talk by the same speaker before attending the workshop, as the talk will give an overall introduction on Buildroot.

This tutorial will take place on Thursday 11th July from 14:00 to 17:00 and will be given by Thomas Petazzoni, embedded Linux engineer at Free Electrons, and long time Buildroot contributor.

Embedded topics at the Libre Software Meeting, Geneva, July 9-11

Libre Software Meeting, Geneva
Libre Software Meeting, Geneva

The Libre Software Meeting is a community-driven free software event that exists since 2000, composed of talks and workshops. Its 2012 edition will take place from July 7th to July 12th in Geneva, Switzerland.

In the context of this conference, I was responsible with Florian Fainelli from the OpenWRT project to organize the Embedded systems and open hardware track. This track will offer an interesting selection of talks related to embedded topics, concentrated between July 9th and July 11th:


In the Operating Systems track, some other conferences might be of interested to Embedded Linux developers as well:

The entrace to the Libre Software Meeting is free, so don’t hesitate to book your train or flight tickets, and join us at this event!

How to boot an uncompressed Linux kernel on ARM

This is a quick post to share my experience booting uncompressed Linux kernel images, during the benchmarks of kernel compression options, and no compression at all was one of these options.

It is sometimes useful to boot a kernel image with no compression. Though the kernel image is bigger, and takes more time to copy from storage to RAM, the kernel image no longer has to be decompressed to RAM. This is useful for systems with a very slow CPU, or very little RAM to store both the compressed and uncompressed images during the boot phase. The typical case is booting CPUs emulated by FPGA, during processor development, before the final silicon is out. For example, I saw a Cortex A15 chip boot at 11 MHz during Linaro Connect Q2.11 in Budapest. At this clock frequency, booting a kernel image with no compression saves several minutes of boot time, reducing development and test time. Note that with such hardware emulators, copying the kernel image to RAM is cheap, as it is done by the emulator from a file given by the user, before starting to emulate the system.

Building a kernel image with no compression on ARM is easy, but only once you know where the uncompressed image is and what to do! For people who have never done that before, I’m sharing quick instructions here.

To generate your uncompressed kernel image, all you have to do is run the usual make command. The file that you need is arch/arm/boot/Image.

Depending on the bootloader that you use, this could be sufficient. However, if you use U-boot, you still need to put this image in a uImage container, to let U-boot know about details such as how big the image is, what its entry point is, whether it is compressed or not… The problem is you can’t run make uImage any more to produce this container. That’s because Linux on ARM has no configuration option to keep the kernel uncompressed, and the uImage file would contain a compressed kernel.

Therefore, you have to create the uImage by invoking the mkimage command manually. To do this without having to guess the right mkimage parameters, I recommend to run make V=1 uImage once:

$ make V=1 uImage
  Kernel: arch/arm/boot/zImage is ready
  /bin/bash /home/mike/linux/scripts/mkuboot.sh -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n 'Linux-3.3.0-rc6-00164-g4f262ac' -d arch/arm/boot/zImage arch/arm/boot/uImage
Image Name:   Linux-3.3.0-rc6-00164-g4f262ac
Created:      Thu Mar  8 13:54:00 2012
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    3351272 Bytes = 3272.73 kB = 3.20 MB
Load Address: 80008000
Entry Point:  80008000
  Image arch/arm/boot/uImage is ready

Don’t be surprised if the above message says that the kernel is uncompressed (corresponding to -C none). If we told U-boot that the image is already compressed, it would take care of uncompressing it to RAM before starting the kernel image.

Now, you know what mkimage command you need to run. Just invoke this command on the Image file instead of zImage (you can directly replace mkuboot.sh by mkimage):

$ mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n 'Linux-3.3.0-rc6-00164-g4f262ac' -d arch/arm/boot/Image arch/arm/boot/uImage
Image Name:   Linux-3.3.0-rc6-00164-g4f262ac
Created:      Thu Mar  8 14:02:27 2012
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    6958068 Bytes = 6794.99 kB = 6.64 MB
Load Address: 80008000
Entry Point:  80008000

Now, you can use your uImage file as usual.

Linux on ARM: xz kernel decompression benchmarks

I recently managed to find time to clean up and submit my patches for xz kernel compression support on ARM, which I started working on back in November, during my flight to Linaro Connect. However, it was too late as Russell King, the ARM Linux maintainer, already accepted a similar patch, about 3 weeks before my submission. The lesson I learned was that checking a git tree is not always sufficient. I should have checked the mailing list archives too.

The good news is that xz kernel compression support should be available in Linux 3.4 in a few months from now. xz is a compression format based on the LZMA2 compression algorithm. It can be considered as the successor of lzma, and achieves even better compression ratios!

Before submitting my patches, I ran a few benchmarks on my own implementation. As the decompressing code is the same, the results should be the same as if I had used the patches that are going upstream.

Benchmark methodology

For both boards I tested, I used the same pre 3.3 Linux kernel from Linus Torvalds’ mainline git tree. I also used the U-boot bootloader in both cases.

I used the very useful grabserial script from Tim Bird. This utility reads messages coming out of the serial line, and adds timestamps to each line it receives. This allow to measure time from the earliest power on stages, and doesn’t slow down the target system by adding instrumentation to it.

Our benchmarks just measure the time for the bootloader to copy the kernel to RAM, and then the time taken by the kernel to uncompress itself.

  • Loading time is measured between “reading uImage” and “OK” (right before “Starting kernel”) in the bootloader messages.
  • Compression time measured between “Uncompressing Linux” and “done”:
    ~/bin/grabserial -v -d /dev/ttyUSB0 -e 15 -t -m "Uncompressing Linux" -i "done," > booting-lzo.log

Benchmarks on OMAP4 Panda

The Panda board has a fast dual Cortex A9 CPU (OMAP 4430) running at 1 GHz. The standard way to boot this board is from an MMC/SD card. Unfortunately, the MMC/SD interface of the board is rather slow.

In this case, we have a fast CPU, but with rather slow storage. Therefore, the time taken to copy the kernel from storage to RAM is expected to have a significant impact on boot time.

This case typically represents todays multimedia and mobile devices such as phones, media players and tablets.

Compression Size Loading time Uncompressing time Total time
gzip 3355768 2.213376 0.501500 2.714876
lzma 2488144 1.647410 1.399552 3.046962
xz 2366192 1.566978 1.299516 2.866494
lzo 3697840 2.471497 0.160596 2.632093
None 6965644 4.626749 0 4.626749

Results on Calao Systems USB-A9263 (AT91)

The USB-A9263 board from Calao Systems has a cheaper and much slower AT91SAM9263 CPU running at 200 MHz.

Here we are booting from NAND flash, which is the fastest way to boot a kernel on this board. Note that we are using the nboot command from U-boot, which guarantees that we just copy the number of bytes specified in the uImage header.

In this case, we have a slow CPU with slow storage. Therefore, we expect both the kernel size and the decompression algorithm to have a major impact on boot time.

This case is a typical example of industrial systems (AT91SAM9263 is still very popular in such applications, as we can see from customer requests), booting from NAND storage operating with a 200 to 400 MHz CPU.

Compression Size Loading time Uncompressing time Total time
gzip 2386936 5.843289 0.935495 6.778784
lzma 1794344 4.465542 6.513644 10.979186
xz 1725360 4.308605 4.816191 9.124796
lzo 2608624 6.351539 0.447336 6.798875
None 4647908 11.080560 0 11.080560

Lessons learned

Here’s what we learned from these benchmarks:

  • lzo is still the best solution for minimum boot time. Remember, lzo kernel compression was merged by Free Electrons.
  • xz is always better than lzma, both in terms of image size. Therefore, there’s no reason to stick to lzma compression if you used it.
  • Because of their heavy CPU usage, lzma and xz remain pretty bad in terms of boot time, on most types of storage devices. On systems with a fast CPU, and very slow storage though, xz should be the best solution
  • On systems with a fast CPU, like the Panda board, boot time with xz is actually pretty close to lzo, and therefore can be a very interesting compromise between kernel size and boot time.
  • Using a kernel image without compression is rarely a worthy solution, except in systems with a very slow CPU. This is the case of CPUs emulated on an FPGA (typically during chip development, before silicon is available). In this particular case, copying to memory is directly done by the emulator, and we just need CPU cycles to start the kernel.

Building a small Debian root filesystem with Multistrap

There are several ways to build a root filesystem for an embedded Linux system: Buildroot and Open Embedded are the usual solutions to do this. They allow to fine tune the contents of your filesystem. The drawback is, in both cases, that you need to build everything from sources and this can take from tens of minutes to several hours.

Sometimes you don’t need all this flexibility and you just want to have a ready-to-use root filesystem, to which you just add a few extra programs. In this case using a distribution is a good solution. So let’s see what we need:

  • A binary distribution
  • Available on several architectures
  • Ability to generate a “small” root filesystem
  • A large choice of packages

Oh, I think it is a pretty good description of Debian!

Emdebian is a project to adapt Debian to embedded devices. A good description from the Debian wiki is:

“In short, what EmDebian does is wrap around the regular Debian package building tools to provide a more fine grained control over package selection, size, dependencies and content to enable creation of very small and efficient Debian packages for use on naturally resource limited embedded targets.”

And so, pretty recently (2009), Emdebian released Multistrap which is similar to Debootstrap but more appropriate for embedded devices. It seems better by the way it builds a system:

It works in a completely different way by simply using apt and dpkg, rather than avoiding to use them, which is how Debootstrap works.

And also more appropriate by its goals:

It is focused on producing rootfs images for devices, as opposed to chroots for existing machines

Practical case: build a root filesystem for the USB A9263 board from Calao Systems (arm926ejs based board).

A drawback of Multistrap is its limitation to Debian, but in fact it is also usable on any distribution based on Debian. In our case, we ran it on an Ubuntu 10.04 system.

First, let’s install Multistrap:

$sudo apt-get install multistrap dpkg-dev

Multistrap needs a config file. For our needs we just use the example one given by Embedian. Let’s name it multistrap.conf:


# space separated package list

Grip is the name of the lightweight Debian distro built by Emdebian.

Now we can run Multistrap:

$ multistrap -a armel -d $PWD/RFS -f multistrap.conf
em_multistrap 0.0.8 using multistrap.conf
Using foreign architecture: armel
em_multistrap building armel multistrap on 'amd64'
INF: Setting ./lib64 -> ./lib symbolic link.
Getting package lists: apt-get  -o Apt::Architecture=armel -o Apt::Get::AllowUnauthenticated=true -o Apt::Get::Download-Only=true -o Apt::Install-Recommends=false -o Dir=/home/mike/celf/multistrap/RFS/ -o Dir::Etc=/home/mike/celf/multistrap/RFS/etc/apt/ -o Dir::Etc::SourceList=/home/mike/celf/multistrap/RFS/etc/apt/sources.list.d/multistrap.sources.list -o Dir::State=/home/mike/celf/multistrap/RFS/var/lib/apt/ -o Dir::State::Status=/home/mike/celf/multistrap/RFS/var/lib/dpkg/status -o Dir::Cache=/home/mike/celf/multistrap/RFS/var/cache/apt/ update
Get:1 http://www.emdebian.org lenny Release.gpg [197B]
Ign http://www.emdebian.org/grip/ lenny/main Translation-en_US
Get:2 http://www.emdebian.org lenny Release [21.4kB]
Ign http://www.emdebian.org lenny Release
Ign http://www.emdebian.org lenny/main Packages
Ign http://www.emdebian.org lenny/main Sources
Ign http://www.emdebian.org lenny/main Packages
Ign http://www.emdebian.org lenny/main Sources
Get:3 http://www.emdebian.org lenny/main Packages [293kB]
Get:4 http://www.emdebian.org lenny/main Sources [351kB]
Fetched 665kB in 0s (6,280kB/s)                     
Reading package lists... Done
W: GPG error: http://www.emdebian.org lenny Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B5B7720097BB3B58
W: Duplicate sources.list entry http://www.emdebian.org/grip/ lenny/main Packages (/home/mike/celf/multistrap/RFS/var/lib/apt/lists/www.emdebian.org_grip_dists_lenny_main_binary-armel_Packages)
Use of uninitialized value within %packages in join or string at /usr/sbin/em_multistrap line 294.
Use of uninitialized value within %keyrings in join or string at /usr/sbin/em_multistrap line 296.
apt-get -y  -o Apt::Architecture=armel -o Apt::Get::AllowUnauthenticated=true -o Apt::Get::Download-Only=true -o Apt::Install-Recommends=false -o Dir=/home/mike/celf/multistrap/RFS/ -o Dir::Etc=/home/mike/celf/multistrap/RFS/etc/apt/ -o Dir::Etc::SourceList=/home/mike/celf/multistrap/RFS/etc/apt/sources.list.d/multistrap.sources.list -o Dir::State=/home/mike/celf/multistrap/RFS/var/lib/apt/ -o Dir::State::Status=/home/mike/celf/multistrap/RFS/var/lib/dpkg/status -o Dir::Cache=/home/mike/celf/multistrap/RFS/var/cache/apt/ install balloon3-config base-files base-passwd bash bsdutils coreutils debianutils diff dpkg e2fslibs e2fsprogs findutils gcc-4.3-base grep grip-config gzip hostname initscripts libacl1 libattr1 libblkid1 libc6 libcap1 libcomerr2 libdevmapper1.02.1 libgcc1 liblocale-gettext-perl libncurses5 libpam-modules libpam-runtime libpam0g libselinux1 libsepol1 libslang2 libss2 libstdc++6 libtext-charwidth-perl libtext-iconv-perl libtext-wrapi18n-perl libuuid1 libvolume-id0 login lsb-base makedev mawk mktemp mount ncurses-base ncurses-bin passwd perl-base procps sed sysv-rc sysvinit sysvinit-utils tar tzdata util-linux zlib1g
Reading package lists... Done
Building dependency tree... Done
The following extra packages will be installed:
  apt debconf debconf-i18n debian-archive-keyring dhcp3-client dhcp3-common gnupg gpgv ifupdown libbz2-1.0 libdb4.6 libncursesw5 libnewt0.52 libpopt0
  libreadline5 libssl0.9.8 libusb-0.1-4 lzma module-init-tools nano net-tools netbase ntpdate readline-common udev wget whiptail
The following NEW packages will be installed:
  apt balloon3-config base-files base-passwd bash bsdutils coreutils debconf debconf-i18n debian-archive-keyring debianutils dhcp3-client dhcp3-common diff
  dpkg e2fslibs e2fsprogs findutils gcc-4.3-base gnupg gpgv grep grip-config gzip hostname ifupdown initscripts libacl1 libattr1 libblkid1 libbz2-1.0 libc6
  libcap1 libcomerr2 libdb4.6 libdevmapper1.02.1 libgcc1 liblocale-gettext-perl libncurses5 libncursesw5 libnewt0.52 libpam-modules libpam-runtime libpam0g
  libpopt0 libreadline5 libselinux1 libsepol1 libslang2 libss2 libssl0.9.8 libstdc++6 libtext-charwidth-perl libtext-iconv-perl libtext-wrapi18n-perl
  libusb-0.1-4 libuuid1 libvolume-id0 login lsb-base lzma makedev mawk mktemp module-init-tools mount nano ncurses-base ncurses-bin net-tools netbase
  ntpdate passwd perl-base procps readline-common sed sysv-rc sysvinit sysvinit-utils tar tzdata udev util-linux wget whiptail zlib1g
0 upgraded, 87 newly installed, 0 to remove and 0 not upgraded.
Need to get 15.4MB of archives.
After this operation, 48.4MB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  libstdc++6 libbz2-1.0 readline-common libncurses5 libreadline5 libusb-0.1-4 zlib1g gpgv gnupg debian-archive-keyring apt debianutils dhcp3-common
  libattr1 libacl1 libselinux1 coreutils lzma dpkg perl-base liblocale-gettext-perl libtext-iconv-perl libtext-charwidth-perl libtext-wrapi18n-perl
  debconf-i18n debconf dhcp3-client sed ncurses-bin lsb-base module-init-tools libssl0.9.8 wget hostname net-tools ifupdown mawk libncursesw5 nano netbase
  libcap1 ntpdate libpam-runtime libpam0g libdb4.6 libpam-modules passwd libvolume-id0 udev libslang2 libnewt0.52 libpopt0 whiptail grip-config
  gcc-4.3-base libgcc1 libc6 base-passwd base-files bash diff libcomerr2 e2fslibs libuuid1 libblkid1 libss2 e2fsprogs findutils grep gzip login mktemp
  mount libsepol1 sysvinit-utils initscripts sysv-rc sysvinit tar tzdata util-linux balloon3-config bsdutils libdevmapper1.02.1 makedev ncurses-base procps
Authentication warning overridden.
Get:1 http://www.emdebian.org/grip/ lenny/main libstdc++6 4.3.2-1.1em1 [268kB]
Get:2 http://www.emdebian.org/grip/ lenny/main libbz2-1.0 1.0.5-1em1 [37.2kB]
Get:3 http://www.emdebian.org/grip/ lenny/main readline-common 5.2-3.1em1 [3,202B]
Get:4 http://www.emdebian.org/grip/ lenny/main libncurses5 5.7+20081213-1em1 [165kB]
Get:5 http://www.emdebian.org/grip/ lenny/main libreadline5 5.2-3.1em1 [108kB]
Get:6 http://www.emdebian.org/grip/ lenny/main libusb-0.1-4 2:0.1.12-13em1 [13.7kB]
Get:7 http://www.emdebian.org/grip/ lenny/main zlib1g 1: [48.1kB]
Get:8 http://www.emdebian.org/grip/ lenny/main gpgv 1.4.9-3+lenny1em1 [139kB]
Get:9 http://www.emdebian.org/grip/ lenny/main gnupg 1.4.9-3+lenny1em1 [533kB]
Get:10 http://www.emdebian.org/grip/ lenny/main debian-archive-keyring 2010.08.28~lenny1em1 [17.9kB]
Get:11 http://www.emdebian.org/grip/ lenny/main apt [514kB]
Get:12 http://www.emdebian.org/grip/ lenny/main debianutils 2.30em1 [23.4kB]
Get:13 http://www.emdebian.org/grip/ lenny/main dhcp3-common 3.1.1-6+lenny4em1 [157kB]
Get:14 http://www.emdebian.org/grip/ lenny/main libattr1 1:2.4.43-2em1 [7,706B]
Get:15 http://www.emdebian.org/grip/ lenny/main libacl1 2.2.47-2em1 [14.0kB]
Get:16 http://www.emdebian.org/grip/ lenny/main libselinux1 2.0.65-5em1 [50.0kB]
Get:17 http://www.emdebian.org/grip/ lenny/main coreutils 6.10-6em1 [1,162kB]
Get:18 http://www.emdebian.org/grip/ lenny/main lzma 4.43-14em1 [51.0kB]
Get:19 http://www.emdebian.org/grip/ lenny/main dpkg 1.14.29em1 [405kB]
Get:20 http://www.emdebian.org/grip/ lenny/main perl-base 5.10.0-19lenny2em1 [905kB]
Get:21 http://www.emdebian.org/grip/ lenny/main liblocale-gettext-perl 1.05-4em1 [11.0kB]
Get:22 http://www.emdebian.org/grip/ lenny/main libtext-iconv-perl 1.7-1+b1em1 [11.2kB]
Get:23 http://www.emdebian.org/grip/ lenny/main libtext-charwidth-perl 0.04-5+b1em1 [6,656B]
Get:24 http://www.emdebian.org/grip/ lenny/main libtext-wrapi18n-perl 0.06-6em1 [4,444B]
Get:25 http://www.emdebian.org/grip/ lenny/main debconf-i18n 1.5.24em1 [2,882B]
Get:26 http://www.emdebian.org/grip/ lenny/main debconf 1.5.24em1 [110kB]
Get:27 http://www.emdebian.org/grip/ lenny/main dhcp3-client 3.1.1-6+lenny4em1 [185kB]
Get:28 http://www.emdebian.org/grip/ lenny/main sed 4.1.5-6em1 [23.8kB]
Get:29 http://www.emdebian.org/grip/ lenny/main ncurses-bin 5.7+20081213-1em1 [70.8kB]
Get:30 http://www.emdebian.org/grip/ lenny/main lsb-base 3.2-20em1 [5,888B]
Get:31 http://www.emdebian.org/grip/ lenny/main module-init-tools 3.4-1em1 [44.5kB]
Get:32 http://www.emdebian.org/grip/ lenny/main libssl0.9.8 0.9.8g-15+lenny8em1 [713kB]
Get:33 http://www.emdebian.org/grip/ lenny/main wget 1.11.4-2+lenny2em1 [116kB]
Get:34 http://www.emdebian.org/grip/ lenny/main hostname 2.95em1 [5,808B]
Get:35 http://www.emdebian.org/grip/ lenny/main net-tools 1.60-22em1 [156kB]
Get:36 http://www.emdebian.org/grip/ lenny/main ifupdown 0.6.8+nmu1em1 [18.9kB]
Get:37 http://www.emdebian.org/grip/ lenny/main mawk 1.3.3-11.1em1 [51.2kB]
Get:38 http://www.emdebian.org/grip/ lenny/main libncursesw5 5.7+20081213-1em1 [187kB]
Get:39 http://www.emdebian.org/grip/ lenny/main nano 2.0.7-5em1 [83.6kB]
Get:40 http://www.emdebian.org/grip/ lenny/main netbase 4.34em1 [11.6kB]
Get:41 http://www.emdebian.org/grip/ lenny/main libcap1 1:1.10-14em1 [7,574B]
Get:42 http://www.emdebian.org/grip/ lenny/main ntpdate 1:4.2.4p4+dfsg-8lenny3em1 [36.1kB]
Get:43 http://www.emdebian.org/grip/ lenny/main libpam-runtime 1.0.1-5+lenny1em1 [7,786B]
Get:44 http://www.emdebian.org/grip/ lenny/main libpam0g 1.0.1-5+lenny1em1 [41.0kB]
Get:45 http://www.emdebian.org/grip/ lenny/main libdb4.6 4.6.21-11em1 [531kB]
Get:46 http://www.emdebian.org/grip/ lenny/main libpam-modules 1.0.1-5+lenny1em1 [160kB]
Get:47 http://www.emdebian.org/grip/ lenny/main passwd 1:4.1.1-6+lenny1em1 [267kB]
Get:48 http://www.emdebian.org/grip/ lenny/main libvolume-id0 0.125-7+lenny3em1 [18.2kB]
Get:49 http://www.emdebian.org/grip/ lenny/main udev 0.125-7+lenny3em1 [145kB]
Get:50 http://www.emdebian.org/grip/ lenny/main libslang2 2.1.3-3em1 [266kB]
Get:51 http://www.emdebian.org/grip/ lenny/main libnewt0.52 0.52.2-11.3+lenny1em1 [36.7kB]
Get:52 http://www.emdebian.org/grip/ lenny/main libpopt0 1.14-4em1 [22.3kB]
Get:53 http://www.emdebian.org/grip/ lenny/main whiptail 0.52.2-11.3+lenny1em1 [11.7kB]
Get:54 http://www.emdebian.org/grip/ lenny/main grip-config 0.1.2em1 [11.5kB]
Get:55 http://www.emdebian.org/grip/ lenny/main gcc-4.3-base 4.3.2-1.1em1 [5,496B]
Get:56 http://www.emdebian.org/grip/ lenny/main libgcc1 1:4.3.2-1.1em1 [23.7kB]
Get:57 http://www.emdebian.org/grip/ lenny/main libc6 2.7-18lenny4em1 [4,410kB]
Get:58 http://www.emdebian.org/grip/ lenny/main base-passwd 3.5.20em1 [11.5kB]
Get:59 http://www.emdebian.org/grip/ lenny/main base-files 5lenny7em1 [49.2kB]
Get:60 http://www.emdebian.org/grip/ lenny/main bash 3.2-4em1 [364kB]
Get:61 http://www.emdebian.org/grip/ lenny/main diff 2.8.1-12em1 [59.6kB]
Get:62 http://www.emdebian.org/grip/ lenny/main libcomerr2 1.41.3-1em1 [6,366B]
Get:63 http://www.emdebian.org/grip/ lenny/main e2fslibs 1.41.3-1em1 [91.3kB]
Get:64 http://www.emdebian.org/grip/ lenny/main libuuid1 1.41.3-1em1 [10.8kB]
Get:65 http://www.emdebian.org/grip/ lenny/main libblkid1 1.41.3-1em1 [21.6kB]
Get:66 http://www.emdebian.org/grip/ lenny/main libss2 1.41.3-1em1 [10.9kB]
Get:67 http://www.emdebian.org/grip/ lenny/main e2fsprogs 1.41.3-1em1 [234kB]
Get:68 http://www.emdebian.org/grip/ lenny/main findutils 4.4.0-2em1 [160kB]
Get:69 http://www.emdebian.org/grip/ lenny/main grep 2.5.3~dfsg-6em1 [128kB]
Get:70 http://www.emdebian.org/grip/ lenny/main gzip 1.3.12-6+lenny1em1 [44.0kB]
Get:71 http://www.emdebian.org/grip/ lenny/main login 1:4.1.1-6+lenny1em1 [50.6kB]
Get:72 http://www.emdebian.org/grip/ lenny/main mktemp 1.5-9em1 [5,772B]
Get:73 http://www.emdebian.org/grip/ lenny/main mount [69.3kB]
Get:74 http://www.emdebian.org/grip/ lenny/main libsepol1 2.0.30-2em1 [96.4kB]
Get:75 http://www.emdebian.org/grip/ lenny/main sysvinit-utils 2.86.ds1-61em1 [17.8kB]
Get:76 http://www.emdebian.org/grip/ lenny/main initscripts 2.86.ds1-61em1 [33.6kB]
Get:77 http://www.emdebian.org/grip/ lenny/main sysv-rc 2.86.ds1-61em1 [13.7kB]
Get:78 http://www.emdebian.org/grip/ lenny/main sysvinit 2.86.ds1-61em1 [46.8kB]
Get:79 http://www.emdebian.org/grip/ lenny/main tar 1.20-1+lenny1em1 [148kB]
Get:80 http://www.emdebian.org/grip/ lenny/main tzdata 2010j-0lenny1em1 [749kB]
Get:81 http://www.emdebian.org/grip/ lenny/main util-linux [293kB]
Get:82 http://www.emdebian.org/grip/ lenny/main balloon3-config 0.6 [2,400B]
Get:83 http://www.emdebian.org/grip/ lenny/main bsdutils 1: [17.0kB]
Get:84 http://www.emdebian.org/grip/ lenny/main libdevmapper1.02.1 2:1.02.27-4em1 [44.1kB]
Get:85 http://www.emdebian.org/grip/ lenny/main makedev 2.3.1-88em1 [15.8kB]
Get:86 http://www.emdebian.org/grip/ lenny/main ncurses-base 5.7+20081213-1em1 [16.4kB]
Get:87 http://www.emdebian.org/grip/ lenny/main procps 1:3.2.7-11em1 [160kB]
Fetched 15.4MB in 3s (4,819kB/s)
Download complete and in download only mode
I: Calculating obsolete packages
I: Extracting apt_0.7.20.2+lenny2em1_armel.deb...
 -> Processing conffiles for apt
I: Extracting balloon3-config_0.6_all.deb...
I: Extracting base-files_5lenny7em1_armel.deb...
 -> Processing conffiles for base-files
I: Extracting base-passwd_3.5.20em1_armel.deb...
I: Extracting bash_3.2-4em1_armel.deb...
 -> Processing conffiles for bash
I: Extracting bsdutils_1%3a2.13.1.1-1em1_armel.deb...
I: Extracting coreutils_6.10-6em1_armel.deb...
I: Extracting debconf-i18n_1.5.24em1_all.deb...
I: Extracting debconf_1.5.24em1_all.deb...
 -> Processing conffiles for debconf
I: Extracting debian-archive-keyring_2010.08.28~lenny1em1_all.deb...
I: Extracting debianutils_2.30em1_armel.deb...
I: Extracting dhcp3-client_3.1.1-6+lenny4em1_armel.deb...
 -> Processing conffiles for dhcp3-client
I: Extracting dhcp3-common_3.1.1-6+lenny4em1_armel.deb...
I: Extracting diff_2.8.1-12em1_armel.deb...
I: Extracting dpkg_1.14.29em1_armel.deb...
 -> Processing conffiles for dpkg
I: Extracting e2fslibs_1.41.3-1em1_armel.deb...
I: Extracting e2fsprogs_1.41.3-1em1_armel.deb...
 -> Processing conffiles for e2fsprogs
I: Extracting findutils_4.4.0-2em1_armel.deb...
I: Extracting gcc-4.3-base_4.3.2-1.1em1_armel.deb...
I: Extracting gnupg_1.4.9-3+lenny1em1_armel.deb...
I: Extracting gpgv_1.4.9-3+lenny1em1_armel.deb...
I: Extracting grep_2.5.3~dfsg-6em1_armel.deb...
I: Extracting grip-config_0.1.2em1_all.deb...
I: Extracting gzip_1.3.12-6+lenny1em1_armel.deb...
I: Extracting hostname_2.95em1_armel.deb...
I: Extracting ifupdown_0.6.8+nmu1em1_armel.deb...
 -> Processing conffiles for ifupdown
I: Extracting initscripts_2.86.ds1-61em1_armel.deb...
 -> Processing conffiles for initscripts
I: Extracting libacl1_2.2.47-2em1_armel.deb...
I: Extracting libattr1_1%3a2.4.43-2em1_armel.deb...
I: Extracting libblkid1_1.41.3-1em1_armel.deb...
I: Extracting libbz2-1.0_1.0.5-1em1_armel.deb...
I: Extracting libc6_2.7-18lenny4em1_armel.deb...
 -> Processing conffiles for libc6
I: Extracting libcap1_1%3a1.10-14em1_armel.deb...
I: Extracting libcomerr2_1.41.3-1em1_armel.deb...
I: Extracting libdb4.6_4.6.21-11em1_armel.deb...
I: Extracting libdevmapper1.02.1_2%3a1.02.27-4em1_armel.deb...
I: Extracting libgcc1_1%3a4.3.2-1.1em1_armel.deb...
I: Extracting liblocale-gettext-perl_1.05-4em1_armel.deb...
I: Extracting libncurses5_5.7+20081213-1em1_armel.deb...
I: Extracting libncursesw5_5.7+20081213-1em1_armel.deb...
I: Extracting libnewt0.52_0.52.2-11.3+lenny1em1_armel.deb...
I: Extracting libpam-modules_1.0.1-5+lenny1em1_armel.deb...
 -> Processing conffiles for libpam-modules
I: Extracting libpam-runtime_1.0.1-5+lenny1em1_all.deb...
 -> Processing conffiles for libpam-runtime
I: Extracting libpam0g_1.0.1-5+lenny1em1_armel.deb...
I: Extracting libpopt0_1.14-4em1_armel.deb...
I: Extracting libreadline5_5.2-3.1em1_armel.deb...
I: Extracting libselinux1_2.0.65-5em1_armel.deb...
I: Extracting libsepol1_2.0.30-2em1_armel.deb...
I: Extracting libslang2_2.1.3-3em1_armel.deb...
I: Extracting libss2_1.41.3-1em1_armel.deb...
I: Extracting libssl0.9.8_0.9.8g-15+lenny8em1_armel.deb...
I: Extracting libstdc++6_4.3.2-1.1em1_armel.deb...
I: Extracting libtext-charwidth-perl_0.04-5+b1em1_armel.deb...
I: Extracting libtext-iconv-perl_1.7-1+b1em1_armel.deb...
I: Extracting libtext-wrapi18n-perl_0.06-6em1_all.deb...
I: Extracting libusb-0.1-4_2%3a0.1.12-13em1_armel.deb...
I: Extracting libuuid1_1.41.3-1em1_armel.deb...
I: Extracting libvolume-id0_0.125-7+lenny3em1_armel.deb...
I: Extracting login_1%3a4.1.1-6+lenny1em1_armel.deb...
 -> Processing conffiles for login
I: Extracting lsb-base_3.2-20em1_all.deb...
I: Extracting lzma_4.43-14em1_armel.deb...
I: Extracting makedev_2.3.1-88em1_all.deb...
I: Extracting mawk_1.3.3-11.1em1_armel.deb...
I: Extracting mktemp_1.5-9em1_armel.deb...
I: Extracting module-init-tools_3.4-1em1_armel.deb...
 -> Processing conffiles for module-init-tools
I: Extracting mount_2.13.1.1-1em1_armel.deb...
I: Extracting nano_2.0.7-5em1_armel.deb...
 -> Processing conffiles for nano
I: Extracting ncurses-base_5.7+20081213-1em1_all.deb...
 -> Processing conffiles for ncurses-base
I: Extracting ncurses-bin_5.7+20081213-1em1_armel.deb...
I: Extracting net-tools_1.60-22em1_armel.deb...
I: Extracting netbase_4.34em1_all.deb...
 -> Processing conffiles for netbase
I: Extracting ntpdate_1%3a4.2.4p4+dfsg-8lenny3em1_armel.deb...
 -> Processing conffiles for ntpdate
I: Extracting passwd_1%3a4.1.1-6+lenny1em1_armel.deb...
 -> Processing conffiles for passwd
I: Extracting perl-base_5.10.0-19lenny2em1_armel.deb...
I: Extracting procps_1%3a3.2.7-11em1_armel.deb...
 -> Processing conffiles for procps
I: Extracting readline-common_5.2-3.1em1_all.deb...
I: Extracting sed_4.1.5-6em1_armel.deb...
I: Extracting sysv-rc_2.86.ds1-61em1_all.deb...
I: Extracting sysvinit-utils_2.86.ds1-61em1_armel.deb...
I: Extracting sysvinit_2.86.ds1-61em1_armel.deb...
I: Extracting tar_1.20-1+lenny1em1_armel.deb...
 -> Processing conffiles for tar
I: Extracting tzdata_2010j-0lenny1em1_all.deb...
I: Extracting udev_0.125-7+lenny3em1_armel.deb...
 -> Processing conffiles for udev
I: Extracting util-linux_2.13.1.1-1em1_armel.deb...
 -> Processing conffiles for util-linux
I: Extracting wget_1.11.4-2+lenny2em1_armel.deb...
 -> Processing conffiles for wget
I: Extracting whiptail_0.52.2-11.3+lenny1em1_armel.deb...
I: Extracting zlib1g_1%3a1.2.3.3.dfsg-12em1_armel.deb...
I: Unpacking complete.
Get:1 http://www.emdebian.org lenny Release.gpg [197B]
Ign http://www.emdebian.org/grip/ lenny/main Translation-en_US
Get:2 http://www.emdebian.org lenny Release [21.4kB]
Ign http://www.emdebian.org lenny Release
Ign http://www.emdebian.org lenny/main Packages
Ign http://www.emdebian.org lenny/main Sources
Ign http://www.emdebian.org lenny/main Packages
Ign http://www.emdebian.org lenny/main Sources
Hit http://www.emdebian.org lenny/main Packages
Hit http://www.emdebian.org lenny/main Sources
Fetched 198B in 0s (2,020B/s)
Reading package lists... Done
W: GPG error: http://www.emdebian.org lenny Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B5B7720097BB3B58

Multistrap system installed successfully in /home/mike/celf/multistrap/RFS/.

Let’s explain the parameters:

  • armel is the architecture, for our example: arm in little endian
  • -d $PWD/RFS is the output directory containing the root filesystem. Be careful to pass an absolute path.
  • -f multistrap.conf is the name of the configuration file

If you look at RFS/dev, you will see that there are no device files in it. This will be a problem at boot time, unless you build a kernel with the below options:


Thanks to these parameters, the kernel will automatically mount a tmpfs filesystem on /dev, and will populate it with devices present on the system.

Now we have a root filesystem, but we still need to run the package configuration scripts to make it usable. The packages were installed, but their configuration scripts couldn’t be executed, because they can only run on the target architecture.

The easiest way to do this is to use NFS. On the host side, you need to export the root filesystem directory through NFS. On the target side you have to select /bin/sh for the init process. A typical kernel command could be:

console=ttyS0,115200 root=/dev/nfs nfsroot= rw ip= init=/bin/sh

Then boot your board. You should reach a command line.

First mount /proc:

mount -t proc nodev /proc

Then configure your packages using this command line:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin  dpkg --configure -a 

You will get a few questions about localization for tzdata, then the packages will be configured.

Finally go back to your host to change the RFS/etc/inittab file by uncommenting the below line and modifying it according to your serial console configuration (usually 115200). For example, replace

#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100


T0:23:respawn:/sbin/getty -L ttyS0 115200 vt100

As we built this root filesystem as a normal user we may have problems with some setuid programs, which need to be owned by the root user. So let’s change the ownership of some directories:

sudo chown root:root -R RFS/bin RFS/usr/bin RFS/sbin RFS/usr/sbin

The last trick is to delete the root password by modifying RFS/etc/passwd, by replacing




You can now reboot your system without the init=/bin/sh kernel parameter. We now have a ready to use embedded Linux root filesystem with the power of Debian.

Other things to fix and do:

  • Configure the /etc/resolv.conf file to be able to connect to the Internet.
  • Configure the gateway in the ip= kernel parameter (ip=client-ip:server-ip:gw-ip:netmask:hostname:device:autoconf). For example:
    bootargs=console=ttyS0,115200n8 root=/dev/nfs ip= nfsroot=
  • Install other packages such as mtd-utils and vim
  • Install kernel modules (either manually or through a kernel package)
  • Add a new user
  • Create a minimum /etc/fstab file

You now have a Debian system for which it is very easy to add new software, and which can be configured in a very familiar way. That’s great to make product prototypes, small, low-power and secure servers for home or office use, and in some cases, even real products.

Snowball, a new community Linux development platform

Snowball platformThe success of the BeagleBoard platform, a low-cost development platform, that has greatly contributed to the success of Texas Instruments OMAP3 processor in the embedded Linux industry, seems to have inspired another processor manufacturer: ST Ericsson. They have recently unveiled Snowball, a low-cost development platform for their AP9500 processor, which features a dual Cortex A-9 ARM core and a Mali 400 GPU.

The development board is designed and produced by our partner Calao Systems, and offers the following features:

  • The AP9500 processor, dual Cortex-A9 and Mali 400 GPU
  • 4 to 8 GB of e-MMC storage
  • 1 GB of LP-DDR2 RAM
  • Micro-SD slot
  • Ethernet connector, Wifi and Bluetooth
  • HDMI output, composite video output
  • Audio in/out
  • USB On The Go
  • Battery charger
  • On-board battery to keep time
  • Serial port connector, JTAG connector, MiPi 34 debug connector
  • Builtin GPS
  • 3-axis accelerometer, magnetometer and gyrometer, one pressure sensor
  • Expansion connectors to access SPI, I2C, LCD, MiPi devices, GPIO, UART, etc.
  • Last but not least, the board can be powered via USB (through a regular cable or through a Y one if power hungry devices like Wifi are used.)

The technical documentation page has a few more details, but at this time, they isn’t a lot of public information available about the AP9500 processor. I hope that ST Ericsson will fully understand how open source works and will soon release datasheets for the AP9500 in an open way. Interestingly, the AP9500 does not use the traditional PowerVR SGX 3D graphics core designed by Imagination Technologies and found in many other ARM processors, but instead uses the Mali graphics core, which is designed directly by ARM. It seems ARM has already open-sourced the kernel side bits of their graphic drivers, but it looks like a proprietary binary blob in userspace is still present.

The board will be available in two variants:

  • A Product Development Kit variant for 241 Euros.
  • A Software Development Kit variant for 165 Euros. My understanding is that the only difference between the two are the expansion connectors, present on the PDK variant but not on the SDK variant.

The board should be widely available at the end of Q2 2011, i.e around June, though at Free Electrons, we will receive our first samples by the end of March thanks to our partnership with Calao Systems. The Snowball platform is supported by the Igloo Community, which hosts mailing-lists, an IRC channel, documentation and will also provide Meego and Android builds for the Snowball in the future.

Stay tuned on this blog. As soon as we get our own boards, we will write about our experiments with them.

Linux 2.6.33 features for embedded systems

Interesting features for embedded Linux system developers

Penguin workerLinux 2.6.33 was out on Feb. 24, 2010, and to incite you to try this new kernel in your embedded Linux products, here are features you could be interested in.

The first news is the availability of the LZO algorithm for kernel and initramfs compression. Linux 2.6.30 already introduced LZMA and BZIP2 compression options, which could significantly reduce the size of the kernel and initramfs images, but at the cost of much increased decompression time. LZO compression is a nice alternative. Though its compression rate is not as good as that of ZLIB (10 to 15% larger files), decompression time is much faster than with other algorithms. See our benchmarks. We reduced boot time by 200 ms on our at91 arm system, and the savings could even increase with bigger kernels.

This feature was implemented by my colleague Albin Tonnerre. It is currently available on x86 and arm (commit, commit, commit, commit), and according to Russell King, the arm maintainer, it should become the default compression option on this platform. This compressor can also be used on mips, thanks to Wu Zhangjin (commit).

For systems lacking RAM resources, a new useful feature is Compcache, which allows to swap application memory to a compressed cache in RAM. In practise, this technique increases the amount of RAM that applications can use. This could allow your embedded system or your netbook to run applications or environments it couldn’t execute before. This technique can also be a worthy alternative to on-disk swap in servers or desktops which do need a swap partition, as access performance is much improved. See this LWN.net article for details.

This new kernel also carries lots of improvements on embedded platforms, especially on the popular TI OMAP platform. In particular, we noticed early support to the IGEPv2 board, a very attractive platform based on the TI OMAP 3530 processor, much better than the Beagle Board for a very similar price. We have started to use it in customer projects, and we hope to contribute to its full support in the mainline kernel.

Another interesting feature of Linux 2.6.33 is the improvements in the capabilities of the perf tool. In particular, perf probe allows to insert Kprobes probes through the command line. Instead of SystemTap, which relied on kernel modules, perf probe now relies on a sysfs interface to pass probes to the kernel. This means that you no longer need a compiler and kernel headers to produce your probes. This made it difficult to port SystemTap to embedded platforms. The arm architecture doesn’t have performance counters in the mainline kernel yet (other architectures do), but patches are available. This carries the promise to be able to use probe tools like SystemTap at last on embedded architectures, all the more if SystemTap gets ported to this new infrastructure.

Other noticeable improvements in this release are the ability to mount ext3 and ext2 filesystems with just an ext4 driver, a lightweight RCU implementation, as well as the ability to change the default blinking cursor that is shown at boot time.

Unfortunately, each kernel release doesn’t only carry good news. Android patches got dropped from this release, because of a lack of interest from Google to maintain them. These are sad news and a threat for Android users who may end up without the ability to use newer kernel features and releases. Let’s hope that Google will once more realize the value of converging with the mainline Linux community. I hope that key contributors that this company employs (Andrew Morton in particular) will help to solve this issue.

As usual, this was just a selection. You will probably find many other interesting features on the Linux Changes page for Linux 2.6.33.

Demo: tiny qemu arm system with a DirectFB interface

A tiny embedded Linux system running on the qemu arm emulator, with a DirectFB interface, everything in 2.1 MB (including the kernel)!


This demo embedded Linux system has the following features:

  • Very easy to run demo, just 1 file to download and 1 command line to type!
  • Runs on qemu (easy to get for most GNU/Linux distributions), emulating an ARM Versatile PB board.
  • Available through a single file (kernel and root filesystem), sizing only 2.1 MB!
  • DirectFB graphical user interface.
  • Demonstrates the capabilities of qemu, the Linux kernel, BusyBox, DirectFB, and
    shows the benefits of system size and boot time reduction techniques as advertised and supported by the CE Linux Forum.
  • License: GNU GPL for root filesystem scripts. Each software component has its own license.

How to run the demo

  • Make sure the qemu emulator is installed on your GNU/Linux distribution. The demo works with qemu 0.8.2 and beyond, but it may also work with earlier versions.
  • Download the vmlinuz-qemu-arm-2.6.20
  • Run the below command:
    qemu-system-arm -M versatilepb -m 16 -kernel vmlinuz-qemu-arm-2.6.20 -append "clocksource=pit quiet rw"
  • When you reach the console prompt, you can try regular Unix commands but also the graphical demo:

FAQ / Troubleshooting

  • Q: I get Could not initialize SDL - exiting when I try to run qemu.

    That’s a qemu issue (qemu used the SDL library). Check that you can start graphical applications from your terminal (try xeyes or xterm for example). You may also need to check that you have name servers listed in /etc/resolv.conf. Anyway, you will find solutions for this issue on the Internet.


console screenshot df_andi program screenshot
df_dok program screenshot df_dok2 program screenshot
df_neo program screenshot df_input program screenshot

How to rebuild this demo

All the files needed to rebuild this demo are available here:

  • You can rebuild or upgrade the (Vanilla) kernel by using the given kernel configuration file.
  • The configuration file expects to find an initramfs source directory in ../rootfs, which
    you can create by extracting the contents of the rootfs.tar.7z archive.
  • Of course, you can make changes to this root filesystem!

Tools and optimization techniques used in this demo

Software and development tools

  • The demo was built using Scratchbox, a fantastic development tool that makes cross-compiling transparent!
  • The demo includes BusyBox 1.4.1, an toolbox implementing most UNIX commands in a few hundreds of KB. In our case, BusyBox includes the most common commands (like a vi implementation), and only sizes 192 KB!
  • The root filesystem is shipped within the Linux kernel image, using the initramfs technique, which makes the kernel simpler and saves a dramatic amount of RAM (compared to an init ramdisk).
  • The demo is interfaced by DirectFB example programs (version 0.9.25, with DirectFB 1.0.0-rc4), which demonstrate the amazing capabilities of this library, created to meet the needs of embedded systems.

Size optimization techniques

The below optimization techniques were used to reduce the filesystem size from 74 MB to 3.3 MB (before compression in the Linux kernel image):

  • Removing development files: C headers and manual pages copied when installing tools and libraries, .a library files, gdbserver, strace, /usr/lib/libfakeroot, /usr/local/lib/pkgconfig
  • Files not used by the demo programs: libstdc++, and any library or resource file.
  • Stripping and even super stripping (see sstrip) executables and libraries.
  • Reducing the kernel size using CONFIG_EMBEDDED switches, mainly from the
    Linux Tiny project.

Techniques to reduce boot time

We used the below techniques to reduce boot time:

  • Disabled console output (quiet boot option, printk support was disabled anyway), which saves time scrolling the framebuffer console.
  • Use the Preset Loops per Jiffy technique to disable delay loop calculation, by feeding the kernel with a value measured in an earlier boot (lpj setting, which you may update according to the speed of your own workstation).

All these optimization techniques and other ones we haven’t tried yet are described either on the elinux.org Wiki or in our embedded Linux optimizations presentation.

Future work

We plan to implement a generic tool which would apply some of these techniques in an automatic way, to shrink an existing GNU/Linux or embedded Linux root filesystem without any loss in functionality. More in the next weeks or months!