Building an OpenEmbedded workspace

OpenEmbedded is a great tool for building Linux for an embedded system.  Over the next few posts, I hope to capture the step-by-step instructions needed to create a working Linux system for the Atmel AT91SAM9263-EK board.

OpenEmbedded provides a framework that promotes cross compiling in a “emerge”-like manner.  Relying on BitBake (derived from “emerge”, in fact) as its under-the-hood workhorse, OE creates a sandboxed build system that is entirely self-contained.  Entire systems can be created with a single command and, more importantly, without having to understand the complexities of cross compiling!

This first post will focus on creating a working build system.  By the conclusion, you will be able to compile binary images for the target board.  Follow-up posts will show you how to load the binary images onto the target, create your own custom target board, and then roll your own Linux distribution.

Definitions:

  • Architecture (ARCH). The target’s CPU architecture — in our example, the AT91SAM9263 Rev B. processor.
  • Build host. A “regular” computer that will be used to compile all of the programs needed for the target.
  • OE. Abbreviation for “OpenEmbedded.”
  • Target. The embedded system on which we want Linux to run — in our example, the AT91SAM9263-EK board.

OE requires certain prerequisites to start its build process.  You will need a PC running Linux as the build host.  OE supports many different distributions, so check for specific support required for your particular Linux flavor. Regardless of distribution, you will likely need between 32 GB and 64 GB of free space to begin the process.

I use Gentoo as my build host, so the following instructions will add all prerequisites:

# emerge -n \
  psyco \
  ccache \
  patch \
  make \
  sed \
  dev-lang/python \
  m4 \
  bison \
  cvs \
  openjade \
  quilt \
  sgmltools-lite \
  docbook-xml-dtd \
  docbook-dsssl-stylesheets \
  xmlto \
  docbook-sgml-utils \
  libpcre \
  boost \
  subversion \
  texi2html \
  pysqlite

First, create a directory for your workspace.  I literally use the name “workspace” unless there is a need to support several build systems at the same time.

# mkdir ~/workspace

Next, create a directory for all of the source files that are downloaded (tarballs, subversion snapshots, etc.)  Since these files can be shared across multiple workspaces — aren’t the GCC sources the same regardless of what platform you use? — we put them in a common location to avoid cluttering the hard drive:

# mkdir ~/sources

While most instructions at this point will tell you to export a lot of system variables, I use a Makefile to help coordinate all of the building activities.  It helps when jumping from one workspace to another by providing a single set of commands that operate no matter which workspace you’re using.

Download the Makefile and save it to ~/workspace/Makefile.

Your directory structure resembles the following:

# tree --filelimit 5 --dirsfirst -F --noreport
.
|-- sources/
`-- workspace/
    `-- Makefile

There are four basic targets (e.g. commands) supported:

make workspace
make update
make image [IMG="..."]
make bb PACKAGE="..." [CMD="..."]

The first target, make workspace, downloads the Bitbake and OE files required.

The second target, make update, will update Bitbake and OE to the latest version in their respective repositories.  USE THIS COMMAND WITH CAUTION!  Your build may stop working if an upstream change breaks something unexpectedly.  Once you get a system running, you will almost never want to run this command.

The third target, make image, does the bulk of the work, creating the desired image.  To change the image created, either modify the target in the Makefile or pass the image name through the optional IMG variable.

The fourth target, make bb, executes Bitbake directly and is useful for package development.  The name of the package should go in the PACKAGE variable, while any particular command arguments for Bitbake should go in the optional CMD variable.

Next, modify ~/workspace/local/conf/local.conf to define your particular target. For the AT91SAM9263-EK target, the file should look something like this:

DL_DIR = "/home/chris/sources"

# BitBake configuration
BBFILES = "/home/chris/workspace/openembedded/recipes/*/*.bb"
BBFILES += "/home/chris/workspace/local/recipes/*/*.bb"
BBFILE_COLLECTIONS="upstream local"
BBFILE_PATTERN_upstream = "^/workspace/openembedded/"
BBFILE_PATTERN_local = "^/workspace/local/"
BBFILE_PRIORITY_upstream = "5"
BBFILE_PRIORITY_local = "10"
BBMASK = ""

# Uncomment the next line to have BitBake output debug messages
# BBDEBUG = "yes"

# Uncomment the next line to have BitBake emit a log upon an error
BBINCLUDELOGS = "yes"

# OpenEmbedded configuration
MACHINE="at91sam9263ek"
DISTRO="angstrom-2008.1"
IMAGE_FSTYPES = "jffs2"
ENABLE_BINARY_LOCALE_GENERATION = "0"
# GLIBC_GENERATE_LOCALES = "en_US.UTF-8"

# Select between multiple alternative providers, if more than one is eligible.
PREFERRED_PROVIDERS = "virtual/qte:qte virtual/libqpe:libqpe-opie"
PREFERRED_PROVIDERS += " virtual/libsdl:libsdl-x11"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-intermediate:gcc-cross-intermediate"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross"

Note in the file above, we did not use the ~/workspace abbreviation of the path. BitBake does not like the ~ operator, so we must use the fully-qualified directory name (FQDN) of /home/chris/workspace instead. (Replace /home/chris with whatever ~ is for your system.)

Stop at this point and make sure that your directory structure resembles the following:

# tree --filelimit 5 --dirsfirst -F --noreport
.
|-- sources/
`-- workspace/
    |-- bitbake/
    |-- local/
    |   |-- conf/
    |   |   `-- local.conf
    |   `-- recipes/
    |       `-- images/
    |           `-- dummy-image.bb
    |-- openembedded/
    `-- Makefile

We are now ready to begin the build process.  This will take a LONG time, even on the fastest of machines.  (My average compile from scratch takes approximately 4 hours on a dual-processor 2.4 GHz dedicated system with 4 GB of RAM.)  I recommend starting this when you have other things to do:

# make
BB_ENV_EXTRAWHITE="WORKSPACE" /home/chris/workspace/bitbake/bin/bitbake console-image
Foo None
NOTE: Handling BitBake files: | (5591/7047) [79 %]
   NOTE: Angstrom DOES NOT support bluez-utils because bluez-utils 3.x has been replaced by bluez4
NOTE: Handling BitBake files: \ (5600/7047) [79 %]
   NOTE: Angstrom DOES NOT support bluez-utils because bluez-utils 3.x has been replaced by bluez4
NOTE: Angstrom DOES NOT support bluez-libs because bluez-libs 3.x has been replaced by bluez4
NOTE: Angstrom DOES NOT support bluez-libs because bluez-libs 3.x has been replaced by bluez4
NOTE: Handling BitBake files: \ (5613/7047) [79 %]
   NOTE: Angstrom DOES NOT support bluez-libs because bluez-libs 3.x has been replaced by bluez4
NOTE: Handling BitBake files: / (7047/7047) [100 %]
NOTE: Parsing finished. 0 cached, 6757 parsed, 290 skipped, 0 masked.
NOTE: Resolving any missing task queue dependencies
...

There is a slim chance that the build will exit prematurely, complaining of some error. Try to fix whatever the problem is, then start make again to pick up where you left off. Handling errors that occur during the build process will be a different posting.

If everything succeeds, you will be told so and dropped back to the command prompt. Congratulations! You have a working OpenEmbedded build system.

At this point, you’re ready to load the files onto the board. But that is a discussion for the next posting.

2 thoughts on “Building an OpenEmbedded workspace

  1. Pingback: Headnut.org » Flashing the AT91SAM9263-EK Board

  2. Pingback: Headnut.org » Customizing OpenEmbedded

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.