view www/about.html @ 346:8a71354d8ceb

Added tag 0.4.0 for changeset 1a70dfe0a436
author Rob Landley <>
date Fri, 06 Jun 2008 22:08:56 -0500
parents 7d996cbcc4ac
children d4b89b94e027
line wrap: on
line source

<!--#include file="header.html" -->

<h2>What is Firmware Linux?</h2>

<p>Firmware Linux (FWL) is an embedded Linux build system implemented as a
series of shell scripts.  The full build produces a complete
<a href=downloads/image>bootable linux system</a> (based on uClibc and
BusyBox/toybox) for various hardware platforms (including arm, mips, ppc, x86,
and x86-64).</p>

<p>Firmware Linux is loosely based on <a href=>Linux
From Scratch</a>, stripped down and rebased on busybox and uClibc.</p>

<p>Intermediate stages of the build (such as the cross compiler and the
unpackaged root filesystem directory) may also be useful to Linux developers,
and are also packaged up in the build subdirectory.</p>

<p>The default build provides a native development environment for each target
platform, eliminating the need for cross compiling in favor of
<a href="#native_compiling">native compiling under emulation</a>.</p>


<p>Firmware Linux is licensed under GPL version 2.  This means that the build
scripts are licensed under GPL version 2, and each of the component packages
of the default "mini-native" root filesystem may be redistributed under the
terms of GPLv2 (and in the case of uClibc, LGPLv2).</p>

<p>Adding your own packages to the resulting system is generally "mere
aggregation" (see the last paragraph of section 2), and thus not my
problem.  This license statement is not intended to apply to your packages
as long as they are not derived works of existing GPLv2 code.</p>

<h2>Using the prebuilt binaries</h2>


<p>Each qemu-image tarball contains an ext2 root filesystem image, a kernel
configured to run under qemu, and shell scripts to run the system (in various
modes) under the emulator <a href=>qemu</a>.</p>

<p>To test boot an FWL target system under qemu 0.9.1, download the appropriate
<a href=downloads/image>prebuilt binary tarball</a> for the target you're
interested in, extract it, cd into it, and execute the "./"
script in that directory.</p>

<p>This boots the target Linux system under the emulator, with /dev/console
hooked to the emulator's stdin and stdout.  (I.E. the shell prompt the script
gives you after the boot messages is running in the emulator.)  Type "cat
/proc/cpuinfo" to confirm you're running in the emulator, then play around and
have fun.</p>

<p>The FWL boot script for qemu (/tools/bin/ populates /dev
from sysfs, sets up an emulated (masquerading) network (so you can wget
source packages or talk to <a href="#distcc_trick">distcc</a>), and creates
a few symlinks needed to test build normal software packages (such as making
/lib point to /tools/lib).</p>

<p>For most platforms, exiting the command shell will exit the emulator.
(Some, such as powerpc, don't support this yet.  For those you have to kill
qemu from another window, or exit the xterm.  I'm working on it.)</p>

<p>To use this emulated system as a native build environment, see
<a href="#native_compiling">native compiling</a>.</p>


<p>The cross compiler created during the FWL build is a relocatable C compiler
for the target platform.  To use it on its own, download the appropraite
<a href=downloads/cross-compiler>cross compiler tarball</a> for the host
you're running on and the target you'd like to compile for.  Extract the
compiler tarball and add the cross-compiler-$TARGET/bin directory to your
$PATH, then use $TARGET-gcc as your cross compiler and "$TARGET-" as your CROSS
prefix for packages with cross compiling support.</p>

<p>For example, if you download cross-compiler-armv4l and extract it into
your home directory, set "PATH=~/cross-compiler-armv4l/bin:$PATH",
use armv4l-gcc to build code, and use "CROSS=armv4l-" to set your cross
compiler prefix.</p>

<p>Note that this cross compiler does not support C++.  If you need C++ support,
use the <a href="#native_compiling">native compiling</a> environment.</p>


<p>If you want to run this system on <a href="#real_hardware">real hardware</a>,
you'll generally have to tweak and repackage the root filesystem.  To make this
easier, tarballs of each target's prebuilt root filesystem
<a href=downloads/mini-native>are available</a>.</p>

<p>This root filesystem is a minimal native build environment for the target
platform.  This means it contains a compiler and associated build tools capable
of building a complete new Linux system under itself, although you may have
to bootstrap your way up (I.E. building things like zlib or perl before
building momre complicated packages).</p>

<p>The vast majority of the space taken up by this filesystem is the
development toolchain and associated support files (mostly header files and

<p>If you're doing anything fancy, you'll probably want to rebuild it from

<h2>Building from source</h2>

<p>To build FWL, download the most recent <a href=downloads>source tarball</a>,
extract it, cd into it, and run "./".  This script takes one argument,
which is the target to build for.  Run it with no arguments to see
available targets.  The resulting files are created in the "build" directory,
including all the downloadable tarballs.  (To perform a clean build,
"rm -rf build" and re-run</p>

<p>By default, this Linux system is a <a href=downloads/mini-native>minimal
native build environment</a> for the target platform.  It contains a compiler
and associated build tools capable of building a complete new Linux system under
itself.  This is is to support <a href="#native_compiling">native compiling</a>,
which allows you to build a new (possibly smaller) root filesystem for your

<p>If you don't want to bother with that, set the environment variable
"BUILD_SHORT=1" before running the build to skip building the native
toolchain.  This results in a much, much smaller root filesystem, and also
moves it up out of the /tools directory, but makes adding additional
software to the resulting system much more difficult (as it must be done
via cross compiling).</p>

<p>See <a href="#native_compiling">native compiling under emulation</a>
and <a href="#customize">customizing mini-native</a> for more information.</p>

<h2>How building from source works</h2>

<h3> and</h3>

<p>The script is a simple wrapper which calls the other
scripts in sequence:</p>
<li> $TARGET</li>
<li> $TARGET</li>
<li> $TARGET</li>

<p>Another script,, performs a similar function but builds all
supported targets at once.</p>

<h3>The other scripts</h3>

<li><p><b></b> - Common functions.</p>

<p>This script is not run directly, but is instead included from the other
scripts to set up the build directory and provide common functions like
"setupfor" and "cleanup".  See <a href="#anatomy_of_include">anatomy of</a> for details.</li>

<li><p><b></b> - Download source packages into sources/packages.</p>

<p>This script does not take any arguments, and writes its output into the
sources/packages directory.</p>

<p>This script consists of a list of URLs and associated sha1sum values of all
the source packages used by the build.  It calls the "download" function out
of to wget each package from its source location (or one of the
mirrors listed in the download function) for which the specified sha1sum
doesn't match.  (If a package's sha1sum is set blank, any value is accepted
and the package will only be downloaded if it doesn't exist.)</li>

<p>Re-running this script will re-validate each sha1sum, but won't download
new packages as long as the sha1sums match.  It automatically deletes any files
from sources/packages which are no longer listed in the download script, such
as old package versions.</p>

<li><p><b></b> - Compile various packages to be used during the
build, installing them into build/host.</p>

<p>This script does not take any arguments.  In theory this is an optional
step, and may be omitted.  (In practice, currently needs
User Mode Linux and won't run without it.  See the description of that script
for details.)</p>

<p>The primary purpose of the script is to isolate the build from
dependencies on the host distribution.  It does this by building host versions
of the same command line utilities that will exist in the final mini-native
development environment, and by creating symlinks to the host versions of the
remaining tools (thus enumerating exactly which ones those are).</p>

<p>This allows set the $PATH to point only to the build/host directory,
so no other tools from the host are used.  (In reality, a few such as /bin/bash
are referred to by absolute path, but it's not a big issue.)  This helps to
ensure that the resulting Linux system can rebuild itself under itself,
because it already did.</p>

<p>A secondary purpose of is to build packages (such as distcc
and User Mode Linux) which may not be installed on the host system.</p>

<p>Note that this script no longer attempts to build qemu, due to the
unreasonable requirement of installing gcc 3.x on the host.  The FWL build
scripts do not use qemu (except as an optional test at the end of which is skipped if qemu is not available).  You will need
to install qemu (or find real hardware) to run the resulting images, but they
should build just fine without it.</p>

<p>See <a href="#anatomy_of_host_tools">anatomy of</a> for
more information.</p>

<p>Currently, builds toybox and busybox, and creates symlinks to
the host's compiler toolchain (ar, as, nm, cc, gcc, make, ld), plus a few
utilities that still need to be added to toybox (bzip2, find, install, od,
sort, diff).  Note that until that last category is eliminated, rebuilding the
system under itself requires natively building and installing the bzip2,
coreutils, and diffutils packages as a bootstrapping step.</li>

<li><p><b></b> - Build a cross compiler (binutils, gcc, uClibc,
linux kernel headers, and a wrapper script).

<p>This script takes one argument: the architecture to build for.</p>

<p>Along the way, the build produces a
<a href=downloads/cross-compiler>relocatable cross compiler for the target
hardware</a>.  Additional packages can be added to 

However, cross compiling additional packages is
<a href=/writing/docs/cross-compiling.html>not recommended</a> because
the defaultroot filesystem of the bootable system contains development
tools, and can act as a <a href=downloads/mini-native>native build
environment</a> capable of compiling software on the target.  (To overcome
most of the speed penalty of emulation, use
<a href="#distcc_trick"></a> script.)</p>

<p>Thus the easy way to build software for a target is to compile

To use FWL, download...

<p>This bootable Linux system contains development tools, and can act as a
<a href=downloads/mini-native>minimal native build environment</a>.  If you
run it under an emulator (or on real hardware) you can compile
  Along the way, the build produces a
<a href=downloads/cross-compiler>relocatable cross compiler for the target
hardware</a>, and also a <a href=downloads/mini-native>native build
environment</a> capable of compiling software on the target.</p>

<p>The build system is a series of shell scripts which download, compile,
install, and use the appropriate source packages to generate the output files.
These shell scripts are designed to be easily read and modified.</p>

<p>The system built by these scripts consists of the following source

<li>linux 2.6.25</li>
<li>busybox 1.2.2</li>
<li>uclibc 0.9.29</li>
<li>gcc 4.1.2</li>
<li>binutils 2.17</li>
<li>make 3.81</li>
<li>bash 2.05b</li>

<p>Firmware Linux is licensed under GPL version 2.  Its component packages are
licensed under their respective licenses (mostly GPL and LGPL).</p>

<h2>How do I use it?</h2>

<p><b></b>: Start here.  This is the master script which runs all the
other build stages.  It takes one argument, the platform to build for.  (Run it
with no arguments to see a list of supported platforms.)  The individual stage
scripts can also be run individually, with the same argument as</p>

<p><b></b>: This script checks the sources/packages directory for
source tarballs, and downloads any that are missing or have invalid SHA1
checksums.  It also deletes any old files in sources/packages not used by the
current build version, and populates sources/build-links with
version-independent symlinks for use by later build stages.</p>

<p><b></b>: This script produces a cross compiler for the
indicated target platform.  The working copy is produced in the build
directory, and a copy is saved as "cross-compiler-$ARCH.tar.bz2" for use
outside the build system.  This cross compiler is fully relocatable (using the
wrapper script in sources/toys/gcc-uClibc.c), so and any normal user can
extract it into their home directory, add cross-compiler-$ARCH/bin to their
$PATH, and run $ARCH-gcc to create target binaries.  It contains gcc, binutils,
linux kernel headers, and the uClibc C library.</p>

<p>The cross compiler script also builds squashfs tools, a target platform
emulator (QEMU), and uses the emulator to confirm that the cross compiler
works.  This script can take an optional first argument, <b>--short</b>, to
skip those steps.  This is useful if you want to build several cross compilers
without multiple copies of QEMU.  (The short build will also delete the
build/cross-compiler-$ARCH directory after tarring it up, since the result
isn't usable by later build stages.)</p>

<p><b></b>: This script uses the cross compiler to create
a minimal native build environment for the target platfrom.  This native
environment consists of just seven packages: busybox, uClibc, the linux kernel,
gcc, binutils, make, and bash.  This is a fully self-hosting development
environment, capable of rebuilding itself from source code, organized as a
<a href=>Linux From Scratch</a> /tools
directory.  It also produces a bootable Linux kernel for the target platform,
and packages the /tools directory as a squashfs image for use by QEMU.</p>

<p><b></b>: This script creates an ext2 filesystem image
for use with qemu.  It currently does this using a User Mode Linux image
created by the script.</p>

<p><b>sources/native/</b>: A test script to run inside the native
environment.  Mounts /proc and /sys, populates /dev, switches to a shell with
command history, etc.  (Not quite a substitute for a real init script, but
something to play with.)</p>

<p><b>More to come...</b></p>

<h2><a name="native_compiling">Native compiling under emulation</a></h2>

Why do this?
the distcc trick
hdb for working space.
  Building on nfs sucks rocks.
  Building out of tree with cp -rs

/tools (Linux From Scratch chapter 5). and the /lib symlink.

Deficiencies in the current mini-native filesystem:, bzip2, coreutils, diffutils.

Building glibc is your problem.
  It requires perl.  Statically linking "hello world" is 400k.  It's evil.
  Still, building it natively sucks less than trying to cross compile it.
  Pretty much follow the non-cross Linux From Scratch procedures.

Building a distro:
  Linux From Scratch.
  Gentoo embedded.


<h2><a name="anatomy_of_host_tools">Anatomy of</a></h2>

<p>Currently, builds toybox and busybox 1.2.2.  Eventually,
toybox should completely replace busybox.</p>

<p>It creates symlinks to the host's compiler toolchain, specifically seven
executalbes: ar, as, nm, cc, gcc, make, ld.</p>

<p>It also creates symlinks to a few utilities that need to be added to toybox.
Currently, this list is: bzip2, find, install, od, sort, diff.</p>

<p>Note that until that last category is eliminated, rebuilding the
system under itself requires natively building and installing the bzip2,
coreutils, and diffutils packages as a bootstrapping step.</li>

<h2><a name="customize">Customizing mini-native</a></h2>

<p>If you don't want to build the native toolchain, set the environment
variable "BUILD_SHORT=1" before running the build.  This results in a much, much
smaller root filesystem, and also moves it up out of the /tools directory.
But it eliminates</p>

<p>The default <a href=downloads/mini-native>mini-native</a> root filesystem
is modeled after Linux From Scratch chapter 5.  (This is why it
lives in a <a href=>/tools directory</a>.)</p>

Not in /tools
Adding packages (to the script, without the script)


<h2><a name="real_hardware">Running on real hardware</a></h2>

<p>To run a system on real hardware (not just under an emulator), you need to
do several things:</p>

<li>Figure out how to flash your device (often a jtag with openocd)</li>
<li>Configure and install a bootloader (uboot, apex, etc.)</li>
<li>Build and install a kernel targeted to your hardware (in the kernel source,
see arch/$ARCH/configs for default .config files for various boards)</li>
<li>Package and install the root filesystem appropriately for your system
(ext2, initramfs, jffs2).</li>

<!--#include file="footer.html" -->