You are previewing Pro Linux Embedded Systems.
O'Reilly logo
Pro Linux Embedded Systems

Book Description

Modern embedded hardware is more sophisticated than ever: most systems include the capabilities found on desktop systems. This book is written from the perspective of a user employing technologies and techniques typically reserved for desktop systems.

Table of Contents

  1. Copyright
  2. About the Author
  3. About the Technical Reviewer
  4. Acknowledgments
  5. Introduction
  6. 1. About Embedded Linux
    1. 1.1. Why Use Embedded Linux?
      1. 1.1.1. Technical Reasons to Use Embedded Linux
        1. 1.1.1.1. Standards Based
        2. 1.1.1.2. Process Isolation and Control
          1. 1.1.1.2.1. Manage and Isolate Tasks
          2. 1.1.1.2.2. Memory Management and Linux
          3. 1.1.1.2.3. Uniform Interface to Resources
          4. 1.1.1.2.4. System Calls
        3. 1.1.1.3. Peripheral Support
        4. 1.1.1.4. Security
          1. 1.1.1.4.1. SELinux
          2. 1.1.1.4.2. PAM
          3. 1.1.1.4.3. IPsec
      2. 1.1.2. Commercial Reasons to Use Embedded Linux
        1. 1.1.2.1.
          1. 1.1.2.1.1. Complete Software Ecosystem
          2. 1.1.2.1.2. No Royalties
          3. 1.1.2.1.3. Control
    2. 1.2. 10,000-Foot Embedded Linux Development Flyover
      1. 1.2.1. Target Hardware
      2. 1.2.2. Obtaining Linux
      3. 1.2.3. Booting Linux
      4. 1.2.4. Development Environment
      5. 1.2.5. System Design
    3. 1.3. Anatomy of an Embedded Linux System
      1. 1.3.1. Boot Loader
      2. 1.3.2. Kernel
      3. 1.3.3. Root File System
      4. 1.3.4. Your Application
      5. 1.3.5. Cross-Compiler
      6. 1.3.6. Tools of the Trade
        1. 1.3.6.1. The GNU Compiler Collection
          1. 1.3.6.1.1. GDB
        2. 1.3.6.2. BusyBox
        3. 1.3.6.3. uClibc
        4. 1.3.6.4. Automake/Autoconf
        5. 1.3.6.5. Packaging Systems
        6. 1.3.6.6. Patch
        7. 1.3.6.7. Make
    4. 1.4. Where to Get Help
      1. 1.4.1. University of Google
      2. 1.4.2. Mailing Lists and Newsgroups
        1. 1.4.2.1. Etiquette
      3. 1.4.3. Vendor-Sponsored Resources
      4. 1.4.4. Trade Group and Community Interest Sites
      5. 1.4.5. IRC
    5. 1.5. Next Up
  7. 2. Configuring the Software Environment
    1. 2.1. Host Environment
      1. 2.1.1. Linux
        1. 2.1.1.1. Debian (Ubuntu) Systems
        2. 2.1.1.2. RPM
      2. 2.1.2. Windows
        1. 2.1.2.1. Cygwin
          1. 2.1.2.1.1. Installation
          2. 2.1.2.1.2. Cygwin's View of the File System
        2. 2.1.2.2. Virtual Linux Machines on Windows
          1. 2.1.2.2.1. Using VirtualBox
    2. 2.2. Host Services
      1. 2.2.1. Turn Off Your Firewall
      2. 2.2.2. TFTP
      3. 2.2.3. DHCP
      4. 2.2.4. NFS
        1. 2.2.4.1. NFS with Cygwin
      5. 2.2.5. PXE
    3. 2.3. Cabling
      1. 2.3.1. Serial (for Console)
      2. 2.3.2. Network
    4. 2.4. Avoiding an Angry Visit from IT
      1. 2.4.1. Dual-Homed Host
  8. 3. Target Emulation and Virtual Machines
    1. 3.1. Why Target Emulation?
    2. 3.2. Emulation via QEMU
      1. 3.2.1. Compiling QEMU
      2. 3.2.2. Using QEMU to Emulate a Target
      3. 3.2.3. Using QEMU to Compile under Emulation
    3. 3.3. Virtualization Software for x86 Hosts
      1. 3.3.1. Approaches to Virtualization
    4. 3.4. Summary
  9. 4. Starting Your Project
    1. 4.1. Most Boards Include a Linux Distribution
    2. 4.2. What to Do After Unpacking the Board
      1. 4.2.1. Have Linux? Boot It!
      2. 4.2.2. Assess the Kernel
        1. 4.2.2.1. Locate Sources and Patches
        2. 4.2.2.2. Locate the Configuration
      3. 4.2.3. Understand the RFS
        1. 4.2.3.1. File System Format
        2. 4.2.3.2. Locate Sources for the Root File System
        3. 4.2.3.3. Devices and In-Memory File Systems
    3. 4.3. Suitability for Your Project
      1. 4.3.1. Cross-Compiler
    4. 4.4. Moving Forward
  10. 5. Getting Linux for Your Board
    1. 5.1. Obtaining Linux from the Board Vendor
      1. 5.1.1. Questions You Should Ask Your Board Vendor
      2. 5.1.2. Now That You're a Customer...
    2. 5.2. Open Source Embedded Distributions
      1. 5.2.1. Why Embedded Linux Distribution Builders Exist
      2. 5.2.2. Should You Use One?
      3. 5.2.3. Popular Open Source Embedded Distributions
        1. 5.2.3.1. LTIB (http://www.bitshrine.org)
          1. 5.2.3.1.1. Using LTIB
          2. 5.2.3.1.2. LTIB Tricks
          3. 5.2.3.1.3. Getting Help
        2. 5.2.3.2. Buildroot (http://buildroot.uclibc.org/)
          1. 5.2.3.2.1. Using Buildroot
          2. 5.2.3.2.2. Buildroot Tricks
          3. 5.2.3.2.3. Getting Help
        3. 5.2.3.3. OpenEmbedded (http://wiki.openembedded.net/)
          1. 5.2.3.3.1. Using OpenEmbedded
          2. 5.2.3.3.2. Getting Help
    3. 5.3. Getting Linux from Commercial Vendors and Consultants
      1. 5.3.1. Do You Need a Commercial Vendor?
      2. 5.3.2. What You Should Expect
      3. 5.3.3. Roundup of Vendors
        1. 5.3.3.1. Wind River
        2. 5.3.3.2. MontaVista
        3. 5.3.3.3. Embedded Alley
        4. 5.3.3.4. DENX
        5. 5.3.3.5. Free Electrons
        6. 5.3.3.6. Code Sourcery
    4. 5.4. What's Next
  11. 6. Creating a Linux Distribution from Scratch
    1. 6.1. Cross-Compiler Basics
      1. 6.1.1. A Note about Building Software
      2. 6.1.2. Get Comfortable with the Command Line
    2. 6.2. Overview of Building a GCC Cross-Compiler
      1. 6.2.1. The C Library
      2. 6.2.2. Gathering Sources
        1. 6.2.2.1. Getting Sources via Source Control
          1. 6.2.2.1.1. Binutils
          2. 6.2.2.1.2. GCC
          3. 6.2.2.1.3. Glibc
          4. 6.2.2.1.4. GMP and MPFR
          5. 6.2.2.1.5. A Linux Kernel
        2. 6.2.2.2. Getting via Source Archives
          1. 6.2.2.2.1. Binutils
          2. 6.2.2.2.2. Glibc
          3. 6.2.2.2.3. GCC
          4. 6.2.2.2.4. GMP and MPFR
          5. 6.2.2.2.5. A Linux Kernel
      3. 6.2.3. Building GCC
        1. 6.2.3.1. The Build Environment
        2. 6.2.3.2. Binutils
        3. 6.2.3.3. Kernel Headers
        4. 6.2.3.4. Bootstrap (Stage 1) GCC
        5. 6.2.3.5. Creating Glibc Headers
        6. 6.2.3.6. Building Glibc
        7. 6.2.3.7. Building the Next GCC
        8. 6.2.3.8. Building GMP and MPFR
          1. 6.2.3.8.1. GMP
          2. 6.2.3.8.2. MPFR
        9. 6.2.3.9. Building the Final GCC
    3. 6.3. Building Toolchains with Crosstool-NG
    4. 6.4. Creating the Root File System
      1. 6.4.1. Configuring the Environment
      2. 6.4.2. Building and Installing BusyBox
      3. 6.4.3. Libraries
      4. 6.4.4. Creating Device Nodes and Directories
      5. 6.4.5. Finishing Touches
      6. 6.4.6. Building the Kernel
      7. 6.4.7. Troubleshooting Booting Problems
        1. 6.4.7.1. Improperly Configured Board
        2. 6.4.7.2. The Root File System Can't Be Mounted
        3. 6.4.7.3. The Root File System init Program Doesn't Run
    5. 6.5. Distributing the Distribution
    6. 6.6. Wrapping Up
  12. 7. Booting the Board
    1. 7.1. Booting a Linux System Is a Three-Act Play
      1. 7.1.1. The Boot Loader
      2. 7.1.2. Kernel-Land vs. Userland
    2. 7.2. Boot Loaders
      1. 7.2.1.
        1. 7.2.1.1. RedBoot
          1. 7.2.1.1.1. Using RedBoot
        2. 7.2.1.2. YAMON
        3. 7.2.1.3. Das U-Boot
          1. 7.2.1.3.1. Using U-Boot
        4. 7.2.1.4. LILO
        5. 7.2.1.5. GRUB
      2. 7.2.2. About Flash Memory
    3. 7.3. Kernel Startup
      1. 7.3.1. The Kernel Entry Point
        1. 7.3.1.1. Sysfs and Device Management
        2. 7.3.1.2. Finding a Root File System
          1. 7.3.1.2.1. NFS Root File Systems
      2. 7.3.2. Userland Startup
        1. 7.3.2.1. What an Init Program Needs to Do
        2. 7.3.2.2. Mysteries of the /etc/init.d Directory
      3. 7.3.3. BusyBox Init
      4. 7.3.4. Your Init
    4. 7.4. What's Next
  13. 8. Configuring the Application Development Environment
    1. 8.1. Pick the Right Tool for the Job
    2. 8.2. Know Your Application
      1. 8.2.1. Hardware Constraints
        1. 8.2.1.1. Software Constraints
    3. 8.3. What to Use for Development
      1. 8.3.1. C
      2. 8.3.2. C++
      3. 8.3.3. Java
        1. 8.3.3.1. Java Runtime Environment
        2. 8.3.3.2. Embedding Java: Using GCJ
        3. 8.3.3.3. Compiling Java Code with GCJ
        4. 8.3.3.4. Embedded GCJ
    4. 8.4. Non-Traditional Embedded Languages
      1. 8.4.1. Python
        1. 8.4.1.1. Embedding Python
        2. 8.4.1.2. Debugging
      2. 8.4.2. TCL
        1. 8.4.2.1. Embedding TCL
        2. 8.4.2.2. Debugging
      3. 8.4.3. Shell Scripting
        1. 8.4.3.1. Embedded Shell Scripting
      4. 8.4.4. PHP
        1. 8.4.4.1. Embedding PHP
    5. 8.5. Performance and Profiling Tools
      1. 8.5.1. Profiling
        1. 8.5.1.1. Gprof Option Reference
      2. 8.5.2. Leak Detection
        1. 8.5.2.1. dmalloc
        2. 8.5.2.2. Mpatrol
      3. 8.5.3. Static Analysis
    6. 8.6. IDE
      1. 8.6.1. Your Editor + Make + Shell
        1. 8.6.1.1. Using Make
      2. 8.6.2. Eclipse
        1. 8.6.2.1. Installing Eclipse and Plug-ins
        2. 8.6.2.2. Using Eclipse
    7. 8.7. What's Next
  14. 9. Application Development
    1. 9.1. Getting Started on Your Application
    2. 9.2. Desktop vs. Target
      1. 9.2.1. Coding for Portability
      2. 9.2.2. System Differences
        1. 9.2.2.1. FIFO
    3. 9.3. Hello World
      1. 9.3.1. Getting the Tools
      2. 9.3.2. Making Make Work
      3. 9.3.3. Running the Code on the Target
      4. 9.3.4. More Complex Projects
    4. 9.4. Getting Ready for Debugging
    5. 9.5. What's Next
  15. 10. Debugging Applications
    1. 10.1. Getting Started on Your Application
    2. 10.2. Types of Debugging
    3. 10.3. Remote Debugging Overview
    4. 10.4. Debugging C and C++
      1. 10.4.1. Building GDB
      2. 10.4.2. GDB Front Ends
      3. 10.4.3. Compiling for Debugging
        1. 10.4.3.1. GDB Command Line Survival Guide
        2. 10.4.3.2. Remote Debugging with DDD
        3. 10.4.3.3. Remote Debugging with GNU Emacs
        4. 10.4.3.4. Remote Debugging with Eclipse
    5. 10.5. Debugging Java
    6. 10.6. Instrumentation
    7. 10.7. Java Instrumentation
    8. 10.8. Instrumentation in Scripting Languages
    9. 10.9. What's Next
  16. 11. Kernel Configuration and Development
    1. 11.1. Kernel Project Layout
      1. 11.1.1. Downloading the Kernel
        1. 11.1.1.1. Downloading a Compressed Tar File
        2. 11.1.1.2. Using Git to Clone the Repository
    2. 11.2. Building the Kernel
      1. 11.2.1. How Kernel Configuration Works
      2. 11.2.2. Default Configurations
      3. 11.2.3. Editing .config By Hand
      4. 11.2.4. Building the Kernel
      5. 11.2.5. Building Modules
      6. 11.2.6. Cleaning Up
    3. 11.3. Open Source Community
      1. 11.3.1. The Kernel Development Process
      2. 11.3.2. Contributing to the Linux Kernel
      3. 11.3.3. Applying Patches
      4. 11.3.4. What's Next
  17. 12. Real Time
    1. 12.1.
      1. 12.1.1. Real-Time Core Concepts
        1. 12.1.1.1. Deadline
        2. 12.1.1.2. Latency
        3. 12.1.1.3. Jitter
        4. 12.1.1.4. Predictability
        5. 12.1.1.5. Worst Case
        6. 12.1.1.6. Priority Inversion
        7. 12.1.1.7. Periodic Task
      2. 12.1.2. The Linux Scheduler
        1. 12.1.2.1. Group Scheduling
      3. 12.1.3. Real-Time Scheduler
    2. 12.2. Real-Time Implementation in Linux
      1. 12.2.1. Getting the Patch
    3. 12.3. Real-Time Programming Practices
      1. 12.3.1. The One Real-Time Process
      2. 12.3.2. Lock Memory
      3. 12.3.3. Avoid the Heap
      4. 12.3.4. Asking for Priority Inheritance Mutexes
      5. 12.3.5. I/O Is Nondeterministic
      6. 12.3.6. Using Thread Pools
      7. 12.3.7. LatencyTOP
    4. 12.4. Common Hardware Pitfalls
      1. 12.4.1. System Management Interrupts
      2. 12.4.2. VGA Console
      3. 12.4.3. DMA Bus Mastering
    5. 12.5. Summary
  18. 13. Using Open Source Software Projects
    1. 13.1. Using Open Source Packages
      1. 13.1.1. How an Open Source Project Is Structured
      2. 13.1.2. The Project Team Isn't Your Extended Workforce
      3. 13.1.3. Understand the Licensing
        1. 13.1.3.1. Permissive vs. Restrictive Licenses
        2. 13.1.3.2. Common Licensing Types
      4. 13.1.4. Downloading
      5. 13.1.5. Using Source Control Systems to Fetch Code
        1. 13.1.5.1. Using CVS
        2. 13.1.5.2. Using Subversion
        3. 13.1.5.3. Using Git
        4. 13.1.5.4. Using Mercurial
      6. 13.1.6. Cross-Compiling
      7. 13.1.7. Using configure
        1. 13.1.7.1. Creating the Script
        2. 13.1.7.2. Gaming the Cache
        3. 13.1.7.3. Installation
        4. 13.1.7.4. Setting Other Configure Options
        5. 13.1.7.5. Configuration Process for Non-Automake Projects
      8. 13.1.8. Building and Installing
    2. 13.2. Commonly Used Projects
      1. 13.2.1. DirectFB
      2. 13.2.2. Dropbear
      3. 13.2.3. QT/Qtopia
      4. 13.2.4. JamVM
      5. 13.2.5. Rzsz
      6. 13.2.6. Netcat
      7. 13.2.7. TinyXML
      8. 13.2.8. Micro_httpd
      9. 13.2.9. Stupid-FTPd
      10. 13.2.10. Quagga
      11. 13.2.11. Tslib
      12. 13.2.12. fgetty
  19. 14. BusyBox
    1. 14.1. How a BusyBox-Based System Is Structured
    2. 14.2. Building a BusyBox-Based System
      1. 14.2.1. Download the Software
      2. 14.2.2. Configure
        1. 14.2.2.1. Build
          1. 14.2.2.1.1. Static or Shared?
        2. 14.2.2.2. Install
        3. 14.2.2.3. Copy Libraries
        4. 14.2.2.4. Default Init Scripts
        5. 14.2.2.5. Update Permissions
        6. 14.2.2.6. Create Additional Folders
        7. 14.2.2.7. Create Device Nodes
    3. 14.3. What Makes BusyBox Small?
    4. 14.4. Creating Your Own Applet
      1. 14.4.1. Create the Applet Code
        1. 14.4.1.1. Add the Applet to the Make File
        2. 14.4.1.2. Register Applet with BusyBox
        3. 14.4.1.3. Add Help Text
        4. 14.4.1.4. Build and Verify
    5. 14.5. Getting Help
    6. 14.6. What's Next
  20. 15. System Design
    1. 15.1. The Big Picture
    2. 15.2. Configuring the Boot Loader and Kernel
      1. 15.2.1. U-Boot
      2. 15.2.2. Other Boot loaders
      3. 15.2.3. Execute in Place
    3. 15.3. Selecting a Root File System
      1. 15.3.1. Block-Based File Systems
        1. 15.3.1.1. Ext2
        2. 15.3.1.2. Ext3
        3. 15.3.1.3. SquashFS
        4. 15.3.1.4. CramFS
        5. 15.3.1.5. Romfs
        6. 15.3.1.6. MINIX
      2. 15.3.2. MTD File Systems
        1. 15.3.2.1. JFFS2
        2. 15.3.2.2. YAFFS2
      3. 15.3.3. RAM Buffer-Based File Systems
        1. 15.3.3.1. Rafms
        2. 15.3.3.2. Tmpfs
        3. 15.3.3.3. Initramfs
      4. 15.3.4. File System Pairings
    4. 15.4. Assembling a Root File System
      1. 15.4.1. Create the Staging Area
      2. 15.4.2. Create a Directory Skeleton
      3. 15.4.3. Gather Libraries and Required Files
        1. 15.4.3.1. Required Files
      4. 15.4.4. Create Initialization Scripts
        1. 15.4.4.1. Using Init and Inittab
        2. 15.4.4.2. Using a Script
        3. 15.4.4.3. Using a Program
      5. 15.4.5. Set Ownership and Permissions
    5. 15.5. Security
      1. 15.5.1. Built-In Security
      2. 15.5.2. SELinux
        1. 15.5.2.1. Reference Policies
        2. 15.5.2.2. Using SEEdit
      3. 15.5.3. PAM
    6. 15.6. What's Next
  21. 16. System Tuning
    1. 16.1.
      1. 16.1.1. Three or Fewer Megabytes
      2. 16.1.2. 16–32 Megabytes
      3. 16.1.3. More than a Gigabyte
    2. 16.2. Reducing the Size of the Root File System
      1. 16.2.1. Start from Zero
        1. 16.2.1.1. Mounting Small File Systems
        2. 16.2.1.2. Shared Libraries
      2. 16.2.2. Compiling to Save Space
        1. 16.2.2.1. GCCs -Os
        2. 16.2.2.2. Static Linking
        3. 16.2.2.3. Stripping
    3. 16.3. Reducing the Size of the Kernel
      1. 16.3.1. Removing Unneeded Features and Drivers
        1. 16.3.1.1. Recommendations for Embedded Systems
        2. 16.3.1.2. Measuring
        3. 16.3.1.3. Using the Bloat-O-Meter
    4. 16.4. Minimizing Boot Time
      1. 16.4.1. Reducing Kernel Boot-Up Time
        1. 16.4.1.1. Uncompressed Kernel Image
        2. 16.4.1.2. No Console Output on Boot
        3. 16.4.1.3. Deferred Initialization
        4. 16.4.1.4. No Kernel Modules
      2. 16.4.2. Measuring Kernel Boot-Up Times
        1. 16.4.2.1. /proc/uptime
        2. 16.4.2.2. Grabserial
        3. 16.4.2.3. Initcall_debug
      3. 16.4.3. Reducing Root File System Startup Times
        1. 16.4.3.1. Use a Read-Only File System
        2. 16.4.3.2. Replacing Initialization Scripts
        3. 16.4.3.3. Inittab Abuse
        4. 16.4.3.4. Link with GNU Hash Style
    5. 16.5. What's Next
  22. 17. Deploying Applications
    1. 17.1. Deployment for Embedded Devices
      1. 17.1.1. Requirements
      2. 17.1.2. Industrial Design
      3. 17.1.3. Mechanical Design
      4. 17.1.4. Electrical Engineering
      5. 17.1.5. Manufacturing Engineering
      6. 17.1.6. Software Design
      7. 17.1.7. Software Engineering
      8. 17.1.8. Manufacturing
    2. 17.2. Deployment Strategies and Tactics
    3. 17.3. Boot Loaders
      1. 17.3.1. In General
      2. 17.3.2. UBOOT: Configuring Initial Parameters
      3. 17.3.3. Expect
        1. 17.3.3.1. Installing Expect
        2. 17.3.3.2. Expect on Windows
        3. 17.3.3.3. Using Expect
      4. 17.3.4. Boot Loaders Are Just Programs
    4. 17.4. Deployment Root File Systems
      1. 17.4.1. Application Files and Libraries
        1. 17.4.1.1. Small Root File Systems
      2. 17.4.2. First Field Update at the Factory
    5. 17.5. What's Next
  23. 18. Handling Field Updates
    1. 18.1. Root File System Updates
      1. 18.1.1. Basic Strategies
      2. 18.1.2. Forklift Upgrade
        1. 18.1.2.1. Designing for Forklift Upgrades
        2. 18.1.2.2. MTD Utilities
        3. 18.1.2.3. Forklift-Upgrade Example
      3. 18.1.3. Parallel Systems
        1. 18.1.3.1. Parallel System Example
      4. 18.1.4. Do It Yourself
        1. 18.1.4.1. Do-It-Yourself Example
      5. 18.1.5. Using Package Managers
        1. 18.1.5.1. RPM
          1. 18.1.5.1.1. Using RPM
          2. 18.1.5.1.2. Using YUM
        2. 18.1.5.2. Dpkg
          1. 18.1.5.2.1. Creating a dpkg
          2. 18.1.5.2.2. Remote Update with Debian
          3. 18.1.5.2.3. Using APT
        3. 18.1.5.3. Ipkg
          1. 18.1.5.3.1. Getting the Sources
          2. 18.1.5.3.2. Creating an Ipkg
          3. 18.1.5.3.3. Creating a Feed
      6. 18.1.6. Initramfs Root File Systems
    2. 18.2. Kernel Updates
      1. 18.2.1. Basic Strategies
        1. 18.2.1.1. Update Kernel Modules
        2. 18.2.1.2. Forklift Upgrade
      2. 18.2.2. Modules
        1. 18.2.2.1. Using Modprobe
        2. 18.2.2.2. Roll Your Own
      3. 18.2.3. Forklift
    3. 18.3. Field Update Failures
      1. 18.3.1. Report Failure, Stop
      2. 18.3.2. Failsafe Root File System
      3. 18.3.3. Failsafe Kernel
    4. 18.4. In Summary