Legacy Development and Integration Guide

From RidgeRun Developer Connection
Revision as of 10:40, 18 March 2010 by Mrodriguez (Talk | contribs)

Jump to: navigation, search

Linux Application Development

This section targets software developers with a little background on Linux software development, presenting some basic concepts about Linux applications that may be unfamiliar to developers with experience in real time operating systems (RTOS).

Linux application development is more like standard PC application development and less like RTOS focused development. The main differences is the clear separation between the applications and the operating system and also that applications are stored on a file system.

This section doesn't replace a good book on Linux/Unix software development, but introduces the minimal concepts that will be useful when porting applications.

Kernel and User Space

Linux is a multi-tasking operating system with protection between executing processes.Therefore applications run in their own address-space which is provided by the kernel using the hardware memory management unit (MMU).

Since applications are separate from the kernel, they live on some file system, therefore Linux needs a least one file system holding the initial applications: the root file system.

The File System

Linux file system is based on Unix file system concepts, and therefore it is composed of a tree of files that are located on some physical storage. The physical storage should provide the root of the tree (the root file system) and other devices can be “mounted” at directories in the file system tree.

Following the Unix mindset, most of the computer universe is represented like a file: files are data containers for more than binary executable files or raw data stored on memory devices, files are also used to represent device drivers, interprocess pipes, or system status.

Unix file system layout is also important, as there are standard locations for configuration files, shared libraries, binaries, shared data, etc.

Pseudo file systems

Linux has several pseudo file systems that when mounted doesn't reflect actual stored files on some memory device, but file handlers that can provide information about the system, a process, a driver, etc. This pseudo file systems generate the file entries and contents dynamically, based on the system status.

The two more common pseudo-file systems are procfs, and sysfs. More information on those can be found on the next section.

Linux File System Layout

Understanding the Linux file system layout is important for the porting process. The following table explains what's the propose for most common locations and give you an idea or where to store the contents of your application.

Location Propose
/bin Intended for executable binaries required for the basic system.
/sbin Intended for executable binaries required for the basic system that should be available only to the super (root) user.
/lib Shared libraries for the basic system.
/etc Text configuration files of the basic system.
/tmp Temporary files: on most embedded systems this directory contents are lost between power cycles.
/var Intended to store data from system programs: web server pages, log files, mail server data, etc.
/proc This is the typical mount point of Linux's pseudo file system procfs, which creates a set of files that contain different aspects of the running system, processes, drivers, etc.
/sys This is the typical mount point of Linux's pseudo file system sysfs, which provides information on, and control of, devices drivers and kernel objects.
/opt Intended for applications that don't form part of the standard system provided by the vendor. These are usually third-party applications. Most of the applications at this location don't conform to the bin/lib separation of the Unix file systems.
/usr/bin Intended for executable binaries that are not required for the basic system.
/usr/sbin Intended for executable binaries that are not required for the basic system that should be available only to the super user.
/usr/lib Shared libraries not required for the basic system.
Embedded Linux File System

The standard Linux file system is designed for use by more than one person at a time. This is rarely the case on an embedded device, so the difference between /bin, /sbin, /usr/bin, /usr/sbin,/opt may seem less useful than for standard desktop computing proposes.

However one of the important uses of this separation is that it simplifies the final layout of the file systems used by the embedded target. RidgeRun applies the following rules to decide where to locate the applications:

  • /bin, /sbin: minimal binaries to boot the system
  • /usr/bin, /usr/sbin: standard Linux applications that are not required to boot the system
  • /opt: customer applications

This layout permits different mount points to be used for the /usr and /opt directories which allows:

  • Creating smaller minimal root file system to speed up booting (depends on the file system technology used), or that using a read only file system.
  • Simplifying software upgrades
  • Security analysis is simplified if suspect activities are limited to a small part of the file system.
Embedded target file system

RidgeRun SDK creates the target file system on the Linux host machine, and processes it to create the proper target file system image to be downloaded (if required) to the embedded system. The file system of the target system is found under the base (referred to as $DEVDIR) of your SDK: $(DEVDIR)/fs/fs.

This directory only exist once you have built the SDK for the first time, and you can copy files to this location to include them in the target file system image.

Since the file system of the target should have a minimal footprint, the SDK only puts the strictly necessary parts of the applications into this directory, leaving out some run-time unnecessary parts of many programs like include files, manual and info pages, unused localizations, etc. However some of this files (like the includes) may be required during the compilation process for other programs. For this propose the SDK provides the directory $DEVDIR/fs/fsdev, which is the typical installation point of most applications (including all the unnecessary run-time files), and later the scripts of the application copy the minimal parts from $(DEVDIR)/fs/fsdev towards $(DEVDIR)/fs/fs . More information on this procedure will be explained later on this document.

SDK build system

Building software for embedded systems is a complex task as it typically involves cross-compiling. Cross compiling presents new challenges to already established procedures for building software. The RidgeRun SDK uses a build system that simplifies the complexities of cross compiling.

The SDK build system was designed by embedded Linux programmers for embedded Linux programmers, therefore it not only simplifies the process of building embedded Linux applications, but the process of integrating, using or developing open source tools or packages with the SDK.

Introduction to RidgeRun SDK build system

Embedded Linux software development differs in various ways from the two environments it mixes: “embedded” and “Linux”.

Embedded Linux differs from most embedded environments using an RTOS in that Linux uses a file system outside the kernel, and advanced software tools like dynamic loaded libraries, multiple applications, dynamic modules, powerful networking tools and high modularity are supported.

An often overlook but crucial difference between Linux and other RTOS systems has to do with the dynamics of building and integrating open source software. Open source software is build by different communities around the world, and a typical embedded Linux system will include pieces from hundreds of developers and several different open source projects. This factor impacts various processes: system integration, application building, bug reporting, etc.RidgeRun support services minimizes this complexity by providing a single point to get access to embedded Linux support experts, but also by accounting this factor on the design of the build system.

Embedded Linux also differs from standard Linux distributions in its requirements for custom tailored kernel, drivers, and file system. Embedded limitations on footprint, power consumption and processing power create a big gap between embedded and desktop Linux systems.

All the previously mentioned details need to be taken into account by the development procedures for building and packaging the software for embedded Linux. We found three different approaches from SDK providers to build the system (with RidgeRun using the last option):

Binary software distributions: some embedded Linux providers ship the file system applications pre-compiled for the target hardware. This approach provides the advantage that the overhead and work to recompile the basic system is avoided, however also presents several disadvantages:

  • Minimal footprint is not achieved as the system is often compiled with broader-audience by including generic features.
  • The packages may have been compiled with or without features required by the customer, therefore requiring the re-compilation of certain packages.
  • Incompatibility of binary code with other software provided by third parties (For example if the object files uses different ABIs).
  • In some cases getting the proper code that matches the binary files may be challenging for debugging or tracing proposes.
  • The binary-oriented design usually lacks proper support to simplify building code from source.

Source software distributions by emulation: some embedded Linux providers use a source building based system that is compiled by running a virtual machine emulating the target hardware and using the compiler natively on the emulated target. This approach has valuable advantages:

  • Avoids the complexities of cross compiling: open source tools like autotools are in better position to properly evaluate the environment, and several other tricks required for cross compiling are not required.
  • Allows building optimized code for the target hardware.
  • Allows creating optimized footprint and features on the compiled software.
  • Permits testing on the emulated environment.

The disadvantages of this system are:

  • Overhead on setup, maintenance and build time due the simulated environment. On big systems the compilation delays my be noticeable.
  • Development files that are not required will be included on the target file system.
  • Building and maintaining an accurate emulation environment is complex and time consuming.

Source software distributions by cross compilation: consists on building the applications from source for the target hardware from the host target. The advantages are:

  • Allows building optimized code for the target hardware.
  • Allows creating optimized footprint and features on the compiled software.
  • Compilation and build time are typically fast as the host machine is usually more powerful than the target.

The disadvantages of this system are:

  • Requires special procedures and manual tweaking when cross-compiling complex applications; for example open source software using autotools requires special steps, since many run time detections can't be performed while cross compiling.
  • Dependency handling between open source packages require special tools.

RidgeRun SDK build system is a source distribution built using cross compilation, and has minimized the complexities of it by defining a centralized system to simplify tool usage, the setting of compilation flags, dependency handling and minimizing host tools requirements.

SDK build tools

The SDK build system is based on a set of technologies commonly found on standard Linux developer machines:

  • The GNU Make system (http://www.gnu.org/software/make/), is used for the core build system logic.
  • Bash shell scripts are used to automated certain tasks.
  • A extended Linux kernel “kconfig” style system, along with custom logic in makefiles, is used to integrate the bootloader, kernel, file sytem and toolchain build and configuration system.
  • The SDK detects and installshost tools required to build the bootloader, kernel, and Linux libraries and applications.

The set of tools were selected are generally available on most systems, and can be extended to integrate with more sophisticated IDEs like Eclipse, or can be used standalone.

The SDK requires a Linux host machine for development, RidgeRun recommends Ubuntu. Please consult the SDK User Guide or RidgeRun support for the latest information on supported distributions.

Anatomy of a build system

An embedded Linux build system can be analyzed by how well it supports the requirements and the components used to meet those requirements. The RidgeRun SDK build system is composed by:

Centralized configuration system: a single system where the user can control the features and components of the software to be build.

Centralized build system: a single system that is responsible for building the software according to the configuration files generated by the configuration tool.

Application build tools: a set of tools and guidelines that provided support for target applications build process (as described in this document), such:

  • Application locations
  • Standard targets for the Makefiles
  • How to define dependencies, or provide dependency information
  • How to provide global definitions for other the applications
  • How to discover global definitions from other applications
  • How to define host applications requirements

SDK Build system basics

The SDK build system needs to be understood to easily integrate new applications and port existing applications.

Configuration system

The SDK uses a dynamic configuration utility, called kconfig, which is shared by other important projects of the open source community, for example the Linux Kernel and the busybox set of tools.

The kconfig system used by RidgeRun differs from standard versions:

  • Customized for SDK usage (file names and menus).
  • The search path for the configuration files has base directories, supporting then integration of the kernel and busybox configurations in a single configuration tool.
  • Supports extra logic in the SDK makefiles to permit dynamic additions to the menu based on external conditions. For example, when a new application is added to the system it is include in the menus without any programming effort.

The build system provides a way to add menus to the configuration system and associate that value to a variable that can later be accessed by the Makefiles to effect decisions or translate it as a compile definition. For example the definition:

   config FS_APPS_MYAPP
         bool “myapp”

will create a definition:


if selected as true on the configuration system. Note that the suffix “CONFIG_” was added to the variable name. Those definitions can be used by the Makefiles by including the file $DEVDIR/bsp/mach/Make.conf

For more information on the syntax of the configuration files used by the kconfig system and the different options please consult $DEVDIR/bsp/bspc/kconfig-language.txt.

Build stages

The SDK build system builds difference components and this order may be important when building software that relays on other definitions or libraries. The SDK build order is:

  • kernel: compiled and kernel images are generated.
  • fs: built and file system images are generated.
  • bootloader: built and the bootloader images are generated. In addtion repacking of the fs and kernel images into the native format of the bootloader (for example .rr images for rrload or .uImage for u-boot) is performed.

The applications from the file system are separated in different directories, and are build in the following order:

  • fs/apps: consists mostly of architecture independent programs.
  • fs/arch: contains programs that are common between all the systems within this hardware family. For example, this directory contains all the generic code for Davinci processors in DM6446 SDK.
  • fs/mach: contains the specific code for the target hardware (the “machine” specific code).
  • fs/proprietary_src: is an optional build stage, if some third party proprietary binary code is included with the SDK, then this code is built at this point.
  • fs/myapps: is the stage where the customer applications stored in the $DEVDIR/myapps directory are built.

The order in which the directories are built inside the specific fs stages defaults to alphabetically sorted directory names. If some application requires a dependent code to be build first, the order can be changed by using the metainfo system explained later on this document.

Makefile integration with the configuration system

The different makefiles of the system can be integrated with the configuration system by including a couple of files providing:

  • Definitions matching the selected configuration of the SDK.
  • Toolchain definitions and flags.
  • Information regarding other applications or libraries of the system that your application may want to use.

All three are described in detail throughout the rest of this document.

Integrating applications in the SDK

Customers are encouraged to create their applications in the $DEVDIR/myapps directory. Use of the other file system build points is not recommended. For example if you want to create a newapp application, you should proceed to create a directory $DEVDIR/myapps/newapp/.

Your application needs some elements in order for the application to be compiled by the SDK:

  • Config file: this an file integrating your application with the SDK configuratio system.
  • Makefile file: this is a set of rules to build/install your application.
  • metainfo file: this is an optional file that may be used to report dependencies of your application on the target machine (some library you require to be installed) or the host machine (if you need certain tool on the host to compile the application).

In this section we will guide you through the process of creating these files for the newapp application. It is recommended that you read the SDK User Guide before reading this section, and also have used and familiarized yourself with the SDK.

Integration with the configuration system

To integrate your application with the configuration system you have to create a file named Config in the application directory. This file contains logic to select if your application should be built within the SDK. A simple example file is:

        bool “NewApp Customer Application”
                Build my NewApp program

In addition, you can use the Config file to force the selection of other configuration options on the SDK (kernel features, libraries, etc). To do this all you need to do is to get the string of the definition you want to enable and add a select statement for it (shown later).

For example, if your application requires zlib (an open source application for compression) then you may use the following code to force incluing of zlib if your application is selected:

        bool “NewApp Customer Application”
        select FS_APPS_ZLIB
                Build my NewApp program

The name of the zlib configuration variable may be queried using the “help” of the feature in the configuration menu system. For example the help of “File System Applications -> SDK Applications -> zlib 1.2.3” says CONFIG_FS_APPS_ZLIB (just strip the prefix CONFIG_).

For further information about the syntax of this file check $DEVDIR/bsp/bspc/kconfig-language.txt. You can look at other Config files in the SDK to find one that is similar to your needs and use it as your starting point.

Once the Config file is created, you can run the “make config” target on your system to enable the the new application to be built and installed in the target file system. A screen will appear as follow:

Fig.1: Adding a new application