Customizing OpenEmbedded

This third post in a series focuses on creating your own “distribution” using OpenEmbedded. The instructions below assume that you have a working build system that can produce binaries that run on the Atmel AT91SAM9263-EK board using NAND flash memory.

Our goal at the end of this post is to have an OE environment that:

  1. builds images for a custom board based on the AT91SAM9263-EK;
  2. adds the patches needed for the custom board to AT91Bootstrap, U-boot, and the Linux kernel; and
  3. creates a custom root filesystem, bundled with programs that you want installed in the default image.

Lots to do, so let’s get started!

Creating the Agama9263 Machine

The Agama9263 machine will be a spin-off of the Atmel AT91SAM9263-EK. The quick overview of technical specifications for this new machine is below:

  • Atmel AT91SAM9263 Rev. B processor
  • 18.432 MHz main crystal
  • ~200 Hz master clock
  • Numonyx NAND02GW3B2D NAND flash (256 MB, 8-bit wide)
  • (2) Micron MT48LC8M16A2B4 SDRAM (Each 32 MB, 16-bit wide — connected in 32-bit wide mode for 64 MB total RAM)
  • (2) USB host ports
  • (1) USB gadget port (for programming)
  • (1) RS-232 Debug UART port (/dev/ttyS0, for programming)
  • (1) RS-232 UART port (/dev/ttyS1, for user output)

A high-level block diagram of the Agama9263 is available.

Since this machine is based on an existing one, we first start by copying the OE machine configuration file:

# cd ~/workspace/local/conf/machine
# cp at91sam9263ek.conf agama9263.conf

Load up the new file in your favorite editor and let’s tweak it:

#@TYPE: Machine
#@Name: Agama9263 from Headnut.org
#@DESCRIPTION: Machine configuration for the Agama9263 board with a at91sam9263 processor

TARGET_ARCH = "arm"
#PACKAGE_EXTRA_ARCHS = "armv4t armv5te"

PREFERRED_PROVIDER_virtual/kernel = "linux"
PREFERRED_VERSION_linux = "2.6.28"
PREFERRED_PROVIDER_xserver = "xserver-kdrive"

KERNEL_IMAGETYPE = "uImage"
UBOOT_MACHINE = "agama9263_nandflash_config"
AT91BOOTSTRAP_MEDIA = "nandflash"

PREFERRED_VERSION_at91bootstrap = "1.14"

#don't try to access tty1
USE_VT = "0"

MACHINE_FEATURES = "kernel26 ext2 usbhost usbgadget screen touchscreen"
EXTRA_IMAGEDEPENDS += "u-boot"
EXTRA_IMAGEDEPENDS += "at91bootstrap"

# used by sysvinit_2
SERIAL_CONSOLE = "115200 ttyS1"
IMAGE_FSTYPES ?= "jffs2"
EXTRA_IMAGECMD_jffs2 = "--pad --little-endian --eraseblock=0x20000 -n"

require conf/machine/include/tune-arm926ejs.inc

We also need to update ~/workspace/local/conf/local.conf to point to this new machine:

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 = "agama9263"
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"

Now the remainder of the work involves porting the various applications that have board-specific support.

Modifying AT91Bootstrap

In our second post, we created a new recipe for AT91Bootstrap that added version 1.14 to OE. Now we need to take that one step further, adding our custom board to the AT91Bootstrap sources. To get started, create a repository for our patches:

# mkdir -p ~/workspace/local/recipes/at91bootstrap/at91bootstrap-1.14/agama9263

Download at91bootstrap-1.14-agama9263.patch and save it to ~/workspace/local/recipes/at91bootstrap/at91bootstrap-1.14/agama9263/. Next, modify at91bootstrap_1.14.bb to include the following:

DESCRIPTION = "at91bootstrap: loaded into internal SRAM by AT91 BootROM"
SECTION = "bootloaders"
PR = "r0"

SRC_URI = " \
     ftp://www.linux4sam.org/pub/at91bootstrap/AT91Bootstrap${PV}.zip \
"

SRC_URI_append_agama9263 = " \
     file://at91bootstrap-1.14-agama9263.patch;patch=1;pnum=0 \
"

S = "${WORKDIR}/Bootstrap-v${PV}"
PACKAGE_ARCH = "${MACHINE_ARCH}"
EXTRA_OEMAKE = "CROSS_COMPILE=${TARGET_PREFIX} DESTDIR=${DEPLOY_DIR_IMAGE} REVISION=${PR}"

AT91BOOTSTRAP_MEDIA ?= "nandflash"

do_compile () {
     unset LDFLAGS
     unset CFLAGS
     unset CPPFLAGS

     rm -Rf ${S}/board/${MACHINE}/${AT91BOOTSTRAP_MEDIA}/${AT91BOOTSTRAP_MEDIA}_${MACHINE}.bin
     rm -Rf ${S}/board/${MACHINE}/${AT91BOOTSTRAP_MEDIA}/${AT91BOOTSTRAP_MEDIA}_${MACHINE}.elf
     rm -Rf ${S}/board/${MACHINE}/${AT91BOOTSTRAP_MEDIA}/${AT91BOOTSTRAP_MEDIA}_${MACHINE}.map
     oe_runmake -C ${S}/board/${MACHINE}/${AT91BOOTSTRAP_MEDIA} AT91_CUSTOM_FLAGS="${AT91BOOTSTRAP_FLAGS}" rebuild
}

do_install () {
     install -d ${DEPLOY_DIR_IMAGE}
     install -m 0755 \
          ${S}/board/${MACHINE}/${AT91BOOTSTRAP_MEDIA}/${AT91BOOTSTRAP_MEDIA}_${MACHINE}.bin \
          ${DEPLOY_DIR_IMAGE}/${MACHINE}-${AT91BOOTSTRAP_MEDIA}boot-${PV}-${PR}.bin
     rm -Rf ${DEPLOY_DIR_IMAGE}/at91bootstrap.bin
     cd ${DEPLOY_DIR_IMAGE} \
          && ln -sf ${MACHINE}-${AT91BOOTSTRAP_MEDIA}boot-${PV}-${PR}.bin at91bootstrap.bin
}

And that’s all, folks. The beauty of OE is that such complex tasks like adding board support are made so ridiculously simple at the build level.

You can incrementally rebuild AT91Bootstrap through the make bb PACKAGE="at91bootstrap" command. (Remember to do it once with CMD="-c clean" and again with no CMD argument.)

Modifying U-boot

Similar to the process we followed with AT91Bootstrap, a patch must be added to the U-boot recipe. For the Agama9263 machine, we’ve provided one for you.

Before we apply the patch, however, we must first create a copy of the U-boot recipe into our local overlay. While we’re doing this, let’s go ahead and make the machine-specific subfolder for the patch require:

# cp -R ~/workspace/openembedded/recipes/u-boot/ \
     ~/workspace/local/recipes/u-boot/
# mkdir -p ~/workspace/local/recipes/u-boot/u-boot-2009.01/agama9263/

Download u-boot-2009.01-agama9263.patch and save it to ~/workspace/local/recipes/u-boot/u-boot-2009.01/agama9263/. Next, let’s modify the u-boot_2009.01.bb recipe to include the patch:

require u-boot.inc

PV = "2009.01"

DEFAULT_PREFERENCE = "-1"

DEFAULT_PREFERENCE_at91rm9200dk  = "1"
DEFAULT_PREFERENCE_at91sam9rlek  = "1"
DEFAULT_PREFERENCE_at91sam9260ek = "1"
DEFAULT_PREFERENCE_at91sam9261ek = "1"
DEFAULT_PREFERENCE_at91sam9g20ek = "-1"
DEFAULT_PREFERENCE_at91sam9263ek = "1"
DEFAULT_PREFERENCE_at91cap9adk   = "1"
DEFAULT_PREFERENCE_atngw100      = "1"
DEFAULT_PREFERENCE_atstk1000     = "1"
DEFAULT_PREFERENCE_agama9263     = "1"

PR = "r1"

SRC_URI = "ftp://ftp.denx.de/pub/u-boot/u-boot-${PV}.tar.bz2"

SRC_URI_append_at91sam9263ek = " \
     file://u-boot-2009.01-exp-002-at91sam9g20ek.patch;patch=1 \
     file://u-boot-2009.01-exp-003-drivers-net-macb.c.patch;patch=1 \
"

SRC_URI_append_at91sam9g20ek = " \
     file://u-boot-2009.01-exp-002-at91sam9g20ek.patch;patch=1 \
     file://u-boot-2009.01-exp-003-drivers-net-macb.c.patch;patch=1 \
     file://at91sam9g20-fix-config.patch;patch=1 \
"

SRC_URI_append_agama9263 = " \
     file://u-boot-2009.01-exp-002-at91sam9g20ek.patch;patch=1 \
     file://u-boot-2009.01-exp-003-drivers-net-macb.c.patch;patch=1 \
     file://u-boot-2009.01-agama9263.patch;patch=1;pnum=0 \
"

Thus has support for the Agama9263 platform been added to U-boot.

Like with AT91Bootstrap, you can incrementally rebuild U-boot through the make bb PACKAGE="u-boot" command. (Remember to do it once with CMD="-c clean" and again with no CMD argument.)

Modifying the Linux Kernel

Finally, we perform the same process in modifying the Linux kernel.  At this point, try to make the modifications needed, using the linux-2.6.28-agam9263.patch and defconfig provided.

Once you are finished or get stuck, take a look below for the recommended approach:

# mkdir -p ~/workspace/local/recipes/linux
# cp ~/workspace/openembedded/recipes/linux/linux.inc \
     ~/workspace/local/recipes/linux/
# cp ~/workspace/openembedded/recipes/linux/linux_2.6.28.bb \
     ~/workspace/local/recipes/linux/
# cp -R ~/workspace/openembedded/recipes/linux/linux-2.6.28/ \
     ~/workspace/local/recipes/linux/linux-2.6.28/
# mkdir -p ~/workspace/local/recipes/linux/linux-2.6.28/agama9263/

Because there are a huge number of files in ~/workspace/openembedded/recipes/linux/, we cherry pick only the ones needed.  Next, modify the linux_2.6.28.bb file:

require linux.inc

PR = "r11"

DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_agama9263 = "28"
DEFAULT_PREFERENCE_at91sam9263ek = "28"

SRC_URI = " \
     ${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.28.tar.bz2 \
     file://linux-2.6.28-at91.patch.bz2;patch=1 \
     file://linux-2.6.28-exp.patch.bz2;patch=1 \
     file://defconfig \
"

SRC_URI_append_agama9263= " \
     file://linux-2.6.28-agama9263.patch;patch=1;pnum=0 \
"

S = "${WORKDIR}/linux-2.6.28/"

Rebuild through the make bb PACKAGE="linux" command.

Building the Root Filesystem

The final step is to build a root filesystem for our new machine.  We want to create our own custom root filesystem (a.k.a. “image” in the OE terminology), and so need to create a corresponding recipe for it.

Create ~/workspace/local/recipes/images/headnut-image.bb with the following content:

export IMAGE_BASENAME = "headnut-image"

PREFERRED_PROVIDER_virtual/psplash      = "psplash/angstrom"
PREFERRED_PROVIDER_virtual/xserver      = "xserver-xorg"
PREFERRED_PROVIDER_xserver              = "xserver-xorg"

SPLASH                                  = "psplash-angstrom"
DISTRO_SSH_DAEMON                       = "openssh"
XSERVER                                 = "xserver-xorg xf86-input-evdev xf86-input-keyboard xf86-input-mouse xf86-video-fbdev"

IMAGE_LINGUAS = ""

DEPENDS = "task-base"

ANGSTROM_EXTRA_INSTALL ?= ""
IMAGE_INSTALL = " \
     task-base-extended \
     apache2 \
     dhclient \
     inetutils \
     libpam \
     msmtp \
     ntp \
     openldap \
     python \
     python-pygtk \
     rng-tools \
     socketcan-modules \
     socketcan-utils-test \
     sqlite3 \
     syslog-ng \
     ${DISTRO_SSH_DAEMON} \
     ${SPLASH} \
     ${XSERVER} \
     ${ANGSTROM_EXTRA_INSTALL} \
"

# create /etc/timestamp from build date
IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp"

inherit image

Two key aspects of the image recipe are marked in red.  The first is the name of the image.  The output image will have a name that corresponds to this field.  The second is the IMAGE_INSTALL variable.  The programs listed in this variable (whitespace separated) are installed in the actual root filesystem.  From our list of programs above, you’ll notice that we’re producing a fairly heavy-set image: Apache, OpenLDAP, etc.  Tweak this list to match your particular desires/needs.

Use the images that come with OE to help guide you in modifying this file.  The images are located in ~/workspace/openembedded/recipes/images/ and range from very basic (minimal-image.bb) to very complex.

The command from ~/workspace/ to accomplish this is simply:

# make image IMG="headnut-image"

Alternatively, you can modify the Makefile to replace the default IMG value and omit it from the command line above.

This one line kicks off a long bundling process.  Take a break while the computer works.

From the Agama9263 to the …?

Unfortunately, the Agama9263 doesn’t actually exist, so loading firmware onto that board will be difficult.  🙂  Suffice to say that if you follow the instructions above and apply your own patches to AT91Bootstrap, U-boot, and Linux, you should be successful at getting your board up and running.

Feel free to use the patches for the Agama9263 as a starting point for your own modifications to those programs.  (The patches were directly derived from those needed for an actual board, so have been tested on live hardware.  Names were changed to protect the innocent.)

Disclaimer

Sadly to say in our “sue-first” world, I need to write the following disclaimer:

This information is provided for educational purposes only.  Headnut.org nor its owner (“AUTHOR”) does not warrant that the information is accurate in every respect.  Author is not responsible for errors, omissions, or inaccuracies of the information or the results obtained from use of the information provided herein.  Users are always encouraged to check and confirm the information with other sources and through direct professional contact.

Restriction of Liability

Author makes no claims, promises or guarantees about the accuracy, completeness, or adequacy of the contents of this web site and expressly disclaims liability for errors and omissions in the contents of this web site. No warranty of any kind, implied, expressed or statutory, including but not limited to the warranties of non-infringement of third party rights, title, merchantablility, fitness for a particular purpose and freedom from computer virus, is given with respect to the contents of this web site or its hyperlinks to other Internet resources. Reference in this web site to any specific commercial products, processes, or services, or the use of any trade, firm or corporation name is for the information and convenience of the public, and does not constitute endorsement, recommendation, or favoring by Author.

Ownership

Information presented on this web site is considered public information and may be distributed or copied. However, all information submitted to Author via this site shall be deemed and remain the property of Author, except those submissions made under separate legal contract.  Author shall be free to use, for any purpose, any ideas, concepts, or techniques contained in information provided to Author through this site.

Next Steps

Congratulations!  You’ve now taken OpenEmbedded all the way from setup to deployment.  However, you may have run into some headaches along the way.  Very soon, we will investigate troubleshooting techniques and best practices to use with OE.

5 thoughts on “Customizing OpenEmbedded

  1. Great job!
    It took me 3 weeks to set my board up… If only these 3 articles were available at the time, ahhhh… 🙂

    Now a noob question:

    I have another board based on at91sam9261 and there is very little information on it (unless u speak Chinese, and I don’t). Is there any way I can find out whether it’s dataflash or nand based? Is it safe to experiment with data/nand images on it to find out?

    • Hi Sasho,

      Thank you. Glad this article set helps in some fashion.

      To start searching for the answer to your question, I’d recommend going back to the source. Atmel has a lot of great information on the AT91SAM9261 CPU on their website. The datasheet for the CPU (sometimes called “Preliminaries”) should indicate whether booting from nandflash is supported.

      A quick Google search using “at91sam9261 boot nandflash” revealed an answer. User ivunin indicates that on page 83 of the AT91SAM9261 preliminary, Atmel specifically mentions that booting from nandflash is not supported. It looks like dataflash must be used to boot, and then nandflash can be used for partitions like /usr or similar.

      Best of luck,
      Chris

  2. This is great work, OE seems to have one of the steepest learning curves in the entire field of embedded programming. Partly because so many people have documented things they only partly understand. These guides have helped me a great deal, so thanks.

Leave a Reply to Chris Cancel reply

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

Time limit is exhausted. Please reload the CAPTCHA.