Categories
Uncategorized

Introduction to OpenEmbedded part 1

This is the first in a multi-part series on the OpenEmbedded development environment.  This and subsequent articles will provide an introduction to OpenEmbedded, why to use it,  how it works, and will provide examples of how BEC has used OE in various projects.

Part 1 — Why do we need OpenEmbedded?  This article discusses some of the problems developers face when building embedded Linux systems, such as collecting the pieces needed, setting up a repeatable build environment, cross-compiling, customizing a system, and licensing issues.  Future articles will cover how OE addresses some of these issues.

Embedded Linux = Complex System

The fundamental problem with building Embedded Linux systems is the sheer complexity.  Lets face it, there is a lot going on in a typical Embedded Linux system.  Millions of lines of code are being compiled.  Typically there are tens to hundreds of applications and libraries that need to be built.  Linux supports many different processor architectures.  The size of Linux leads to the conclusion that a good deal of automation is required to manage all this.  In my paper “Tips for Planning your Embedded Linux Project” (http://bec-systems.com/web/content/view/35/37/ ), the analogy of the Iceberg is presented.  The application specific software in the project is the part of the Iceberg that is above water — the part you see.  Most of the system (Linux and system applications) is below water — you don’t see it.   The part under water is the big unknown and has the potential to add a lot of variance to a project.  Note: this problem is not specific to Linux — any system of this complexity that is targeted to so many different applications faces the same problem.  As a side, one might ask why use Linux if it is so complex?  The answer is simple — features.  Linux has the features and device support required for many Embedded products to be competitive.

Collecting and building all the pieces

There are a lot of pieces of software that need to come together to build an Embedded Linux system.  This may include a toolchain, kernel, system libraries, and many system applications and configuration scripts required to make a system work.  The is not something you want to do manually, or building an embedded Linux system quickly becomes impractical for most developers.

Repeatable Builds

With any software project, it is highly desirable to have a build system that is easily repeatable — which means it can be reproduced at any time on a wide variety of development workstations.  Some of the of the situations I have run into that are less than desirable are:

  • Being dependent on a vendor to provide a pre-compiled root file system image for a system.  What happens when you need to add something two years down the road (such as foreign language support) and you don’t have a build system where you can easily reproduce the current build?
  • Being dependent on a golden build machine that takes a lot of work to set up and is very difficult to reproduce.  If you have a build environment where all the developers use one machine to build software, you may want to investigate if you are in this situation.

What is really needed is a build system where you can check the build system out of a source control system onto about any Linux workstation at any point in time, type make, and a few hours later you have an image.

GPL Compliance

If you distribute binaries in your product compiled from GPL software, you must offer to provide the source code for these binaries.   Do you have easy access to the source for everything that is in your product?  Do you even know what all is in your product?  It is not good enough to simply point to someone else’s distribution or web site and say “I use that”.  As the founder of the MEPIS distribution discovered, the GPL license explicitly states the distributor of the GPL code is obligated to provide source code for up to 3 years.  So if you build a distribution by copying binaries from a pre-build distribution, you may have a problem.  In one case I am familiar with, a company was in the last stages of a multi-year product development cycle.  They then discovered that they did not have the source code used to build the GPL binaries in the system.  The company that built the distribution for them was out of business and the open source project the binaries where originally obtained from no longer maintained the sources.  Although it may be possible to find all of the old sources, it is a huge amount of work and would probably be easier to just start over and build new distribution.

Customizing the system

For most embedded systems, the distribution needs to be customized.  There are often requirements such as custom software update schemes.  Ideally, a good build system should easily allow you to integrate changes into the build system in a automated way, so that you don’t have any manual steps in the process of creating an image for the embedded system.

Cross Compiling

The above “repeatable build” requirement that you be able to build an image for your embedded target on about any Linux workstation leads to a requirement for cross-compiling.  Cross-compiling is the process of creating executable code for a platform different than the one on which the cross compiler is run (http://en.wikipedia.org/wiki/Cross_compiler).  Cross compiling many standard open source applications and libraries can be difficult on a good day, and near impossible on a bad day, as many of them were not written with cross compiling in mind.  Therefore, a good build environment should have tools that automate the process of cross-compiling as well as provide the ability to easily cross compile the many common programs and libraries that may be needed in an embedded Linux system.

Summary

As we examine some of the challenges, it should be obvious that putting together a production embedded Linux system is not something to be done in an ad-hoc fashion.  There are several ways to approach this problem.  Stay tuned for future articles where we explore how the OpenEmbedded build system solves these problems (subscribing to our blog or newsletter is a good way to do this).

Also, please post comments about your experiences — we like to hear and learn from you.  We are also interested in what problems you face when building Embedded systems.  This input will be used when writing future articles.  Thanks!

Categories
Uncategorized

Do you need “software update” functionality in your Embedded Linux system?

In this day and age, most embedded systems include a way for users to easily update software once the device has been deployed.  This article discusses the requirements for a field update mechanism along with pointers for how to implement.

Update Mechanism Requirements

Requirements for a field update mechanism might be:

  • easy for users to perform updates.
  • little chance of “bricking” a unit if reset occurs during update.
  • ability to update all of the software in the unit
  • in this case, update from files on a USB Storage device
  • ability to program NOR and NAND flash

Other systems may have requirements to update from a network, Compact Flash card, etc.

The USB wrinkle

System update is typically done by the bootloader.  In this case, we are using a Compulab cm-x270 module (http://bec-systems.com/site/77/compulab-cm-x270-pxa270-module-review) that has a proprietary boot loader and does not support updates from a USB storage device.  Therefore, we need to run the updates from the context of the Linux operating system which has drivers for USB and the NAND flash.  We decided that the best way in this case is to have a small Linux OS image that contains enough functionality to update the main filesystem.  This also provides us with the capability to recover if the main filesystem ever gets corrupted.  The flash layout for the system is:

Partition Flash Device Size File System Description
Kernel NOR 1536KiB NA Linux kernel
Update rootfs NOR 2304KiB Initramfs (RO) Small rootfs that contains just enough functionality to update the system
Main rootfs NAND 512MiB JFFS2 (RW) Main rootfs including application

There are other schemes that could work as well.  One way might be to have two identical application partitions and only update one at a time.  A reset while updating the kernel or the update rootfs does have the potential of “bricking” the system, but most of the updates will be for the Main rootfs, so we think this risk is low enough to be acceptable in this system.  The update rootfs is loaded into RAM before it is used, so there is little chance of it being corrupted during normal operation.  Running the update rootfs from ram is also convenient in that we can easily re-program the update rootfs in flash as we are not directly mounting the filesystem in flash.

Building the Update rootfs

The base update rootfs is built with OpenEmbedded as described in http://bec-systems.com/site/77/compulab-cm-x270-pxa270-module-review.  Once we had the system booting into the update rootfs, we had to add the following functionality:

  • Boot the main rootfs from NAND flash
  • look for update files on a USB Storage device and flash the kernel, update rootfs, and main rootfs as needed.

Booting the NAND flash image is accomplished using the busybox switch_root application.  This utility allows you to easily switch to another rootfs from an initramfs.  There are a few gotchas to be aware of when working with switch_root:

  • switch_root must be “exec’d” from the init process with PID=”1″.
  • switch_root requires a “/init” file to be present

The above functionality was accomplished by writing a shell script called /init.  If an error occurs, the /init shell script then launches the standard init process in /sbin/init which provides a terminal and allows for easy debugging.  The mtd-utils package provides a handy utility called nandwrite which can be used to write jffs2 images to NAND flash (handles bad blocks, etc).  At some point, we may remove all the extra functionality from the update rootfs like the standard sysvinit, terminal login, etc, but for now it is handy to have for debugging.  To give you an idea how easy it is to write to flash from a shell script, consider the following snippets:

# write Image into update rootfs parition
cat /usb/nor_rootfs.img > /dev/mtd2
# write Image to NAND rootfs partition
flash_eraseall /dev/mtd3
nandwrite /dev/mtd3 /usb/nand_jffs2.img
# and to launch rootfs in nand flash
exec switch_root -c /dev/console /jffs2 /sbin/init 5

Summary

Having typically used bootloaders for system update in the past, I’m very pleased with how this mechanism worked out.  Thanks to the flexibility of Linux and OpenEmbedded, this only took several days to implement and debug.  Writing update programs with shell scripts at the application level gives you a lot of flexibility and allows you to use standard Linux drivers for USB and Flash access which are very robust.  At some point if there is interest, we may look at cleaning up our code and contributing functionality to OpenEmbedded to generate a more generic update initramfs.  Please contact us or leave a comment if you are interested in collaborating on something like this.

Categories
Uncategorized

Building a tiny “safe” boot image using OpenEmbedded

We are currently working a project that contains cm-x270 module (http://bec-systems.com/web/content/view/62/9/ ) which contains 4MB of NOR flash and 128MB of NAND flash.  The Linux kernel and a small root file system (rootfs) will be stored in NOR flash, and the main rootfs in the NAND flash.  The rootfs in the NOR flash will be used to update the system from a USB Flash drive in the field.  This article describes how to build a small boot rootfs using OpenEmbedded.  We also look at various ways to store the image in flash.

Requirments

In many embedded systems, field upgrades is a requirement.  There are many ways to organize this, but one of the most reliable is to have two rootfs partitions.  The first partition is a “safe” rootfs that is only used to update the second partition.  The second partition contains the main application and can be updated in the field.  If a programming error, or power loss occurs while updating the 2nd partition,  you can always boot into the first rootfs partition and restart the process.

The kernel and the bootloader in this system take up about 1.5MB (out of 4MB total) of the NOR flash.  This leaves us with about 2.5MB for the update rootfs.  Because we are building the rest of the system using OpenEmbedded (OE), it may make sense for us to also build this update rootfs using OE to keep everything in one build environment.

uclibc, glibc, or klibc?

There are several libc libraries that are commonly used to build Embedded Linux systems.  glibc is the standard that is used in desktop and sever systems and is what is being used in the main NAND rootfs partition.   uclibc is smaller than glibc is often used in space constrained systems.  klibc is a very minimal libc subset that supports operations typically used in an initramfs.  Because we are already using glibc, we decided to try this first as we could then use the same toolchain and build tree and just generate two images — one for NAND, and one for NOR.

OpenEmbedded support for small images

OE includes a task-base-minimal meta target that can be used as a basis for a small images, or you can create your own based on task-base.  You will then need to create a custom image recipe that will use this meta task.  An example is shown below:

PR = "r0"

export IMAGE_BASENAME = "svs_nor"
export PACKAGE_INSTALL = "task-min"
# keep extra language files from being installed
export IMAGE_LINGUAS = ""

RDEPENDS = "task-min"

IMAGE_FSTYPES = "tar jffs2 ext2 cramfs squashfs squashfs-lzma cpio.gz"
IMAGE_ROOTFS_SIZE_ext2="10240"

#EXTRA_IMAGECMD_jffs2="--pad=0x1000000 --eraseblock=0x40000"
EXTRA_IMAGECMD_jffs2=""

inherit image

In this case, I had defined a custom recipe for task-min based on task-base, which installs the following packages:

root@compulab-pxa270:~$ ipkg list_installed
base-files - 3.0.14-r58 -
base-passwd - 3.5.9-r2 -
busybox - 1.2.1-r11 -
initscripts - 1.0-r86 -
ipkg - 0.99.163-r1 -
ipkg-collateral - 1.0-r5 -
libc6 - 2.5-r4 -
libgcc1 - 4.1.1-r10 -
libipkg0 - 0.99.163-r1 -
makedevs - 1.0.0-r2 -
sysvinit - 2.86-r32 -
sysvinit-inittab - 2.86-r32 -
sysvinit-pidof - 2.86-r32 -
task-min - 1.0-r1 -
tinylogin - 1.4-r3 -
update-rc.d - 0.7-r0 -

Storing the NOR filesystem in flash

OE can generate images for many different flash filesystems and initrd mechanisms.  These are specified in the IMAGE_FSTYPES variable in the above recipe.  In this case, I chose to generate many different filesystems so I could see evaluate how much compression I would get with each filesystem type.  The results:

Rootfs Type Size (bytes)
squashfs-lzma 1785856
tar.bz2 1918243
cpio.gz 2024558
squashfs 2109440
cramfs 2265088
jffs2 2455396
ext2 (uncompressed) 5481000

I ended up choosing the cpio.gz format as it can be loaded directly into an initramfs filesystem by the kernel.   There are several advantages to using an initramfs for this task:

  • You don’t have to mess around setting up tmpfs filesystems for directories that need to be writable.
  • You can update the NOR flash partition while you are running out of the initramfs filesystem.
  • It is fairly small with only squashfs-lzma being smaller.

Future Optimizations

For now, the glibc based solution is good enough because it fits in the flash space we have and it is easy to build with our existing build environment.  In the future, we may move to a uclibc or klibc based solution and try to reduce our flash size (OpenEmbedded supports both klibc and uclibc).  The above image sizes can also be reduced by removing ipkg and other components that are not needed.

This exercise illustrates many of the advantages of Linux and OpenEmbedded.  With very little work, I can produce exactly what I need.  The ability of the 2.6 Linux kernel to load a cpio archive into an initramfs is a very elegant solution for small boot images.

Categories
Uncategorized

How to build GNU/Linux for an embedded x86 computer

Recently, I had a customer who needed an embedded Linux distribution running on an Advantech PCM-9371 single board computer (SBC).  The PCM-9371 contains a low voltage Celeron or Pentium III processor.  This article describes why the Openembedded build system was chosen and a few tips for running Openembedded on a x86 system.

The hard way!

There are many ways to put Linux on a x86 embedded system.  There are hundreds of distributions out there and the temptation is always to do something “quick” and just try to trim down one of the standard distributions.  Other shortcuts are often taken, such as compiling your application on a workstation that is running a different distribution and different versions of the libraries used in the embedded systems.  This approach can work, but there are many possible pitfalls:

  • Several years down the road, it will be difficult to compile applications for your target system as the libraries on the target system are very dated compared to tools and libraries used in standard desktop distributions.  What this means is you will need to keep a “golden” compile machine around for the life of your project — not fun!  I went through an experience like this on a previous version of this same project where it took us a week to set up a build machine to compile applications using a very old version of Debian.
  • It is difficult to gather GPL sources used to build the distribution you are using.  You are required to supply GPL source code upon request to customers who purchase your product.
  • To build applications correctly, you really need a build machine that is running the same distribution as the target, unless you set up a cross-compilation or scratchbox environment.
  • Most distributions are quite large and have difficulty fitting on CF card.
  • Most distributions are difficult to customize in a clean, systematic way.

OpenEmbedded

Considering the disadvantages of using an standard x86 distribution for this project, I chose to use OpenEmbedded (OE).  The OpenEmbedded project (http://openembedded.org ) is a full featured build system for building embedded Linux distributions.  The development is done on a Linux workstation of your choice and the entire distribution is cross-compiled to the architecture of your choice.  The entire build process is automated, including building the toolchain and an image that can be installed on the target embedded system.  Some of the features of OpenEmbedded are:

  • Over 3000 packages that can be built.  About anything you would ever need for an embedded system.
  • Support for a wide variety of target architectures.  ARM and x86 processors are well supported.
  • Build system is very self contained.  This means you can do the builds on a variety of different host machines.  Many of the tools OE needs are built by OE, so there is very little dependence on host tools besides a few basics such as Python, make, and other standard tools.  This also means it is much easier to pull the build system out of the archives in several years, load it on a current machine, and do a build.
  • All source code used in the build is downloaded, so GPL compliance is easy.
  • and the list goes on …

Build and Installation

Setting up an OE build is beyond the scope of this article, but it basically involves selecting a machine and distribution.  In this case, I chose the x86 machine and the generic OE distribution.  Several hours later, I had an image in the form of a tar.gz file that I decompressed to a Compact Flash (CF) card.  After installing grub on the CF card, I had a booting Linux distribution that included all the basics (like ssh, ipkg package manager, shell, standard file utilities, etc) in less than 4MB of disk space.

Adding GTK+ and Xwindows

This system required support for GTK+ and Xwindows.  To add this involved running the following commands: bitbake xserver-kdrive and bitbake gtk+.  The OE build system then automatically downloaded and compiled the need packages.  The image size is now around 20MB — still fits very easily on a CF card.

Getting X running

There are several options for running X on a x86 system.  In this case, I chose the quickest way so that my customer could get started with application integration as quickly as possible.  Linux and Xwindows support the standard VESA Framebuffer mode.  Then can be enabled by selecting the CONFIG_FB_VESA kernel config option.  The kdrive version of X can then be started by running Xvesa.  In the future, we may move to an accelerated X driver if needed.

Summary

We now have Linux running off of a CF card with full X/GTK+ support and the customer can proceed with integration, testing and application development.  Getting to this point took about 1 day of development as we did not encounter any major problems — much less time than it took to resurrect an old build environment used in previous versions of the project.  Future work will involve integrating applications into the OE build system, and customizing the distribution as needed.  Openembedded has proved to be a very valuable tool for getting embedded Linux systems running quickly and maintaining them in a controlled way.

Categories
Uncategorized

Adding software to a Moxa UC7408 using OpenEmbedded

One of the big advantages of using Linux in embedded systems is the thousands of applications and drivers available for it (http://bec-systems.com/web/content/view/35/37/ ).  One of the challenges of Embedded Linux is building these applications.  Building applications for an embedded system often involves cross-compiling which is frustrating on a good day.  This article details how to use OpenEmbedded (OE) with the existing toolchain Moxa provides to build a number of applications for the Moxa UC7408.

Web Application Support

My needs for this project were to build a web application that ran on the UC7408 (See http://bec-systems.com/web/content/view/55/9/ for a review of the Moxa UC7408).  The Moxa firmware is fairly full featured and provides php for web application development.  This is probably fine for many applications, but I prefer to build web applications as detailed in this article: http://bec-systems.com/web/content/view/46/9/ .  Because the rest of the application is written in Python, there are advantages to also implementing the web application in Python.  I also wanted to use the sqlite database.  A quick look at the php supplied with the Moxa firmware suggested it was built without sqlite support.  In summary, I needed the following components:

  • Python
  • Clearsilver
  • sqlite
  • minicom
  • vim
  • strace
  • subversion
  • wget

The above is a fairly small list, but what you don’t see are all the dependencies that also need to be built and installed.  This ends up being many more components.   Some of the items are for development only, but this is Linux — why not have nice tools running on the target system?

OE to the rescue

Ideally, the Moxa system would have a complete root file system built with OE running on it.  But I did not have the time or budget to implement this, so I did the next best thing — use the rootfs and toolchain supplied by Moxa along with OE to compile just the applications I needed.  Typically, OE builds the toolchain and Glibc, but fortunately OE provides a very slick way to use an external toolchain and glibc with OE.  How to do this is detailed in the OE manual: http://www.openembedded.org/user-manual&dpage=commonuse_prebuilt_toolchain.  Below is the setup I used:

Environment variables:

TOOLCHAIN=/usr/local/mxscaleb/bin/
export PRE_BUILT=/usr/local/mxscaleb/armv5b-linux

export CCACHE_DIR="${TOPDIR}/ccache"
export PYTHONPATH="${TOPDIR}/bitbake/lib"
export BBPATH="${TOPDIR}:${TOPDIR}/openembedded:${TOPDIR}/bitbake"
export PATH="${TOPDIR}/bitbake/bin:${TOOLCHAIN}:${PATH}"
export LD_LIBRARY_PATH=
export LANG=C

Local.conf file:

DL_DIR = "/build/sva_oe/downloads"
BBFILES := "/build/sva_oe/openembedded/packages/*/*.bb"
BBMASK = ""
PREFERRED_PROVIDERS = "virtual/qte:qte virtual/libqpe:libqpe-opie"
PREFERRED_PROVIDERS += " virtual/libsdl:libsdl-qpe"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc-initial:gcc-cross-initial"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}gcc:gcc-cross"
PREFERRED_PROVIDERS += " virtual/${TARGET_PREFIX}g++:gcc-cross"
PREFERRED_PROVIDER_virtual/libx11 = "diet-x11"
ASSUME_PROVIDED += " virtual/${TARGET_PREFIX}gcc "
ASSUME_PROVIDED += " virtual/libc "
MACHINE = "moxa"
IPKG_ARCHS = "all arm armv4 armv5te xscale ${MACHINE}"
TARGET_CC_ARCH = "-mcpu=xscale"
TARGET_ARCH = "arm"
PACKAGE_ARCH="xscale"
TARGET_OS = "linux"
TARGET_FPU = "soft"
DISTRO = "moxa-disro"
DISTRO_NAME = "moxa-distro"
DISTRO_VERSION = "0.0.1"
DISTRO_TYPE = "release"
INHERIT += " package_ipk package_tar debian"
IMAGE_FSTYPES = "jffs2 tar"
PARALLEL_MAKE = "-j 4"
BBINCLUDELOGS = "yes"
CVS_TARBALL_STASH = "http://www.oesources.org/source/current/"
export CC  = "mxscaleb-gcc-3.3.2 ${HOST_CC_ARCH}"
export CXX = "mxscaleb-g++ ${HOST_CC_ARCH}"
export CPP = "mxscaleb-gcc-3.3.2 -E"
export LD = "mxscaleb-ld"
export AR  = "mxscaleb-ar"
export AS  = "mxscaleb-as"
export RANLIB  = "mxscaleb-ranlib"
export STRIP  = "mxscaleb-strip"
TARGET_CPPFLAGS_append = " -I${PRE_BUILT}/include "
TARGET_LDFLAGS_prepend = " -L${PRE_BUILT}/lib -Wl,-rpath-link, ...
${PRE_BUILT}/lib -Wl,-rpath-link,${PRE_BUILT}/qt2/lib "

With the above setup, I was able to build the applications I needed with very little effort.  There were a few little problems I ran into, but I was able to quickly work around them.  The result is a number of packages that can be installed on the target system:

bigreqsproto-dev-X11R7.0-1.0.2-r0.tar.gz      python-crypt-2.4.3-ml0.tar.gz
busybox-1.2.1-r1.3.tar.gz                     python-curses-2.4.3-ml1.tar.gz
busybox-udhcpd-1.2.1-r1.3.tar.gz              python-datetime-2.4.3-ml0.tar.gz
clearsilver-0.10.3-r0.tar.gz                  python-db-2.4.3-ml0.tar.gz
clearsilver-dbg-0.10.3-r0.tar.gz              python-devel-2.4.3-ml0.tar.gz
clearsilver-dev-0.10.3-r0.tar.gz              python-distutils-2.4.3-ml0.tar.gz
clearsilver-doc-0.10.3-r0.tar.gz              python-email-2.4.3-ml0.tar.gz
inputproto-dev-X11R7.0-1.3.2-r0.tar.gz        python-fcntl-2.4.3-ml0.tar.gz
ipkg-0.99.163-r1.tar.gz                       python-gdbm-2.4.3-ml0.tar.gz
ipkg-dbg-0.99.163-r1.tar.gz                   python-hotshot-2.4.3-ml0.tar.gz
ipkg-dev-0.99.163-r1.tar.gz                   python-html-2.4.3-ml0.tar.gz
kbproto-dev-X11R7.1-1.0.3-r0.tar.gz           python-idle-2.4.3-ml0.tar.gz
libapr-0-0-0.9.12-r0.tar.gz                   python-image-2.4.3-ml0.tar.gz
libapr-0-bin-0.9.12-r0.tar.gz                 python-io-2.4.3-ml0.tar.gz
libapr-0-dev-0.9.12-r0.tar.gz                 python-lang-2.4.3-ml0.tar.gz
libaprutil-0-0-0.9.12-r0.tar.gz               python-lib-old-and-deprecated-2.4.3-ml0.tar.gz
libaprutil-0-bin-0.9.12-r0.tar.gz             python-logging-2.4.3-ml0.tar.gz
libaprutil-0-dev-0.9.12-r0.tar.gz             python-mailbox-2.4.3-ml0.tar.gz
libcrypto0.9.7-0.9.7g-r1.tar.gz               python-math-2.4.3-ml0.tar.gz
libexpat-bin-2.0.0-r1.tar.gz                  python-mime-2.4.3-ml0.tar.gz
libexpat-dev-2.0.0-r1.tar.gz                  python-mmap-2.4.3-ml0.tar.gz
libexpat-doc-2.0.0-r1.tar.gz                  python-netclient-2.4.3-ml1.tar.gz
libexpat1-2.0.0-r1.tar.gz                     python-netserver-2.4.3-ml0.tar.gz
libgcrypt-dbg-1.2.2-r0.tar.gz                 python-pickle-2.4.3-ml0.tar.gz
libgcrypt-dev-1.2.2-r0.tar.gz                 python-pprint-2.4.3-ml0.tar.gz
libgcrypt-doc-1.2.2-r0.tar.gz                 python-profile-2.4.3-ml0.tar.gz
libgcrypt11-1.2.2-r0.tar.gz                   python-pydoc-2.4.3-ml0.tar.gz
libgdbm-dbg-1.8.3-r2.tar.gz                   python-pyserial-2.2-r1.tar.gz
libgdbm-dev-1.8.3-r2.tar.gz                   python-pysqlite2-2.2.2-ml1.tar.gz
libgdbm-doc-1.8.3-r2.tar.gz                   python-pyxml-0.8.4-ml0.tar.gz
libgdbm3-1.8.3-r2.tar.gz                      python-re-2.4.3-ml0.tar.gz
libgnutls-bin-1.4.0-r1.tar.gz                 python-readline-2.4.3-ml0.tar.gz
libgnutls-dbg-1.4.0-r1.tar.gz                 python-resource-2.4.3-ml0.tar.gz
libgnutls-dev-1.4.0-r1.tar.gz                 python-shell-2.4.3-ml0.tar.gz
libgnutls-doc-1.4.0-r1.tar.gz                 python-stringold-2.4.3-ml0.tar.gz
libgnutls-extra13-1.4.0-r1.tar.gz             python-subprocess-2.4.3-ml0.tar.gz
libgnutls-locale-en+boldquot-1.4.0-r1.tar.gz  python-syslog-2.4.3-ml0.tar.gz
libgnutls-locale-en+quot-1.4.0-r1.tar.gz      python-terminal-2.4.3-ml0.tar.gz
libgnutls-locale-pl-1.4.0-r1.tar.gz           python-tests-2.4.3-ml0.tar.gz
libgnutls-openssl13-1.4.0-r1.tar.gz           python-textutils-2.4.3-ml0.tar.gz
libgnutls13-1.4.0-r1.tar.gz                   python-threading-2.4.3-ml0.tar.gz
libgpg-error-dbg-1.3-r1.tar.gz                python-tkinter-2.4.3-ml0.tar.gz
libgpg-error-dev-1.3-r1.tar.gz                python-unittest-2.4.3-ml0.tar.gz
libgpg-error-locale-de-1.3-r1.tar.gz          python-unixadmin-2.4.3-ml0.tar.gz
libgpg-error-locale-fr-1.3-r1.tar.gz          python-xml-2.4.3-ml0.tar.gz
libgpg-error-locale-pl-1.3-r1.tar.gz          python-xmlrpc-2.4.3-ml0.tar.gz
libgpg-error-locale-ro-1.3-r1.tar.gz          python-zlib-2.4.3-ml1.tar.gz
libgpg-error-locale-vi-1.3-r1.tar.gz          sqlite3-3.3.7-r2.tar.gz
libgpg-error0-1.3-r1.tar.gz                   sqlite3-dbg-3.3.7-r2.tar.gz
libice-dbg-X11R7.1-1.0.1-r0.tar.gz            strace-4.5.14-r3.tar.gz
libice-dev-X11R7.1-1.0.1-r0.tar.gz            strace-dbg-4.5.14-r3.tar.gz
libice6-X11R7.1-1.0.1-r0.tar.gz               strace-doc-4.5.14-r3.tar.gz
libipkg-dev-0.99.163-r1.tar.gz                subversion-1.3.1-r1.tar.gz
libipkg0-0.99.163-r1.tar.gz                   subversion-dbg-1.3.1-r1.tar.gz
liblzo-dbg-1.08-r14.tar.gz                    subversion-dev-1.3.1-r1.tar.gz
liblzo-dev-1.08-r14.tar.gz                    subversion-doc-1.3.1-r1.tar.gz
liblzo1-1.08-r14.tar.gz                       subversion-locale-de-1.3.1-r1.tar.gz
libneon-bin-0.25.5-r0.tar.gz                  subversion-locale-es-1.3.1-r1.tar.gz
libneon-dev-0.25.5-r0.tar.gz                  subversion-locale-fr-1.3.1-r1.tar.gz
libneon-doc-0.25.5-r0.tar.gz                  subversion-locale-it-1.3.1-r1.tar.gz
libneon25-0.25.5-r0.tar.gz                    subversion-locale-ja-1.3.1-r1.tar.gz
libpython2.4-1.0-2.4.3-ml5.tar.gz             subversion-locale-ko-1.3.1-r1.tar.gz
libreadline-dbg-4.3-r3.tar.gz                 subversion-locale-nb-1.3.1-r1.tar.gz
libreadline-dev-4.3-r3.tar.gz                 subversion-locale-pl-1.3.1-r1.tar.gz
libreadline-doc-4.3-r3.tar.gz                 subversion-locale-pt-br-1.3.1-r1.tar.gz
libreadline4-4.3-r3.tar.gz                    subversion-locale-sv-1.3.1-r1.tar.gz
libsm-dbg-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-cn-1.3.1-r1.tar.gz
libsm-dev-X11R7.1-1.0.1-r0.tar.gz             subversion-locale-zh-tw-1.3.1-r1.tar.gz
libsm6-X11R7.1-1.0.1-r0.tar.gz                tcl-8.4.11-r3.tar.gz
libsqlite-bin-2.8.17-r2.tar.gz                tcl-dbg-8.4.11-r3.tar.gz
libsqlite-dbg-2.8.17-r2.tar.gz                tcl-dev-8.4.11-r3.tar.gz
libsqlite-dev-2.8.17-r2.tar.gz                tcl-doc-8.4.11-r3.tar.gz
libsqlite0-2.8.17-r2.tar.gz                   time-1.7-r0.tar.gz
libsqlite3-0-3.3.7-r2.tar.gz                  time-dbg-1.7-r0.tar.gz
libsqlite3-dev-3.3.7-r2.tar.gz                time-doc-1.7-r0.tar.gz
libssl0.9.7-0.9.7g-r1.tar.gz                  tmp
libx11-6-X11R7.1-1.0.1-r1.tar.gz              update-rc.d-0.7-r0.tar.gz
libx11-dbg-X11R7.1-1.0.1-r1.tar.gz            util-macros-dev-X11R7.1-1.0.2-r0.tar.gz
libx11-dev-X11R7.1-1.0.1-r1.tar.gz            vim-7.0-r0.tar.gz
libx11-doc-X11R7.1-1.0.1-r1.tar.gz            vim-doc-7.0-r0.tar.gz
libx11-locale-X11R7.1-1.0.1-r1.tar.gz         vim-help-7.0-r0.tar.gz
libxau-dbg-X11R7.1-1.0.1-r0.tar.gz            vim-syntax-7.0-r0.tar.gz
libxau-dev-X11R7.1-1.0.1-r0.tar.gz            vim-tutor-7.0-r0.tar.gz
libxau-doc-X11R7.1-1.0.1-r0.tar.gz            wget-1.9.1-r6.tar.gz
libxau6-X11R7.1-1.0.1-r0.tar.gz               wget-dbg-1.9.1-r6.tar.gz
libxdmcp-dbg-X11R7.1-1.0.1-r0.tar.gz          wget-doc-1.9.1-r6.tar.gz
libxdmcp-dev-X11R7.1-1.0.1-r0.tar.gz          wget-locale-bg-1.9.1-r6.tar.gz
libxdmcp6-X11R7.1-1.0.1-r0.tar.gz             wget-locale-ca-1.9.1-r6.tar.gz
libxml2-2.6.22-r3.tar.gz                      wget-locale-cs-1.9.1-r6.tar.gz
libxml2-dbg-2.6.22-r3.tar.gz                  wget-locale-da-1.9.1-r6.tar.gz
libxml2-dev-2.6.22-r3.tar.gz                  wget-locale-de-1.9.1-r6.tar.gz
libxml2-doc-2.6.22-r3.tar.gz                  wget-locale-el-1.9.1-r6.tar.gz
libxml2-utils-2.6.22-r3.tar.gz                wget-locale-es-1.9.1-r6.tar.gz
libxt-dbg-X11R7.1-1.0.2-r0.tar.gz             wget-locale-et-1.9.1-r6.tar.gz
libxt-dev-X11R7.1-1.0.2-r0.tar.gz             wget-locale-fr-1.9.1-r6.tar.gz
libxt-doc-X11R7.1-1.0.2-r0.tar.gz             wget-locale-gl-1.9.1-r6.tar.gz
libxt6-X11R7.1-1.0.2-r0.tar.gz                wget-locale-he-1.9.1-r6.tar.gz
libz-dbg-1.2.3-r1.tar.gz                      wget-locale-hr-1.9.1-r6.tar.gz
libz-dev-1.2.3-r1.tar.gz                      wget-locale-hu-1.9.1-r6.tar.gz
libz1-1.2.3-r1.tar.gz                         wget-locale-it-1.9.1-r6.tar.gz
minicom-2.1-r0.tar.gz                         wget-locale-ja-1.9.1-r6.tar.gz
minicom-dbg-2.1-r0.tar.gz                     wget-locale-nl-1.9.1-r6.tar.gz
minicom-doc-2.1-r0.tar.gz                     wget-locale-no-1.9.1-r6.tar.gz
ncurses-5.4-r8.tar.gz                         wget-locale-pl-1.9.1-r6.tar.gz
ncurses-dbg-5.4-r8.tar.gz                     wget-locale-pt-br-1.9.1-r6.tar.gz
ncurses-dev-5.4-r8.tar.gz                     wget-locale-ro-1.9.1-r6.tar.gz
ncurses-doc-5.4-r8.tar.gz                     wget-locale-ru-1.9.1-r6.tar.gz
ncurses-terminfo-5.4-r8.tar.gz                wget-locale-sk-1.9.1-r6.tar.gz
ncurses-tools-5.4-r8.tar.gz                   wget-locale-sl-1.9.1-r6.tar.gz
openssl-0.9.7g-r1.tar.gz                      wget-locale-sv-1.9.1-r6.tar.gz
openssl-dbg-0.9.7g-r1.tar.gz                  wget-locale-tr-1.9.1-r6.tar.gz
openssl-dev-0.9.7g-r1.tar.gz                  wget-locale-uk-1.9.1-r6.tar.gz
openssl-doc-0.9.7g-r1.tar.gz                  wget-locale-zh-cn-1.9.1-r6.tar.gz
python-audio-2.4.3-ml0.tar.gz                 wget-locale-zh-tw-1.9.1-r6.tar.gz
python-bsddb-2.4.3-ml0.tar.gz                 xcmiscproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-codecs-2.4.3-ml0.tar.gz                xextproto-dev-X11R7.0-7.0.2-r0.tar.gz
python-compile-2.4.3-ml0.tar.gz               xf86bigfontproto-dev-X11R7.0-1.1.2-r0.tar.gz
python-compiler-2.4.3-ml0.tar.gz              xproto-dev-X11R7.1-7.0.5-r0.tar.gz
python-compression-2.4.3-ml0.tar.gz           xtrans-dev-X11R7.0-1.0.0-r1.tar.gz
python-core-2.4.3-ml1.tar.gz

Installing the needed packages is just a matter of uncompressing a subset of the above files on the target system.

Summary

This exercise demonstrates how a developer can quickly (took me less than 4 hours) add a large number of applications (and dependencies) to about any Embedded Linux system.  Leveraging embedded Linux is being able to use the components you need.  Please contact us if you would like additional details or assistance.