Gentoo Logo

Gentoo Embedded Handbook

Content:

  • General Topics
    Embedded fundamentals you need before playing with hardware.
    1. Introduction
      An introduction into the world of embedded, cross-compilers, and dragons.
    2. Creating a Cross-Compiler
      Build a cross-compiler on your machine!
    3. Cross-Compiling With Portage
      Leverage Portage as a cross-compiling package manager.
    4. Cross-Compiling The Kernel
      Cross-compile a kernel for your system with flair!
    5. Compiling with qemu user chroot
      How To compile with QEMU user.
    6. Frequently Asked Questions
      Frequently Asked Questions for Gentoo Embedded.
  • Emulators
    Software emulation of systems can often times be as good (if not better) than the real thing.
    1. Qemu
      A generic and open source machine emulator and virtualizer for x86, x86_64, arm, sparc, powerpc, mips, m68k (coldfire), and superh.
    2. SkyEye
      ARM embedded hardware simulator.
    3. Armulator
      Emulate armnommu/uClinux (no-mmu Linux) in GDB.
    4. Softgun
      ARM software emulator.
    5. Hercules
      Hercules System/370, ESA/390 and zArchitecture Mainframe Emulator.
  • Bootloaders
    From the obscure to the obscene, we'll cover some of the common bootloaders out there and how to get your feet wet with them.
    1. Das U-Boot
      The Universal Bootloader which supports every embedded architecture out there.
    2. NeTTrom
      Simple bootloader on NetWinders.
    3. RedBoot
      Small bootloader based on eCos which supports every embedded architecture out there.
    4. SH-LILO
      Port of LILO to SuperH which tends to be pretty common on that architecture.
  • Boards
    Some boards are fun while others can be a PITA; we'll cover many of the common gotchas with systems out there.
    1. Hammer/Nailboard
      Little-endian armv4l board.
    2. LANTank
      Little-endian SuperH based NAS (using internal IDE) from I-O Data.
    3. NetWinder
      Little-endian ARMv4 based network server from Rebel.
    4. NSLU2
      Big-endian arm based NAS (using external USB) from Linksys.
    5. QNAP TurboStation 109/209/409
      Little-endian ARMv5TE NAS from QNAP.
    6. Marvell Sheevaplug
      Little-endian ARMv5TE from Marvell.
    7. ACME SYSTEMS Netus G20
      Netus G20 (ARMv5TE) from ACME SYSTEMS
    8. Genesi Efika MX
      Little-endian ARMv7-A from Genesi USA.
    9. Pandaboard
      Little-endian ARMv7-A from pandaboard.org.
    10. Trimslice
      Little-endian ARMv7-A from Compulab/trimslice.com.
    11. Beaglebone
      Little-endian ARMv7-A from Beagleboard.org.
    12. BeagleBone Black
      Little-endian ARMv7-A from Beagleboard.org.
  • Beyond
    A handbook can only go so far, so here we list resources to go the distance when we can't get you there.
    1. Communication
      Gentoo Embedded communication channels.
    2. Contributing
      Gentoo Embedded and you: the answer to the ever prevalent "What can I do?" question.
    3. Vendors
      Information specific to vendors who wish to help out.
    4. Further Learning
      External references to help you expand your embedded Linux knowledge.

A. General Topics

1. Introduction

1.a. Overview

Cross development has traditionally been a black art, requiring a lot of research, trial and error, and perseverance. Intrepid developers face a shortage of documentation and the lack of mature, comprehensive open source toolkits for multi-platform cross development. Ongoing work by the Embedded Gentoo project, the Gentoo Toolchain herd, and other contributors is yielding a Gentoo-based development platform that greatly simplifies cross development.

1.b. The Toolchain

The term "toolchain" refers to the collection of packages used to build up a system (the "tools" which are used in the "chain" of events to take some input and produce some output). It is a loose definition in terms of what packages exactly are considered part of the toolchain, but for the sake of keeping things simple, we will consider the components that are needed to compile code into something fun and usable.

Your typical toolchain is therefore composed of the following:

  • binutils - Essential utilities for handling binaries (includes assembler and linker)
  • gcc - The GNU Compiler Collection (the C and C++ compiler)
  • glibc or uclibc or newlib - The system C Library
  • linux-headers - Kernel headers needed by the system C Library
  • gdb - The GNU debugger

All proper Gentoo systems have a toolchain installed as part of the base system. This toolchain is configured to build binaries native to its host platform.

In order to build binaries on the host system for a non-native platform you'll need a special toolchain - a so-called cross toolchain - which can target that particular platform. Gentoo provides a simple but powerful tool called crossdev for this purpose. Crossdev can build and install arbitrary GCC-supported cross toolchains on the host system, and because Gentoo installs toolchain files into target-specific directories the toolchains built by crossdev won't interfere with the host's native toolchain.

1.c. Toolchain Tuples

All toolchains have a prefix (think CHOST). More details on that can be found in the system tuples page.

1.d. Environment Variables

Certain environment variables used by the Gentoo toolchain and Portage can thoroughly confuse developers inexperienced with cross development. The following table explains some tricky variables and provides sample values based on the cross development examples presented in this guide. See More Terminology and Variables for more unusual variables and related concepts.

Variable Meaning When Building Cross-Toolchain Meaning When Building Cross-Binaries
CBUILD Platform you are building on Platform you are building on
CHOST Platform the cross-toolchain will run on Platform the binaries built by cross-toolchain will run on
CTARGET Platform the binaries built by cross-toolchain will run on Platform the binaries built by cross-toolchain will run on. Redundant, but there's no harm in setting this, and a few binaries do like it.
ROOT Path to the virtual root (/) you are installing into
PORTAGE_CONFIGROOT Path to the virtual root (/) portage can find its config files (like /etc/make.conf)

Say we have an AMD64 desktop as our normal Gentoo machine and we have an ARM PDA we wanted to develop for, the above table would look like:

Variable Value For Building Cross-Toolchain Value For Building Cross-Binaries
CBUILD x86_64-pc-linux-gnu x86_64-pc-linux-gnu
CHOST x86_64-pc-linux-gnu arm-unknown-linux-gnu
CTARGET arm-unknown-linux-gnu not set
ROOT not set -- defaults to / /path/where/you/install
PORTAGE_CONFIGROOT not set -- defaults to / /path/where/your/portage/env/for/arm/pda/is

1.e. More Terminology and Variables

canadian cross
The process of building a cross-compiler which will run on a different machine from the one it was compiled on (CBUILD != CHOST && CHOST != CTARGET)
sysroot: system root
The root directory a compiler uses to find its standard headers and libraries
hardfloat
The system has a hardware Floating Point Unit (FPU) to handle floating point math
softfloat
The system lacks a hardware FPU so all floating point operations are approximated with fixed point math
PIE
Position Independent Executable (-fPIE -pie)
PIC
Position Independent Code (-fPIC)
CRT
C RunTime

2. Creating a Cross-Compiler

2.a. Overview

The first thing you should know about building a toolchain is that some versions of toolchain components refuse to work together. Exactly which combinations are problematic is a matter that's constantly in flux as the Portage tree evolves. The only reliable way to determine what works is to run crossdev, adjusting individual component versions as necessary, until crossdev completes the toolchain build successfully. Even then, the cross toolchain may build binaries which break on the target system. Only through trial and error and patience will you arrive at a favorable combination of all factors.

You do not have to worry about the cross-compiler interfering with your native build system. All of the toolchain packages are designed such that they are isolated from each other based on the target. This way you can install cross-compilers for whatever architecture you wish without breaking the rest of your system.

2.b. crossdev

Intro

Generating a cross-compiler by hand is a long and painful process. This is why it has been fully integrated into Gentoo! A frontend called crossdev will run emerge with all of the proper environment variables and install all the right packages to generate arbitrary cross-compilers based on your needs. First you'll need to install crossdev:

Code Listing 2.1: Install crossdev

# emerge crossdev

You'll probably want to install the ~arch keyworded version of crossdev to get all the latest fixes.

Note: If you are upgrading from an older version of crossdev, and have crossdev-wrappers installed, be sure to uninstall crossdev-wrappers first. Your existing cross-toolchains will remain intact.

We only cover the basic usage of crossdev here, but crossdev can customize the process fairly well for most needs. Run crossdev --help to get some ideas on how to use crossdev. Here are a few common uses:

Code Listing 2.2: Useful crossdev options

(Use specific package versions)
# crossdev --g [gcc version] --l [(g)libc version] --b [binutils version] --k [kernel headers version] -P -v -t [tuple]
(Use the stable version only)
# crossdev -S -P -v -t [tuple]

Installing

The first step is to select the proper tuple for your target. Here we will assume you want to build a cross-compiler for the SH4 (SuperH) processor with glibc running on Linux. We will do this on a PowerPC machine.

Code Listing 2.3: Generating SH4 cross-compiler

# crossdev --target sh4-unknown-linux-gnu
-----------------------------------------------------------------------------------------------------
 * Host Portage ARCH:     ppc
 * Target Portage ARCH:   sh
 * Target System:         sh4-unknown-linux-gnu
 * Stage:                 4 (C/C++ compiler)

 * binutils:              binutils-[latest]
 * gcc:                   gcc-[latest]
 * headers:               linux-headers-[latest]
 * libc:                  glibc-[latest]

 * PORTDIR_OVERLAY:       /usr/local/portage
 * PORT_LOGDIR:           /var/log/portage
 * PKGDIR:                /usr/portage/packages/powerpc-unknown-linux-gnu/cross/sh4-unknown-linux-gnu
 * PORTAGE_TMPDIR:        /var/tmp/cross/sh4-unknown-linux-gnu
  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  -  ~  -  _  
 * Forcing the latest versions of {binutils,gcc}-config/gnuconfig ...                          [ ok ]
 * Log: /var/log/portage/cross-sh4-unknown-linux-gnu-binutils.log
 * Emerging cross-binutils ...                                                                 [ ok ]
 * Log: /var/log/portage/cross-sh4-unknown-linux-gnu-gcc-stage1.log
 * Emerging cross-gcc-stage1 ...                                                               [ ok ]
 * Log: /var/log/portage/cross-sh4-unknown-linux-gnu-linux-headers.log
 * Emerging cross-linux-headers ...                                                            [ ok ]
 * Log: /var/log/portage/cross-sh4-unknown-linux-gnu-glibc.log
 * Emerging cross-glibc ...                                                                    [ ok ]
 * Log: /var/log/portage/cross-sh4-unknown-linux-gnu-gcc-stage2.log
 * Emerging cross-gcc-stage2 ...                                                               [ ok ]

Note: At the moment it's not possible to set PORTAGE_CONFIGROOT before calling crossdev to a folder set to the arch you're targetting. You have to use your own config. If you want to use arch specific use flags, like altivec in a non powerpc architecture, you need to unmask the use flag in /usr/portage/base/use.mask, or temporarily change your profile.

Quick Test

If everything goes as planned, you should have a shiny new compiler on your machine. Give it a spin!

Code Listing 2.4: Using SH4 cross-compiler

$ sh4-unknown-linux-gnu-gcc --version
sh4-unknown-linux-gnu-gcc (GCC) 4.2.0 (Gentoo 4.2.0 p1.4)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ echo 'int main(){return 0;}' > sh4-test.c
$ sh4-unknown-linux-gnu-gcc -Wall sh4-test.c -o sh4-test
$ file sh4-test
sh4-test: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), not stripped

If the crossdev command failed, you have the log file which you can review to see if the problem is local. If you're unable to fix the issue, you're welcome to file a bug in our bugzilla. See the Communication page for more information.

Uninstalling

To uninstall a toolchain, simply use the --clean option. If you modified the sysroot by hand, you'll be prompted to delete things inside of it, so you may want to pipe yes | into the command.

Code Listing 2.5: Uninstalling cross-compiler

# crossdev --clean sh4-unknown-linux-gnu

In case you didn't already notice, deleting any and all files in the /usr/CTARGET/ directory is completely safe.

Options

Obviously crossdev can do a lot more, so to find out more, simply run crossdev --help.

2.c. Cross-compiler Internals

Warning: This section is included for posterity and in the hopes that others will find it useful. The target audience is people who (for some stupid reason or another) really really want to create their own cross compiler with binutils/(glibc|uclibc)/gcc all by themselves. This section is not meant to cover/document/whatever the myriad of build failures you are likely to see along the way. If you need such help, see the Beyond section in the handbook for some pointers. You certainly should not bug me or anyone else in Gentoo.

Warning: If you're still reading, you should really check out the crosstool project (refer to the Beyond section) as that provides a distribution independent method for generating cross-compilers. While it does kind of suck (imo), it is certainly the best (and really only) option out there for creating cross-compilers.

Overview

There are generally two ways to build up your cross-compiler. The "accepted" way, and the cheater's shortcut.

The current "accepted" way is:

  1. binutils
  2. kernel headers
  3. libc headers
  4. gcc stage1 (c-only)
  5. libc
  6. gcc stage2 (c/c++/etc...)

The cheater's shortcut is:

  1. binutils
  2. kernel headers
  3. gcc stage1 (c-only)
  4. libc
  5. gcc stage2 (c/c++/etc...)

The reason people are keen on the shortcut is that the libc headers step tends to take quite a while, especially on slower machines. It can also be kind of a pain to setup kernel/libc headers without a usuable cross compiler. Note though that if you seek help with cross-compilers, upstream projects will not want to help you if you took the shortcut.

Also note that the shortcut requires the gcc stage1 to be "crippled". Since you're building without headers, you cannot enable the sysroot option nor can you build up proper gcc libs. This is OK if the only thing you use the stage1 is building the C library and a kernel, but beyond that you need a nice sysroot based compiler.

Below I will describe the "accepted" way as the steps are pretty much the same. You just need some extra patches for gcc in order to take the shortcut.

Sysroot

We will be cross-compiling using the sysroot method. But does the sysroot do?

The sysroot tells GCC to consider dir as the root of a tree that contains a (subset of) the root filesystem of the target operating system. Target system headers, libraries and run-time object files will be searched in there.

The top level dir is commonly rooted in /usr/$CTARGET

Code Listing 3.1: typical sysroot layout

/usr/$CTARGET/
|-- bin/
|-- lib/            critical runtime libs (libc/ldso/etc...)
`-- usr/
    |-- include/    development headers
    |   |-- linux/      like the linux kernel
    |   `-- asm/        like the arch-specific
    `-- lib/        non critical runtime libs / development libs

As you can see, it's just like the directory setup in / but in /usr/$CTARGET. This setup is of course not an accident but designed on purpose so you can easily migrate applications/libraries out of /usr/$CTARGET and into / on your target board. If you wanted, you could even be lazy and use the /usr/$CTARGET as a quick NFS root!

Note: The old style of cross-compilers was to use --prefix=/usr/$CTARGET. If you are using versions of binutils/gcc that predate sysroot support, you may have to do just this. I will not document this because (1) you should not be using such old/crusty/busted versions and (2) it's quite a huge pain compared to sysroot.

Binutils

Grab the latest binutils tarball and unpack it.

The --disable-werror configure option is to prevent binutils from aborting the compile due to warnings. Great feature for developers, but a pain for users.

Code Listing 3.2: configure and build binutils

$ ./configure \
	--target=$CTARGET \
	--prefix=/usr \
	--with-sysroot=/usr/$CTARGET \
	--disable-werror
$ make
$ make install DESTDIR=$PWD/install-root

The reason we install into the localdir is so we can remove crap that doesn't belong. For example, a normal install will give us /usr/lib/libiberty.a which doesn't belong in our host /usr/lib. So clean out stuff first:

Code Listing 3.3: cleaning binutils

$ rm -rf install-root/usr/{info,lib,man,share}

And install what's left:

Code Listing 3.4: install binutils

# cp -a install-root/* /

Kernel headers

Grab the latest Linux tarball and unpack it. There are two ways of installing the kernel headers: sanitized and unsanitized. The former is clearly better (but requires a recent version of the Linux kernel), but we'll quickly cover both.

Note: Clearly you'll have to replace $ARCH with a value that makes sense for your platform.

Code Listing 3.5: building/installing unsanitized headers

$ yes "" | make ARCH=$ARCH oldconfig prepare
# mkdir -p /usr/$CTARGET/usr/include
# cp -a include/linux include/asm-generic /usr/$CTARGET/usr/include/
# cp -a include/asm-$ARCH /usr/$CTARGET/usr/include/asm

Code Listing 3.6: building/installing sanitized headers

# make ARCH=$ARCH headers_install INSTALL_HDR_PATH=/usr/$CTARGET/usr

System libc headers

Grab the latest glibc tarball and unpack it. Glibc is picky, so you'll have to compile in a directory separate from the source code.

Code Listing 3.7: building/installing glibc headers

$ mkdir build
$ cd build
$ ../configure \
	--host=$CTARGET \
	--prefix=/usr \
	--with-headers=/usr/$CTARGET/usr/include \
	--without-cvs \
	--disable-sanity-checks
# make -k install-headers install_root=/usr/$CTARGET

Glibc sucks at life so you have to do a few things by hand:

Code Listing 3.8: help glibc

# mkdir -p /usr/$CTARGET/usr/include/gnu
# touch /usr/$CTARGET/usr/include/gnu/stubs.h
# cp bits/stdio_lim.h /usr/$CTARGET/usr/include/bits/

GCC Stage 1 (C only)

We first have to help gcc find the current libc headers.

Code Listing 3.9: help gcc

# ln -s usr/include /usr/$CTARGET/sys-include

Then grab the latest gcc tarball and unpack it.

Code Listing 3.10: building gcc stage 1

$ mkdir build
$ cd build
$ ../configure \
	--target=$CTARGET \
	--prefix=/usr \
	--with-sysroot=/usr/$CTARGET \
	--enable-languages=c \
	--disable-shared \
	--disable-checking \
	--disable-werror \
	--disable-libmudflap \
	--disable-libssp \
	--disable-libgomp
$ make
$ make install DESTDIR=$PWD/install-root

Same as binutils, gcc leaves some stuff behind we don't want.

Code Listing 3.11: cleaning gcc stage 1

$ rm -rf install-root/usr/{info,include,lib/libiberty.a,man,share}

Then install what's left (everything should be in CTARGET specific directories which prevents overwriting your host files):

Code Listing 3.12: installing gcc stage 1

# cp -a install-root/* /

System libc

Remove the old glibc build dir and recreate it.

Code Listing 3.13: building/installing glibc

$ rm -rf build
$ mkdir build
$ cd build
$ ../configure \
	--host=$CTARGET \
	--prefix=/usr \
	--without-cvs
$ make
# make install install_root=/usr/$CTARGET

GCC Stage 2 (All frontends)

Build up a full GCC now. Select whichever compiler frontends you like; we'll just do C/C++ for simplicity.

Code Listing 3.14: building/installing gcc stage 2

$ ./configure \
	--target=$CTARGET \
	--prefix=/usr \
	--with-sysroot=/usr/$CTARGET \
	--enable-languages=c,c++ \
	--enable-shared \
	--disable-checking \
	--disable-werror
$ make
# make install

Core Runtime Files

There are many random core runtime files that people wonder what they may be for. Let's explain.

Files provided by glibc
File Purpose
crt0.o Older style of the initial runtime code. No one generates this anymore.
crt1.o Newer style of the initial runtime code. Contains the _start symbol which sets up the env with argc/argv/libc _init/libc _fini before jumping to the libc main. glibc calls this file 'start.S'.
crti.o Defines the function prolog; _init in the .init section and _fini in the .fini section. glibc calls this 'initfini.c'.
crtn.o Defines the function epilog. glibc calls this 'initfini.c'.
Scrt1.o Used in place of crt1.o when generating PIEs.
gcrt1.o Used in place of crt1.o when generating code with profiling information. Compile with -pg. Produces output suitable for the gprof util.
Mcrt1.o Like gcrt1.o, but is used with the prof utility. glibc installs this as a dummy file as it's useless on linux systems.
Files provided by GCC
File Purpose
crtbegin.o GCC uses this to find the start of the constructors.
crtbeginS.o Used in place of crtbegin.o when generating shared objects/PIEs.
crtbeginT.o Used in place of crtbegin.o when generating static executables.
crtend.o GCC uses this to find the start of the destructors.
crtendS.o Used in place of crtend.o when generating shared objects/PIEs.

The general linking order:

Code Listing 3.15: general linking order

... crt1.o crti.o crtbegin.o [-L paths] [user objects] [gcc libs] [C libs] [gcc libs] crtend.o crtn.o	

3. Cross-Compiling With Portage

3.a. Variables

There are a few important variables that we will use throughout this section.

Variable Meaning
CBUILD Platform you are building on
CHOST Platform you are compiling for
ROOT The virtual / you are installing into
PORTAGE_CONFIGROOT The virtual / portage can find its config files (like make.conf)

You can either set this all by hand, but that obviously gets quite tedious very quickly. A better idea is to stick these into a shell script so you can avoid typing it out all the time.

3.b. Filesystem Setup

Cross-compiling a system generally involves two directory trees. The first is where all development files are normally installed. This is your sysroot. The other tree is where only your runtime files are installed. You emerge all of your fun packages into your sysroot (without trimming down any files), and then either install via binary packages or copying files by hand all the stuff you need in your runtime tree.

The common convention is to use your /usr/CTARGET/ tree as your sysroot as the include/library directories in this tree are already encoded into the gcc cross-compiler for searching. You could use another directory and then add custom -I/-L paths to your CPPFLAGS/LDFLAGS, but this has historically proven to be problematic. Yes, it works most of the time, but the corner cases are why this method is discouraged. In the embedded handbook, we'll assume you're using the sysroot as your development ROOT.

For your runtime system, you'll need a much slimmer/trimmed-down setup. The files you remove from a normal installed package is why this tree is not suitable for compiling against. If you build binary packages while installing into your sysroot, then you can use those binary packages in conjunction with the INSTALL_MASK variable to trim out most things. See man make.conf for more information.

3.c. Intro: crossdev's wrappers

These are simple wrapper scripts that will setup the environment variables to point to the right places for you to be able to cross compile using emerge. PORTAGE_CONFIGROOT and ROOT both point to the SYSROOT.

Code Listing 3.1: crossdev's wrappers

# emerge crossdev

Note: Before beginning any cross-emerge, you'll need to run emerge-wrapper --init. Be sure to follow any instructions printed by emerge-wrapper before beginning your cross-emerge.

We can use these tools for both installing into your development root (sysroot) and into your runtime root. For the latter, simply specify by using the --root option. For example if you had merged via crossdev an armv4tl-softfloat-linux-gnueabi toolchain you would then invoke the command just like normal emerge. But using the ctarget prefix:

Code Listing 3.2: CTARGET-emerge

# armv4tl-softfloat-linux-gnueabi-emerge pkg0 pkg1 pkg2

By default these wrappers use the --root-deps=rdeps option to avoid the host dependencies from being pulled into the deptree. This can lead to incomplete deptrees. Therefore you may want to use --root-deps alone to see the full depgraph.

By default the wrappers will link to the generic embedded profile. This is done to simpilify things, but the user may wish to use a more advanced targeted profile. In order to do that we can update the profile symlink.

Code Listing 3.3: ${SYSROOT}/etc/portage/make.profile

# ln -s /usr/portage/profiles/default/linux/arm/13.0 ${SYSROOT}/etc/portage/make.profile

And naturally to change settings for the target system like USE flags, FEATURES, and VIDEO_CARDS. We would edit the standard portage config files.

Code Listing 3.4: ${SYSROOT}/etc/portage/make.conf

# $EDITOR ${SYSROOT}/etc/portage/make.conf

Sometimes there are some additional tests we need override for configure scripts. To do this the wrappers export a few variables to force the test to get the answer it should. This will help prevent bloat in packages which add local functions to workaround issues it assumes your system has because it could not run the test. From time to time you may find you need to add additional variables to these files in /usr/share/crossdev/include/site/ to get a package to compile. To figure out the variable you need to add, it's often as simple as greping the configure script for the autoconf variable and adding it to the appropriate target file. This becomes obvious after the first few times of doing it.

3.d. Uninstall

If you want to uninstall and delete your work, then you can safely remove the sysroot tree without affecting any native packages. See also the section in the crossdev guide about uninstalling.

4. Cross-Compiling The Kernel

4.a. Sources

First install the relevant kernel sources. You can use a package from the Gentoo portage tree or fetch your own from The Linux Kernel Archive or some other random source. The method for actually compiling is all the same.

You should install the kernel into the sysroot so that if you want to cross-compile packages which include kernel modules, the process will be transparent. Otherwise, the actual place where you build the kernel does not matter. Some people build all their kernels in /usr/src/ for example.

4.b. Setup Cross-compiling

There are two fundamental variables that the kernel uses to select the target architecture. Normally these values are guessed based on your build environment, but of course that environment here does not match our target embedded system, so we'll need to override them. The variables in question are ARCH and CROSS_COMPILE. The default values for both are found in the toplevel Makefile and the values of both may be overriden on the command line.

The ARCH variable is the architecture you're targetting as the kernel knows it. So while portage and other people may use "x86", the kernel uses "i386". Peek in the arch/ subdirectory real quick to figure out what you want to use.

Hopefully the CROSS_COMPILE variable is pretty self-explanatory. Set this to the prefix of your toolchain (including the trailing dash "-"). So if your toolchain is invoked as say x86_64-pc-linux-gnu-gcc, just chop off that trailing gcc and that's what you use: x86_64-pc-linux-gnu-.

There is an additional variable, INSTALL_MOD_PATH, which defines where the /lib directory will be created, and all the modules stored. While you don't have to transfer the kernel sources to your target device, if you build any modules, you'll want this directory.

There are really two ways you can setup the system. You can modify the toplevel Makefile or you can override the relevant variables on the command line. How you do it is largely a matter of taste, so we'll cover both. Pick one of the following.

Code Listing 2.1: Editing Toplevel Makefile

# This is what the vanilla Makefile looks like
ARCH            ?= $(SUBARCH)
CROSS_COMPILE   ?= 

# Set the ARCH and CROSS_COMPILE default values
ARCH            ?= arm
CROSS_COMPILE   ?= arm-unknown-linux-gnu-

Code Listing 2.2: Overriding On The Commandline

# make ARCH=arm CROSS_COMPILE=arm-unknown-linux-gnu- ....

You can use a little helper script if you need to hop between different kernel trees at the sametime. We'll call this script xkmake.

Code Listing 2.3: xkmake

#!/bin/sh
exec make ARCH="arm" CROSS_COMPILE="arm-unknown-linux-gnu-" INSTALL_MOD_PATH="${SYSROOT}" "$@"

So now when you want to build a kernel or do anything else, you just execute xkmake in place of make.

4.c. Configure and Compile

At this point, configuring and compiling the kernel is like any other kernel, so we won't go into depth as there are plenty of HOWTOs and guides out there which can treat the subject in much greater detail.

Code Listing 3.1: Configure and Compile

# cd "${SYSROOT}/usr/src/linux"
# xkmake menuconfig
# xkmake

5. Compiling with qemu user chroot

5.a. Usage

In order to take advantage of QEMU user mode we need to do a few things. First we need to merge the QEMU package with the right settings. That means building it with USE=static and setting QEMU_USER_TARGETS to include the targets we want to utilize.

Code Listing 1.1: Building QEMU

See the portage(5) man page for other ways of doing this.
# echo app-emulation/qemu static > /etc/portage/package.use

Tweak the list here to include the target(s) you care about.
See the `emerge -pv qemu` output for the full list.
See the portage(5) man page for other ways of doing this than make.conf.
# echo 'QEMU_SOFTMMU_TARGETS="alpha arm i386 mips mips64 mips64el mipsel ppc ppc64 s390x sh4 sh4eb sparc sparc64 x86_64"' >> /etc/portage/make.conf
# echo 'QEMU_USER_TARGETS="alpha arm armeb i386 mips mipsel ppc ppc64 ppc64abi32 s390x sh4 sh4eb sparc sparc32plus sparc64"' >> /etc/portage/make.conf

Then install the package!
# emerge -1 app-emulation/qemu

Next we need to build the kernel module binfmt_misc. Add this to your kernel .config: CONFIG_BINFMT_MISC=m or CONFIG_BINFMT_MISC=y. If this module is not built already, then the devel host will require a reboot after the kernel update and modules_install.

Mount the binfmt_misc handler if it's not already, then we need to register our format with the kernel via the procfs.

Code Listing 1.2: binfmt_misc

# [ -d /proc/sys/fs/binfmt_misc ] || modprobe binfmt_misc
# [ -f /proc/sys/fs/binfmt_misc/register ] || mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
(Do not register a handler that matches the host machine)
# echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
# echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/qemu-wrapper:' > /proc/sys/fs/binfmt_misc/register
# echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
# echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
# echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
# echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
# echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
# echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/bin/qemu-sh4:' >/proc/sys/fs/binfmt_misc/register
# echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb:' >/proc/sys/fs/binfmt_misc/register
# echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register

Code Listing 1.3: Enter/Exit the chroot

(Download your desired stage tarball)
# wget http://arch-stageball
(Unpack the tarball)
# tar -xzvf arch-stageball
# cd arch-stageball
(Install the static qemu user into the chroot)
# ROOT=$PWD/ emerge -K qemu user
# mkdir -p usr/portage
(Mount the required directories)
# mount --bind /usr/portage usr/portage
# mount --bind /proc proc
# mount --bind /sys sys
# mount --bind /dev dev
# mount --bind /dev/pts dev/pts
(Chroot into the environment)
# chroot . /bin/busybox mdev -s
# chroot . /bin/bash --login
(Unmount stuff when not in use)
# umount usr/portage sys proc dev/pts dev

Sometimes we'll need to pass additional args to QEMU (cpu model), so we'll create a wrapper script that'll call QEMU with it.

Code Listing 1.4: qemu-wrapper

#include <string.h>
#include <unistd.h>

int main(int argc, char **argv, char **envp) {
	char *newargv[argc + 3];

	newargv[0] = argv[0];
	newargv[1] = "-cpu";
	newargv[2] = "cortex-a8";

	memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc - 1));
	newargv[argc + 2] = NULL;
	return execve("/usr/bin/qemu-arm", newargv, envp);
}

Compile the wrapper with gcc -static qemu-wrapper.c -O3 -s -o qemu-wrapper and copy into the chroot. Notice the first example arm entry in the binfmt_misc section uses this method.

6. Frequently Asked Questions

6.a. I get "configure: error: C compiler cannot create executables"

This is a generic error and can be caused by just about anything. The test is pretty simple: can the requested compiler create an executable? However, this relies on many things being correct: the toolchain itself being completely sane, the compiler and compiler flags being appropriate, your environment set up properly, etc... The only way to find out the real source of the problem is to open up the generated config.log file and scroll down to where this test is run and see what exactly the error message is that the toolchain is spitting out.

6.b. "epatch" always fails in newly compiled system

The bash package does not properly cross-compile and mixes the host signal definitions with those of the target. This manifests itself differently depending on the combination of host architecture and target architecture. To resolve the issue, simply re-compile bash natively. "But bash uses epatch!" you exclaim. In that case, you will need to modify the ebuild and comment out all the calls to epatch. Once you've installed the fixed bash this way, uncomment all of the bash lines and rebuild it again.

6.c. uClibc build segfaults/crashes while building locale

The uClibc locale support is pretty experimental at this point. Unless you really need support for it (and you're willing to help bang on the problem), simply disable support by adding -nls -iconv -pregen -userlocales to your USE when building uClibc.

B. Emulators

1. Qemu

1.a. Usage

TODO

2. SkyEye

2.a. Usage

TODO

3. Armulator

3.a. Usage

TODO

4. Softgun

4.a. Usage

TODO

5. Hercules

5.a. Usage

TODO

C. Bootloaders

1. Das U-Boot

1.a. Usage

Rather than duplicate existing information, please consult the upstream documentation and their main wiki.

2. NeTTrom

2.a. Usage

TODO

3. RedBoot

3.a. Usage

TODO

4. SH-LILO

4.a. Usage

TODO

D. Boards

1. Hammer/Nailboard

1.a. Nail Board Specifications:

Code Listing 1.1: Board Specifications


# All power received from the USB port (no external power supply required)
# Male (upstream) USB connector
# Female (downstream) USB connector
# Complete USB JTAG device on board (via internal FT2232)
# USB Hub on board
# USB serial port console (via internal FT2232)
# USB controlled GPIO's (for configuration)
# USB gadget interface (via the Hammer module)
    * Ethernet Gadget Driver (default)
    * Serial Port Gadget Driver
    * Mass Storage Driver

# USB host interface (via the Hammer module)
    * USB 1.1 Compliant
    * Low Speed Support (2mb)
    * Full Speed Support (12mb)

# 3 User LED's available
    * Two on the Nail Board
    * One user LED on the Hammer module
    * USER led on the Hammer Board

# 2 interrupt driven pushbutton switches
# User controlled PWM buzzer
# Reset button
# Power LED
# Expansion header (20-pin: 2 x10)
    * +5V available
    * +3.3V available
    * 2 SPI ports
    * 2 wire Serial Port  (TX/RX)
    * GPIO's
    * External Interrupts
    * Headers can be jumper configured

# Hammer module breakout header
    * Access to all 40 I/O pins of the Hammer module
    * 0.1 inch headers

1.b. /proc/cpuinfo

Code Listing 2.1: CPU Info

Processor	: ARM920T rev 0 (v4l)
BogoMIPS	: 101.17
Features	: swp half thumb 
CPU implementer	: 0x41
CPU architecture: 4T
CPU variant	: 0x1
CPU part	: 0x920
CPU revision	: 0
Cache type	: write-back
Cache clean	: cp15 c7 ops
Cache lockdown	: format A
Cache format	: Harvard
I size		: 16384
I assoc		: 64
I line length	: 32
I sets		: 8
D size		: 16384
D assoc		: 64
D line length	: 32
D sets		: 8

Hardware	: TCT_HAMMER
Revision	: 0000
Serial		: 0000000000000000

1.c. Cross Compile Preparation

Code Listing 3.1: Setup uClibc

echo '>=cross-arm-softfloat-linux-uclibc/gcc-4' >> /etc/portage/package.mask
echo 'dev-embedded/openocd ft2232 ftdi' >> /etc/portage/package.use
modprobe ftdi_sio
emerge openocd
ACCEPT_KEYWORDS="~*" emerge crossdev
crossdev arm-softfloat-linux-uclibc

Code Listing 3.2: Setup uClibc + EABI

echo '>=cross-armv4l-softfloat-linux-uclibceabi/gcc-4' >> /etc/portage/package.mask
echo 'dev-embedded/openocd ft2232 ftdi' >> /etc/portage/package.use
modprobe ftdi_sio
emerge openocd
ACCEPT_KEYWORDS="~*" emerge crossdev
crossdev armv4tl-softfloat-linux-uclibceabi

1.d. References:

2. LANTank

2.a. IO-Data LANTANK Specifications:

Code Listing 1.1: Board Specifications

# SH4 SH7751 processor, ~266MHz
# 64MB RAM
# Artop Electronic Corp ATP865 IDE controller
# 10/100Mbit Realtek 8139C+ Ethernet controller
# 2x NEC USB 2.0

2.b. /proc/cpuinfo

Code Listing 2.1: CPU Info

machine         : LANDISK
processor       : 0
cpu family      : sh4
cpu type        : SH7751R
cpu flags       : fpu ptea
cache type      : split (harvard)
icache size     : 16KiB (2-way)
dcache size     : 32KiB (2-way)
bogomips        : 266.24
master_clk      : 266.66MHz
module_clk      : 33.33MHz
bus_clk         : 133.33MHz
cpu_clk         : 266.66MHz
tmu0_clk        : 8.33MHz

2.c. Cross Compile Preparation

Code Listing 3.1: Setup

# emerge crossdev
# crossdev sh4-unknown-linux-gnu

Code Listing 3.2: Emerge Wrapper (lantank-merge)

#!/bin/sh

CHOST=sh4-unknown-linux-gnu

#export CBUILD=$(portageq envvar CBUILD)
export SYSROOT="/usr/${CHOST}"
export PORTAGE_CONFIGROOT="/usr/${CHOST}"

# optional exports
export enable_malloc0returnsnull=yes \
        ac_cv_file__usr_share_sgml_X11_defs_ent=1 \
        ac_cv_func_setpgrp_void=yes ac_cv_func_setgrent_void=yes \
        ac_cv_func_calloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes \
        gl_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes \
        ac_cv_func_memcmp_working=yes ac_cv_func_strnlen_working=yes

# optional export for glib:2
export glib_cv_uscore=no glib_cv_stack_grows=no \
        glib_cv_stack_grows=no  glib_cv_has__inline=yes \
        glib_cv_has__inline__=yes glib_cv_hasinline=yes \
        glib_cv_sane_realloc=yes glib_cv_va_copy=yes \
        glib_cv___va_copy=yes glib_cv_va_val_copy=no \
        glib_cv_rtldglobal_broken=no glib_cv_uscore=no \
        ac_cv_func_posix_getpwuid_r=yes \
        ac_cv_func_posix_getgrgid_r=yes \
        ac_cv_header_pwd_h=yes \
        ac_cv_func_getpwuid_r=yes \
        glib_cv_sizeof_gmutex=40 

FAKEROOT=
if [[ $(id -u) != 0 ]]; then
	if [[ $(type -p fakeroot) != "" ]]; then
		FAKEROOT=fakeroot
	fi
fi

${FAKEROOT} emerge -q "$@"

Code Listing 3.3: /usr/sh4-unknown-linux-gnu/etc/make.conf

CHOST=sh4-unknown-linux-gnu
CBUILD=x86_64-pc-linux-gnu
ARCH="sh"
ROOT=/usr/${CHOST}/
ACCEPT_KEYWORDS="sh ~sh"
USE="${ARCH} zlib bindist make-symlinks minimal \
        input_devices_keyboard input_devices_evdev \
        video_cards_fbdev video_cards_dummy"

VIDEO_CARDS="fbdev dummy"

INPUT_DEVICES="evdev keyboard mouse touchscreen"
USE_EXPAND="video_cards input_devices"
MARCH_TUNE="-m4"
CFLAGS="-Os -pipe ${MARCH_TUNE} -fomit-frame-pointer -I${ROOT}/usr/include/ -I${ROOT}/include/"

CXXFLAGS="${CFLAGS}"
LDFLAGS="-L${ROOT}/usr/lib -L${ROOT}/lib"

PKG_CONFIG_PATH="${ROOT}/usr/lib/pkgconfig/"
MAKEOPTS="-j8"
FEATURES="-collision-protect sandbox buildpkg noman noinfo nodoc"

PORTDIR_OVERLAY="/usr/portage/local/"
PKGDIR=${ROOT}/packages/
PORTAGE_TMPDIR=${ROOT}/tmp/
PORTAGE_WORKDIR_MODE=2775
PORTAGE_ECLASS_WARNING_ENABLE=0

CLEAN_DELAY=0
EPAUSE_IGNORE=1
EBEEP_IGNORE=1

2.d. References:

3. NetWinder

3.a. Rebel NetWinder

Code Listing 1.1: Board Specifications

# DEC/Intel StrongARM 110 processor, ~233MHz
# DEC/Intel 21285 FootBridge chipset
# 32/64/128MB RAM
# Intergraphics Systems CyberPro 2000A graphics chip with 2MB RAM, VGA output
# WinBond 553 IDE controller
# RockWell WaveArtist audio chip
# Philips 7111 video capture/WinBond 9660 TV Encoder
# 1x WinBond 940 10BaseT Ethernet controller
# 1x Digital 21143(Tulip) 10/100BaseT Ethernet controller

3.b. /proc/cpuinfo

Code Listing 2.1: CPU Info

Processor       : StrongARM-110 rev 4 (v4l)
BogoMIPS        : 185.54
Features        : swp half 26bit fastmult
CPU implementer : 0x44
CPU architecture: 4
CPU variant     : 0x0
CPU part        : 0xa10
CPU revision    : 4

Hardware        : Rebel-NetWinder
Revision        : 59ff
Serial          : 0000000000000000

3.c. Cross Compile Preparation

Code Listing 3.1: Setup

# emerge crossdev
# crossdev armv4l-unknown-linux-gnu

Code Listing 3.2: Emerge Wrapper (netwinder-merge)

#!/bin/sh

CHOST=armv4l-unknown-linux-gnu

#export CBUILD=$(portageq envvar CBUILD)
export SYSROOT="/usr/${CHOST}"
export PORTAGE_CONFIGROOT="/usr/${CHOST}"

# optional exports
export enable_malloc0returnsnull=yes \
        ac_cv_file__usr_share_sgml_X11_defs_ent=1 \
        ac_cv_func_setpgrp_void=yes ac_cv_func_setgrent_void=yes \
        ac_cv_func_calloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes \
        gl_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes \
        ac_cv_func_memcmp_working=yes ac_cv_func_strnlen_working=yes

# optional export for glib:2
export glib_cv_uscore=no glib_cv_stack_grows=no \
        glib_cv_stack_grows=no  glib_cv_has__inline=yes \
        glib_cv_has__inline__=yes glib_cv_hasinline=yes \
        glib_cv_sane_realloc=yes glib_cv_va_copy=yes \
        glib_cv___va_copy=yes glib_cv_va_val_copy=no \
        glib_cv_rtldglobal_broken=no glib_cv_uscore=no \
        ac_cv_func_posix_getpwuid_r=yes \
        ac_cv_func_posix_getgrgid_r=yes \
        ac_cv_header_pwd_h=yes \
        ac_cv_func_getpwuid_r=yes \
        glib_cv_sizeof_gmutex=40 

FAKEROOT=
if [[ $(id -u) != 0 ]]; then
	if [[ $(type -p fakeroot) != "" ]]; then
		FAKEROOT=fakeroot
	fi
fi

${FAKEROOT} emerge -q "$@"

Code Listing 3.3: /usr/armv4l-unknown-linux-gnu/etc/make.conf

CHOST=armv4l-unknown-linux-gnu
CBUILD=x86_64-pc-linux-gnu
ARCH="arm"
ROOT=/usr/${CHOST}/
ACCEPT_KEYWORDS="arm ~arm"
USE="${ARCH} zlib bindist make-symlinks minimal \
        input_devices_keyboard input_devices_evdev \
        video_cards_fbdev video_cards_dummy"

VIDEO_CARDS="fbdev dummy"

INPUT_DEVICES="evdev keyboard mouse touchscreen"
USE_EXPAND="video_cards input_devices"
MARCH_TUNE="-mcpu=strongarm110"
CFLAGS="-Os -pipe ${MARCH_TUNE} -fomit-frame-pointer -I${ROOT}/usr/include/ -I${ROOT}/include/"

CXXFLAGS="${CFLAGS}"
LDFLAGS="-L${ROOT}/usr/lib -L${ROOT}/lib"

PKG_CONFIG_PATH="${ROOT}/usr/lib/pkgconfig/"
MAKEOPTS="-j8"
FEATURES="-collision-protect sandbox buildpkg noman noinfo nodoc"

PORTDIR_OVERLAY="/usr/portage/local/"
PKGDIR=${ROOT}/packages/
PORTAGE_TMPDIR=${ROOT}/tmp/
PORTAGE_WORKDIR_MODE=2775
PORTAGE_ECLASS_WARNING_ENABLE=0

CLEAN_DELAY=0
EPAUSE_IGNORE=1
EBEEP_IGNORE=1

3.d. References:

4. NSLU2

4.a. Usage

TODO

5. QNAP TurboStation 109/209/409

5.a. Gentoo documentation

Currently, the TS109/TS209 and TS409 boards are supported on Gentoo thanks to QNAP Inc. who provided us with hardware to create and document the installation process.

5.b. QNAP TurboStation TS109/209/409 Specifications:

Code Listing 2.1: Board Specifications


# Marvell Orion SoC MV88F5182(for the TS109/209) and MV88F5281(for the TS409)
# Marvell Feroceon ARMv5TE 500MHz processor
# 128/256/512MB DDR2 RAM between the different models
# 8MB NAND Flash
# Marvell SATA2 controller
# Marvell Gigabit Ethernet controller

# LED's available:
    * Power led (TS109/209 only)
	* Status led
	* SATA HDD leds
	* Network interface led
	* USB led

# Reset button
# 3x USB 2.0 ports
# 1x eSATA port, TS109 only
# Buzzer

5.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

Processor       : Feroceon rev 0 (v5l)
BogoMIPS        : 498.07
Features        : swp half thumb fastmult vfp edsp
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant     : 0x0
CPU part        : 0x926
CPU revision    : 0
Cache type      : write-back
Cache clean     : cp15 c7 ops
Cache lockdown  : format C
Cache format    : Harvard
I size          : 32768
I assoc         : 1
I line length   : 32
I sets          : 1024
D size          : 32768
D assoc         : 4
D line length   : 32
D sets          : 256

Hardware        : QNAP TS-409
Revision        : 0000
Serial          : 0000000000000000

5.d. Cross Compile Preparation

Code Listing 4.1: Setup

emerge crossdev
crossdev armv5tel-softfloat-linux-gnueabi

Code Listing 4.2: Emerge Wrapper (qnap-merge)

#!/bin/sh

CHOST=armv5tel-softfloat-linux-gnueabi

#export CBUILD=$(portageq envvar CBUILD)
export SYSROOT="/usr/${CHOST}"
export PORTAGE_CONFIGROOT="/usr/${CHOST}"

# optional exports
export enable_malloc0returnsnull=yes \
        ac_cv_file__usr_share_sgml_X11_defs_ent=1 \
        ac_cv_func_setpgrp_void=yes ac_cv_func_setgrent_void=yes \
        ac_cv_func_calloc_0_nonnull=yes ac_cv_func_malloc_0_nonnull=yes \
        gl_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes \
        ac_cv_func_memcmp_working=yes ac_cv_func_strnlen_working=yes

# optional export for glib:2
export glib_cv_uscore=no glib_cv_stack_grows=no \
        glib_cv_stack_grows=no  glib_cv_has__inline=yes \
        glib_cv_has__inline__=yes glib_cv_hasinline=yes \
        glib_cv_sane_realloc=yes glib_cv_va_copy=yes \
        glib_cv___va_copy=yes glib_cv_va_val_copy=no \
        glib_cv_rtldglobal_broken=no glib_cv_uscore=no \
        ac_cv_func_posix_getpwuid_r=yes \
        ac_cv_func_posix_getgrgid_r=yes \
        ac_cv_header_pwd_h=yes \
        ac_cv_func_getpwuid_r=yes \
        glib_cv_sizeof_gmutex=40 

FAKEROOT=
if [[ $(id -u) != 0 ]]; then
	if [[ $(type -p fakeroot) != "" ]]; then
		FAKEROOT=fakeroot
	fi
fi

${FAKEROOT} emerge -q "$@"

Code Listing 4.3: /usr/armv5tel-softfloat-linux-gnueabi/etc/make.conf

#
CHOST=armv5tel-softfloat-linux-gnueabi
CBUILD=x86_64-pc-linux-gnu
ARCH="arm"
ROOT=/usr/${CHOST}/
ACCEPT_KEYWORDS="arm ~arm"
USE="${ARCH} zlib bindist make-symlinks minimal \
        input_devices_keyboard input_devices_evdev \
        video_cards_fbdev video_cards_dummy"

VIDEO_CARDS="fbdev dummy"

INPUT_DEVICES="evdev keyboard mouse touchscreen"
USE_EXPAND="video_cards input_devices"
MARCH_TUNE="-march=armv5t -mtune=arm926ej-s"
CFLAGS="-Os -pipe ${MARCH_TUNE} -fomit-frame-pointer -I${ROOT}/usr/include/ -I${ROOT}/include/"

CXXFLAGS="${CFLAGS}"
LDFLAGS="-L${ROOT}/usr/lib -L${ROOT}/lib"

PKG_CONFIG_PATH="${ROOT}/usr/lib/pkgconfig/"
MAKEOPTS="-j8"
FEATURES="-collision-protect sandbox buildpkg noman noinfo nodoc"

PORTDIR_OVERLAY="/usr/portage/local/"
PKGDIR=${ROOT}/packages/
PORTAGE_TMPDIR=${ROOT}/tmp/
PORTAGE_WORKDIR_MODE=2775
PORTAGE_ECLASS_WARNING_ENABLE=0

CLEAN_DELAY=0
EPAUSE_IGNORE=1
EBEEP_IGNORE=1

5.e. References:

6. Marvell Sheevaplug

6.a. Gentoo documentation

Currently, the Marvell Sheevaplug is supported on Gentoo thanks to Marvell who provided us with hardware to create and document the installation process.

6.b. Marvell Sheevaplug specifications

Code Listing 2.1: Board Specifications

# Marvell Kirkwood SoC 88F6281
# Marvell Feroceon ARMv5TE 1200MHz processor
# 512MB DDR2 RAM
# 512MB NAND Flash
# Marvell Gigabit Ethernet controller
# 1x SDHC slot
# 1x USB 2.0 port
# 1x mini-USB 2.0 port (for integrated JTAG and serial access)
# Reset button

6.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

Processor       : Feroceon 88FR131 rev 1 (v5l)
BogoMIPS        : 1192.75
Features        : swp half thumb fastmult edsp
CPU implementer : 0x56
CPU architecture: 5TE
CPU variant     : 0x2
CPU part        : 0x131
CPU revision    : 1

Hardware        : Marvell SheevaPlug Reference Board
Revision        : 0000
Serial          : 0000000000000000

6.d. References:

7. ACME SYSTEMS Netus G20

7.a. Gentoo documentation

The Netus G20 is a 4x4cm Linux ready core engine based on the Atmel(TM) AT91SAM9G20 (ARMv5TE) and sold by ACME SYSTEMS. It is supported on Gentoo thanks to the vendor and in special to Davide Cantaluppi who maintains it. In fact, Gentoo is the default OS shipped with this device.

7.b. ACME SYSTEMS Netus G20 specifications

Code Listing 2.1: Board Specifications

# CPU Atmel AT91SAM9G20 based on ARM926EJ-S with clock speed of 400MHz.
# 64MBytes of SDRAM with 32bit access.
# 8MBytes of Dataflash.
# Size 40x40mm. Weight 10g.
# Operative temperature range: -20º + 70º
# Four 60 pin connectors (0.8mm pitch) with the following signals available on top and bottom sides (see the pinout)
  # One USB 2.0 Full Speed (12 Mbits per second) Device Port.
  # Two USB 2.0 Full Speed (12 Mbits per second) Host Ports.
  # One Ethernet MAC 10/100 Base T Port.
  # Image Sensor Interface (ITU-R BT. 601/656 12 bit).
  # One Two-slot MultiMedia Card Interface (MCI). SDCard/SDIO and MultiMediaCard(TM) Compliant.
  # Four Universal Synchronous/Asynchronous Receiver Transmitters (USART) with RS485 support.
  # Two 2-wire UARTs.
  # Two Master/Slave Serial Peripheral Interfaces (SPI).
  # One Synchronous Serial Controller (SSC). I2S Analog Interface Support.
  # Two Wire Interface
  # Four-channel 10-bit ADC.
  # 80 general purpose I/O lines multiplexed with up to two peripheral I/Os.
    # Individually Programmable Open-drain, Pull-up Resistor and Synchronous Output.
    # All I/O Lines are Schmitt Trigger when programmed as inputs.
    # Input Change Interrupt Capability on Each I/O Line.
  # Serial 2 wire console port.
  # JTAG Console and Boundary Scan on All Digital Pins (IEEE(R) 1149.1).
# Two Three-channel 16-bit Timer/Counters with PWM Generation.
# Watchdog timer.
# Real-time clock (optional external battery backup).
# Very Slow Clock Operating Mode.

7.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

netusg20 / # cat /proc/cpuinfo
Processor    : ARM926EJ-S rev 5 (v5l)
BogoMIPS    : 197.83
Features    : swp half thumb fastmult edsp java
CPU implementer    : 0x41
CPU architecture: 5TEJ
CPU variant    : 0x0
CPU part    : 0x926
CPU revision    : 5

Hardware    : Atmel AT91SAM9G20-EK
Revision    : 0000
Serial        : 0000000000000000

7.d. dmesg

Code Listing 4.1: Kernel messages

Linux version 2.6.31-gentooGentooNETUSembedded (root@localhost) (gcc version
4.3.3 (Gentoo 4.3.3 p1.0, pie-10.1.5) ) #29 Fri Oct 16 12:00:28 CEST 2009
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: Atmel AT91SAM9G20-EK
Memory policy: ECC disabled, Data cache writeback
On node 0 totalpages: 16384
free_area_init_node: node 0, pgdat c04046a0, node_mem_map c0426000
  Normal zone: 128 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 16256 pages, LIFO batch:3
Clocks: CPU 396 MHz, master 132 MHz, main 18.432 MHz
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: mem=64M console=ttyS0,115200 rootdelay=5
root=/dev/mmcblk0p1 rw rootfstype=reiserfs rootflags=data=writeback
init=/sbin/init nodevfs
PID hash table entries: 256 (order: 8, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 60652KB available (3840K code, 256K data, 108K init, 0K highmem)
Hierarchical RCU implementation.
NR_IRQS:192
AT91: 96 gpio irqs in 3 banks
Console: colour dummy device 80x30
console [ttyS0] enabled
Calibrating delay loop... 197.83 BogoMIPS (lpj=989184)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
tcb_clksrc: tc0 at 16.012 MHz
bio: create slab <bio-0> at 0
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
Bluetooth: Core ver 2.15
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
NET: Registered protocol family 2
Switched to high resolution mode on CPU 0
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 2048 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 2048 bind 2048)
TCP reno registered
NET: Registered protocol family 1
squashfs: version 4.0 (2009/01/31) Phillip Lougher
NTFS driver 2.1.29 [Flags: R/W].
JFFS2 version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
JFS: nTxBlock = 474, nTxLock = 3795
msgmni has been set to 118
io scheduler noop registered
io scheduler deadline registered (default)
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
atmel_usart.1: ttyS1 at MMIO 0xfffb0000 (irq = 6) is a ATMEL_SERIAL
atmel_usart.2: ttyS2 at MMIO 0xfffb4000 (irq = 7) is a ATMEL_SERIAL
atmel_usart.3: ttyS3 at MMIO 0xfffb8000 (irq = 8) is a ATMEL_SERIAL
atmel_usart.4: ttyS4 at MMIO 0xfffd0000 (irq = 23) is a ATMEL_SERIAL
brd: module loaded
loop: module loaded
ssc ssc.0: Atmel SSC device at 0xc48d8000 (irq 14)
PPP generic driver version 2.4.2
MACB_mii_bus: probed
eth0: Atmel MACB at 0xfffc4000 irq 21 (3a:1f:34:08:54:54)
eth0: attached PHY driver [Generic PHY] (mii_bus:phy_addr=ffffffff:00,
irq=-1)
ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
at91_ohci at91_ohci: AT91 OHCI
at91_ohci at91_ohci: new USB bus registered, assigned bus number 1
at91_ohci at91_ohci: irq 20, io mem 0x00500000
usb usb1: New USB device found, idVendor=1d6b, idProduct=0001
usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
usb usb1: Product: AT91 OHCI
usb usb1: Manufacturer: Linux 2.6.31-gentooGentooNETUSembedded ohci_hcd
usb usb1: SerialNumber: at91
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 2 ports detected
Initializing USB Mass Storage driver...
usbcore: registered new interface driver usb-storage
USB Mass Storage support registered.
usbcore: registered new interface driver libusual
mice: PS/2 mouse device common for all mice
usbcore: registered new interface driver xpad
xpad: X-Box pad driver
at91_rtt: dev (254:0)
rtc-at91sam9 at91_rtt.0: rtc core: registered at91_rtt as rtc0
IRQ 1/rtc0: IRQF_DISABLED is not guaranteed on shared IRQs
i2c /dev entries driver
at24 0-0050: 65536 byte 24c512 EEPROM (writable)
i2c-gpio i2c-gpio: using pins 55 (SDA) and 56 (SCL)
AT91SAM9 Watchdog: sorry, watchdog is disabled
at91_wdt: probe of at91_wdt failed with error -5
Bluetooth: HCI UART driver ver 2.2
Bluetooth: HCI H4 protocol initialized
Bluetooth: HCI BCSP protocol initialized
Bluetooth: HCILL protocol initialized
Bluetooth: Generic Bluetooth USB driver ver 0.5
usbcore: registered new interface driver btusb
at91_mci at91_mci: 4 wire bus mode not supported - using 1 wire
Registered led device: ds5
Registered led device: ds1
usbcore: registered new interface driver hiddev
usbcore: registered new interface driver usbhid
usbhid: v2.6:USB HID core driver
TCP cubic registered
NET: Registered protocol family 10
IPv6 over IPv4 tunneling driver
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
rtc-at91sam9 at91_rtt.0: readtime: 2009-09-19 14:56:38
rtc-at91sam9 at91_rtt.0: setting system clock to 2009-10-19 14:56:38 UTC
(1255964198)
Waiting 5sec before mounting root device...
usb 1-2: new full speed USB device using at91_ohci and address 2
mmc0: host does not support reading read-only switch. assuming write-enable.
mmc0: new SDHC card at address 8fe4
mmcblk0: mmc0:8fe4 SU04G 3.69 GiB
 mmcblk0: p1
usb 1-2: New USB device found, idVendor=1370, idProduct=0323
usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-2: Product: pitchBLACK
usb 1-2: Manufacturer: Swissbit
usb 1-2: SerialNumber: 000010004269FR0002b5
usb 1-2: configuration #1 chosen from 1 choice
scsi0 : SCSI emulation for USB Mass Storage devices
usb-storage: device found at 2
usb-storage: waiting for device to settle before scanning
REISERFS (device mmcblk0p1): found reiserfs format "3.6" with standard
journal
REISERFS (device mmcblk0p1): using writeback data mode
REISERFS (device mmcblk0p1): journal params: device mmcblk0p1, size 8192,
journal first block 18, max trans len 1024, max batch 900, max commit age
30, max trans age 30
REISERFS (device mmcblk0p1): checking transaction log (mmcblk0p1)
REISERFS (device mmcblk0p1): Using r5 hash to sort names
VFS: Mounted root (reiserfs filesystem) on device 179:1.
Freeing init memory: 108K
eth0: link up (100/Full)
eth0: no IPv6 routers present

7.e. References:

8. Genesi Efika MX

8.a. Gentoo documentation

The Genesi USA Efika MX Smarttop is supported on Gentoo, thanks to Genesi USA who provided us with hardware to bring this forward.

8.b. Genesi Efika MX specifications

Code Listing 2.1: Board Specifications

# Freescale i.MX51 SoC
# ARMv7-A 800MHz ARM Cortex-A8 processor
# 512MB DDR2 RAM
# 8GB SSD Flash
# Ralink RT3070USB Wireless card
# ASIX AX88772 USB 2.0 Ethernet card
# Soundcard
# 
# 1x SDHC slot
# 2x USB 2.0 ports
# 1x HDMI out
# 1x Audio IN
# 1x Audio OUT
# 1x Ethernet 100Mbps
# Power button
#
# Board with serial and JTAG

8.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

Processor	: ARMv7 Processor rev 1 (v7l)
BogoMIPS	: 799.53
Features	: swp half thumb fastmult vfp edsp 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x2
CPU part	: 0xc08
CPU revision	: 1

Hardware	: Genesi Efika MX
Revision	: 51025
Serial		: 0000000000000000

8.d. References:

9. Pandaboard

9.a. Gentoo documentation

Currently, the Pandaboard is supported on Gentoo thanks to pandaboard.org who provided us with hardware to create and document the installation process.

9.b. Pandaboard specifications

Code Listing 2.1: Board Specifications

# TI OMAP SoC 4430
# Dual-core ARMv7-A 1GHz Cortex-A9 processor
# 1GB DDR2 RAM
# USB-based SMSC 9514-JZX Ethernet controller and USB HUB
# LS Research WL1271 SDIO module (WLAN, BT, FM)
#
# 1x SDHC/MMC/SDIO slot
# 2x USB 2.0 port
# 1x mini-USB 2.0 OTG port
# 1x HDMI out
# 1x DVI-D out(HDMI connector)
# 1x Audio IN
# 1x Audio OUT
# 1x RS232 serial port
# 1x RJ45 port

# Reset and user-defined button

9.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

Processor	: ARMv7 Processor rev 2 (v7l)
processor	: 0
BogoMIPS	: 2013.49

processor	: 1
BogoMIPS	: 1963.08

Features	: swp half thumb fastmult vfp edsp thumbee neon vfpv3 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x1
CPU part	: 0xc09
CPU revision	: 2

Hardware	: OMAP4430 Panda Board
Revision	: 0010
Serial		: 0000000000000000

9.d. References:

10. Trimslice

10.a. Gentoo documentation

The Compulab TrimSlice is supported on Gentoo, thanks to Compulab/Trimslice.com who provided us with hardware to bring this forward.

10.b. TrimSlice specifications

Code Listing 2.1: Board Specifications

# Nvidia Tegra2 SoC
# Dual-Core ARMv7-A 1GHz ARM Cortex-A9 processor
# 1GB DDR2-667 RAM
# Realtek RTL8111DL Gigabit Ethernet
# Soundcard
# 
# 1x SDHC slot
# 1x MicroSD slot
# 4x USB 2.0 ports
# 1x microUSB port for serial
# 1x HDMI out, 1x DVI out(depends on the model)
# 1x Audio IN
# 1x Audio OUT
# 1x Ethernet 1Gbps
# Power button
#

10.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

Processor	: ARMv7 Processor rev 0 (v7l)
processor	: 0
BogoMIPS	: 1998.84

processor	: 1
BogoMIPS	: 1998.84

Features	: swp half thumb fastmult vfp edsp thumbee vfpv3 vfpv3d16 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x1
CPU part	: 0xc09
CPU revision	: 0

Hardware	: TrimSlice
Revision	: 0000
Serial		: 0x00000000000000000

10.d. References:

11. Beaglebone

11.a. Gentoo documentation

The Beaglebone is supported on Gentoo, thanks to Beagleboard.org who provided us with hardware to bring this forward.

11.b. Beaglebone specifications

Code Listing 2.1: Board Specifications

# ARMv7-A 500MHz(USB power)/720MHz(PSU power) TI AM3358/9 ARM Cortex-A8 processor
# 256MB DDR2 RAM
# SMSC LAN8710A Ethernet card
# 
# 1x microSDHC slot
# 1x USB 2.0 Type-A port
# 1x mini-USB 2.0 OTG port
# 1x RJ45
#
# Reset and user-defined button

11.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

(Note: running in USB power)
Processor	: ARMv7 Processor rev 2 (v7l)
BogoMIPS	: 498.89
Features	: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x3
CPU part	: 0xc08
CPU revision	: 2

Hardware	: am335xevm
Revision	: 0000
Serial		: 0000000000000000

11.d. References:

12. BeagleBone Black

12.a. Gentoo documentation

The BeagleBone Black is supported on Gentoo, thanks to Beagleboard.org who provided us with hardware to bring this forward.

12.b. BeagleBone Black specifications

Code Listing 2.1: Board Specifications

# ARMv7-A 1GHz TI AM3358/9 ARM Cortex-A8 processor
# 512MB DDR3L RAM
# SMSC LAN8710 Ethernet card
#
# 1x microSDHC slot
# 1x USB 2.0 Type-A port
# 1x mini-USB 2.0 OTG port
# 1x RJ45
# 1x 6 pin 3.3V TTL Header for serial
#
# Reset, power and user-defined button

12.c. /proc/cpuinfo

Code Listing 3.1: CPU Info

processor	: 0
model name	: ARMv7 Processor rev 2 (v7l)
BogoMIPS	: 990.68
Features	: swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x3
CPU part	: 0xc08
CPU revision	: 2

Hardware	: Generic AM33XX (Flattened Device Tree)
Revision	: 0000
Serial		: 0000000000000000

12.d. References:

E. Beyond

1. Communication

1.a. Mailing Lists

To participate in the Embedded Gentoo project first join the mailing list at gentoo-embedded@gentoo.org. Then ask if there are plans to support something that you are interested in, propose a new subproject that you are interested in or choose one of the planned subprojects to work on.

For more information, see the common mailing list page.

1.b. IRC

You may talk to the developers and users in the IRC channel #gentoo-embedded on irc.freenode.net for more information or just to chat about the project or any subprojects.

For more information, see the common IRC page.

1.c. Bugzilla

We use the Gentoo Bugzilla to handle all of our tracking. All bug reports should generally go here.

For more information, see the Gentoo bug reporting guide.

2. Contributing

2.a. Where To Contribute

First off, please review the Gentoo Embedded communication channels and join as needed. Please do not start with e-mailing specific developers.

Below we outline the many different aspects which could use your help. Contribute whatever and whenever you can!

2.b. Arch Testers

Often times considered a mighty boring job, it is unfortunately quite critical to the smooth running of a port. It involves testing new packages for stabilization or new packages that have not yet been tested on the particular architecture. Simply select your favorite embedded architecture (arm, m68k, mips, ppc, sh) and start watching the alias on the Gentoo Bugzilla. When a bug opens requesting stabilization or arch testing, test the package in question on your setup and report back to the bug on how things go. If you want to contribute more, sign up to be a developer yourself for the architecture in question and just start committing fixes yourself! :) See our Gentoo Developer Relations page for more information.

2.c. Release Engineers

Every release of Gentoo should see updated stages for people to use as a base when creating a new native install. Each architecture (arm, m68k, sh) needs a dedicated person to go through the process of building these stages and tracking down/fixing failures as they come up.

2.d. Board Developers

Got a crazy new embedded device and you want to put Gentoo on it? Then do it! Once you've gone through the steps, put together a little bit of information on it and get it integrated into the Gentoo Embedded Handbook. Finally, start making little firmware images for others to drop into their system so they can get a head start on the process.

2.e. Answer Questions

Have general knowledge and like to help people? Great! We get questions every day in our mailing lists/irc channels/etc... which require people to simply watch and answer as they can. Maybe you'll learn a thing or two yourself!

2.f. Documentation Writers

One of Gentoo's strong points is its documentation. However, this stuff doesn't write itself, so we need people familiar with Gentoo's simple GuideXML documentation format to help maintain and expand the Gentoo Embedded documentation.

3. Vendors

3.a. Hardware Donations

Obviously the first barrier to supporting something is hardware. It's hard to develop for something without hardware to actually test on. There are generally two classes of machines: (1) generic hardware development platforms and (2) specific device platforms. The generic platforms can be thought of as "desktopish" machines where the system is self hosting, has large local storage (i.e. a harddisk, not flash), and network connectivity. These platforms are useful in the sense of getting software to build specifically for that architecture. The device platforms are things like a PDA or a cell phone. The target of the development is to produce a firmware image which can be used on just the one device.

If you have hardware to spare, feel free to contact the Gentoo Embedded team to find the best home for your donation. Thanks!

4. Further Learning

4.a. Books

Embedded Books

Linux Kernel Books

4.b. Links

Embedded Forums

Cross-compiler Pages

Projects

Print

Page updated April 28, 2013

Summary: The Gentoo Embedded Handbook is the center point for all Embedded work done with Gentoo. It aims to cover just about all aspects of the process -- from theory to design to practice.

Mike Frysinger
Author

Ned Ludd
Author

Robin H. Johnson
Author

Alex Tarkovsky
Author

Alexey Shvetsov
Author

Raúl Porcel
Author

Joshua Saddler
Editor

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.