Contents
Foreword for the First Edition
Foreword for the Second Edition
Preface
Acknowledgments for the First Edition
Acknowledgments for the Second Edition
About the Author
Chapter 1 Introduction
1.1 Why Linux?
1.2 Embedded Linux Today
1.3 Open Source and the GPL
1.3.1 Free Versus Freedom
1.4 Standards and Relevant Bodies
1.4.1 Linux Standard Base
1.4.2 Linux Foundation
1.4.3 Carrier-Grade Linux
1.4.4 Mobile Linux Initiative: Moblin
1.4.5 Service Availability Forum
1.5 Summary
1.5.1 Suggestions for Additional Reading
Chapter 2 The Big Picture
2.1 Embedded or Not?
2.1.1 BIOS Versus Bootloader
2.2 Anatomy of an Embedded System
2.2.1 Typical Embedded Linux Setup
2.2.2 Starting the Target Board
2.2.3 Booting the Kernel
2.2.4 Kernel Initialization: Overview
2.2.5 First User Space Process: init
2.3 Storage Considerations
2.3.1 Flash Memory
2.3.2 NAND Flash
2.3.3 Flash Usage
2.3.4 Flash File Systems
2.3.5 Memory Space
2.3.6 Execution Contexts
2.3.7 Process Virtual Memory
2.3.8 Cross-Development Environment
2.4 Embedded Linux Distributions
2.4.1 Commercial Linux Distributions
2.4.2 Do-It-Yourself Linux Distributions
2.5 Summary
2.5.1 Suggestions for Additional Reading
Chapter 3 Processor Basics
3.1 Stand-Alone Processors
3.1.1 IBM 970FX
3.1.2 Intel Pentium M
3.1.3 Intel Atom
3.1.4 Freescale MPC7448
3.1.5 Companion Chipsets
3.2 Integrated Processors: Systems on Chip
3.2.1 Power Architecture
3.2.2 Freescale Power Architecture
3.2.3 Freescale PowerQUICC I
3.2.4 Freescale PowerQUICC II
3.2.5 PowerQUICC II Pro
3.2.6 Freescale PowerQUICC III
3.2.7 Freescale QorIQ
3.2.8 AMCC Power Architecture
3.2.9 MIPS
3.2.10 Broadcom MIPS
3.2.11 Other MIPS
3.2.12 ARM
3.2.13 TI ARM
3.2.14 Freescale ARM
3.2.15 Other ARM Processors
3.3 Other Architectures
3.4 Hardware Platforms
3.4.1 CompactPCI
3.4.2 ATCA
3.5 Summary
3.5.1 Suggestions for Additional Reading
Chapter 4 The Linux Kernel: A Different Perspective
4.1 Background
4.1.1 Kernel Versions
4.1.2 Kernel Source Repositories
4.1.3 Using git to Download a Kernel
4.2 Linux Kernel Construction
4.2.1 Top-Level Source Directory
4.2.2 Compiling the Kernel
4.2.3 The Kernel Proper: vmlinux
4.2.4 Kernel Image Components
4.2.5 Subdirectory Layout
4.3 Kernel Build System
4.3.1 The Dot-Config
4.3.2 Configuration Editor(s)
4.3.3 Makefile Targets
4.4 Kernel Configuration
4.4.1 Custom Configuration Options
4.4.2 Kernel Makefiles
4.5 Kernel Documentation
4.6 Obtaining a Custom Linux Kernel
4.6.1 What Else Do I Need?
4.7 Summary
4.7.1 Suggestions for Additional Reading
Chapter 5 Kernel Initialization
5.1 Composite Kernel Image: Piggy and Friends
5.1.1 The Image Object
5.1.2 Architecture Objects
5.1.3 Bootstrap Loader
5.1.4 Boot Messages
5.2 Initialization Flow of Control
5.2.1 Kernel Entry Point: head.o
5.2.2 Kernel Startup: main.c
5.2.3 Architecture Setup
5.3 Kernel Command-Line Processing
5.3.1 The __setup Macro
5.4 Subsystem Initialization
5.4.1 The *__initcall Macros
5.5 The init Thread
5.5.1 Initialization Via initcalls
5.5.2 initcall_debug
5.5.3 Final Boot Steps
5.6 Summary
5.6.1 Suggestions for Additional Reading
Chapter 6 User Space Initialization
6.1 Root File System
6.1.1 FHS: File System Hierarchy Standard
6.1.2 File System Layout
6.1.3 Minimal File System
6.1.4 The Embedded Root FS Challenge
6.1.5 Trial-and-Error Method
6.1.6 Automated File System Build Tools
6.2 Kernel’s Last Boot Steps
6.2.1 First User Space Program
6.2.2 Resolving Dependencies
6.2.3 Customized Initial Process
6.3 The init Process
6.3.1 inittab
6.3.2 Sample Web Server Startup Script
6.4 Initial RAM Disk
6.4.1 Booting with initrd
6.4.2 Bootloader Support for initrd
6.4.3 initrd Magic: linuxrc
6.4.4 The initrd Plumbing
6.4.5 Building an initrd Image
6.5 Using initramfs
6.5.1 Customizing initramfs
6.6 Shutdown
6.7 Summary
6.7.1 Suggestions for Additional Reading
Chapter 7 Bootloaders
7.1 Role of a Bootloader
7.2 Bootloader Challenges
7.2.1 DRAM Controller
7.2.2 Flash Versus RAM
7.2.3 Image Complexity
7.2.4 Execution Context
7.3 A Universal Bootloader: Das U-Boot
7.3.1 Obtaining U-Boot
7.3.2 Configuring U-Boot
7.3.3 U-Boot Monitor Commands
7.3.4 Network Operations
7.3.5 Storage Subsystems
7.3.6 Booting from Disk
7.4 Porting U-Boot
7.4.1 EP405 U-Boot Port
7.4.2 U-Boot Makefile Configuration Target
7.4.3 EP405 First Build
7.4.4 EP405 Processor Initialization
7.4.5 Board-Specific Initialization
7.4.6 Porting Summary
7.4.7 U-Boot Image Format
7.5 Device Tree Blob (Flat Device Tree)
7.5.1 Device Tree Source
7.5.2 Device Tree Compiler
7.5.3 Alternative Kernel Images Using DTB
7.6 Other Bootloaders
7.6.1 Lilo
7.6.2 GRUB
7.6.3 Still More Bootloaders
7.7 Summary
7.7.1 Suggestions for Additional Reading
Chapter 8 Device Driver Basics
8.1 Device Driver Concepts
8.1.1 Loadable Modules
8.1.2 Device Driver Architecture
8.1.3 Minimal Device Driver Example
8.1.4 Module Build Infrastructure
8.1.5 Installing a Device Driver
8.1.6 Loading a Module
8.1.7 Module Parameters
8.2 Module Utilities
8.2.1 insmod
8.2.2 lsmod
8.2.3 modprobe
8.2.4 depmod
8.2.5 rmmod
8.2.6 modinfo
8.3 Driver Methods
8.3.1 Driver File System Operations
8.3.2 Allocation of Device Numbers
8.3.3 Device Nodes and mknod
8.4 Bringing It All Together
8.5 Building Out-of-Tree Drivers
8.6 Device Drivers and the GPL
8.7 Summary
8.7.1 Suggestions for Additional Reading
Chapter 9 File Systems
9.1 Linux File System Concepts
9.1.1 Partitions
9.2 ext2
9.2.1 Mounting a File System
9.2.2 Checking File System Integrity
9.3 ext3
9.4 ext4
9.5 ReiserFS
9.6 JFFS2
9.6.1 Building a JFFS2 Image
9.7 cramfs
9.8 Network File System
9.8.1 Root File System on NFS
9.9 Pseudo File Systems
9.9.1 /proc File System
9.9.2 sysfs
9.10 Other File Systems
9.11 Building a Simple File System
9.12 Summary
9.12.1 Suggestions for Additional Reading
Chapter 10 MTD Subsystem
10.1 MTD Overview
10.1.1 Enabling MTD Services
10.1.2 MTD Basics
10.1.3 Configuring MTD on Your Target
10.2 MTD Partitions
10.2.1 Redboot Partition Table Partitioning
10.2.2 Kernel Command-Line Partitioning
10.2.3 Mapping Driver
10.2.4 Flash Chip Drivers
10.2.5 Board-Specific Initialization
10.3 MTD Utilities
10.3.1 JFFS2 Root File System
10.4 UBI File System
10.4.1 Configuring for UBIFS
10.4.2 Building a UBIFS Image
10.4.3 Using UBIFS as the Root File System
10.5 Summary
10.5.1 Suggestions for Additional Reading
Chapter 11 BusyBox
11.1 Introduction to BusyBox
11.1.1 BusyBox Is Easy
11.2 BusyBox Configuration
11.2.1 Cross-Compiling BusyBox
11.3 BusyBox Operation
11.3.1 BusyBox init
11.3.2 Sample rcS Initialization Script
11.3.3 BusyBox Target Installation
11.3.4 BusyBox Applets
11.4 Summary
11.4.1 Suggestions for Additional Reading
Chapter 12 Embedded Development Environment
12.1 Cross-Development Environment
12.1.1 “Hello World” Embedded
12.2 Host System Requirements
12.2.1 Hardware Debug Probe
12.3 Hosting Target Boards
12.3.1 TFTP Server
12.3.2 BOOTP/DHCP Server
12.3.3 NFS Server
12.3.4 Target NFS Root Mount
12.3.5 U-Boot NFS Root Mount Example
12.4 Summary
12.4.1 Suggestions for Additional Reading
Chapter 13 Development Tools
13.1 GNU Debugger (GDB)
13.1.1 Debugging a Core Dump
13.1.2 Invoking GDB
13.1.3 Debug Session in GDB
13.2 Data Display Debugger
13.3 cbrowser/cscope
13.4 Tracing and Profiling Tools
13.4.1 strace
13.4.2 strace Variations
13.4.3 ltrace
13.4.4 ps
13.4.5 top
13.4.6 mtrace
13.4.7 dmalloc
13.4.8 Kernel Oops
13.5 Binary Utilities
13.5.1 readelf
13.5.2 Examining Debug Information Using readelf
13.5.3 objdump
13.5.4 objcopy
13.6 Miscellaneous Binary Utilities
13.6.1 strip
13.6.2 addr2line
13.6.3 strings
13.6.4 ldd
13.6.5 nm
13.6.6 prelink
13.7 Summary
13.7.1 Suggestions for Additional Reading
Chapter 14 Kernel Debugging Techniques
14.1 Challenges to Kernel Debugging
14.2 Using KGDB for Kernel Debugging
14.2.1 KGDB Kernel Configuration
14.2.2 Target Boot with KGDB Support
14.2.3 Useful Kernel Breakpoints
14.2.4 Sharing a Console Serial Port with KGDB
14.2.5 Debugging Very Early Kernel Code
14.2.6 KGDB Support in the Mainline Kernel
14.3 Kernel Debugging Techniques
14.3.1 gdb Remote Serial Protocol
14.3.2 Debugging Optimized Kernel Code
14.3.3 GDB User-Defined Commands
14.3.4 Useful Kernel GDB Macros
14.3.5 Debugging Loadable Modules
14.3.6 printk Debugging
14.3.7 Magic SysReq Key
14.4 Hardware-Assisted Debugging
14.4.1 Programming Flash Using a JTAG Probe
14.4.2 Debugging with a JTAG Probe
14.5 When It Doesn’t Boot
14.5.1 Early Serial Debug Output
14.5.2 Dumping the printk Log Buffer
14.5.3 KGDB on Panic
14.6 Summary
14.6.1 Suggestions for Additional Reading
Chapter 15 Debugging Embedded Linux Applications
15.1 Target Debugging
15.2 Remote (Cross) Debugging
15.2.1 gdbserver
15.3 Debugging with Shared Libraries
15.3.1 Shared Library Events in GDB
15.4 Debugging Multiple Tasks
15.4.1 Debugging Multiple Processes
15.4.2 Debugging Multithreaded Applications
15.4.3 Debugging Bootloader/Flash Code
15.5 Additional Remote Debug Options
15.5.1 Debugging Using a Serial Port
15.5.2 Attaching to a Running Process
15.6 Summary
15.6.1 Suggestions for Additional Reading
Chapter 16 Open Source Build Systems
16.1 Why Use a Build System?
16.2 Scratchbox
16.2.1 Installing Scratchbox
16.2.2 Creating a Cross-Compilation Target
16.3 Buildroot
16.3.1 Buildroot Installation
16.3.2 Buildroot Configuration
16.3.3 Buildroot Build
16.4 OpenEmbedded
16.4.1 OpenEmbedded Composition
16.4.2 BitBake Metadata
16.4.3 Recipe Basics
16.4.4 Metadata Tasks
16.4.5 Metadata Classes
16.4.6 Configuring OpenEmbedded
16.4.7 Building Images
16.5 Summary
16.5.1 Suggestions for Additional Reading
Chapter 17 Linux and Real Time
17.1 What Is Real Time?
17.1.1 Soft Real Time
17.1.2 Hard Real Time
17.1.3 Linux Scheduling
17.1.4 Latency
17.2 Kernel Preemption
17.2.1 Impediments to Preemption
17.2.2 Preemption Models
17.2.3 SMP Kernel
17.2.4 Sources of Preemption Latency
17.3 Real-Time Kernel Patch
17.3.1 Real-Time Features
17.3.2 O(1) Scheduler
17.3.3 Creating a Real-Time Process
17.4 Real-Time Kernel Performance Analysis
17.4.1 Using Ftrace for Tracing
17.4.2 Preemption Off Latency Measurement
17.4.3 Wakeup Latency Measurement
17.4.4 Interrupt Off Timing
17.4.5 Soft Lockup Detection
17.5 Summary
17.5.1 Suggestion for Additional Reading
Chapter 18 Universal Serial Bus
18.1 USB Overview
18.1.1 USB Physical Topology
18.1.2 USB Logical Topology
18.1.3 USB Revisions
18.1.4 USB Connectors
18.1.5 USB Cable Assemblies
18.1.6 USB Modes
18.2 Configuring USB
18.2.1 USB Initialization
18.3 sysfs and USB Device Naming
18.4 Useful USB Tools
18.4.1 USB File System
18.4.2 Using usbview
18.4.3 USB Utils (lsusb)
18.5 Common USB Subsystems
18.5.1 USB Mass Storage Class
18.5.2 USB HID Class
18.5.3 USB CDC Class Drivers
18.5.4 USB Network Support
18.6 USB Debug
18.6.1 usbmon
18.6.2 Useful USB Miscellanea
18.7 Summary
18.7.1 Suggestions for Additional Reading
Chapter 19 udev
19.1 What Is udev?
19.2 Device Discovery
19.3 Default udev Behavior
19.4 Understanding udev Rules
19.4.1 Modalias
19.4.2 Typical udev Rules Configuration
19.4.3 Initial System Setup for udev
19.5 Loading Platform Device Drivers
19.6 Customizing udev Behavior
19.6.1 udev Customization Example: USB Automounting
19.7 Persistent Device Naming
19.7.1 udev Helper Utilities
19.8 Using udev with busybox
19.8.1 busybox mdev
19.8.2 Configuring mdev
19.9 Summary
19.9.1 Suggestions for Additional Reading
Appendix A: GNU Public License
Preamble
Terms and Conditions for Copying, Distribution, and Modification
No Warranty
Appendix B: U-Boot Configurable Commands
Appendix C: BusyBox Commands
Appendix D: SDRAM Interface Considerations
D.1 SDRAM Basics
D.1.1 SDRAM Refresh
D.2 Clocking
D.3 SDRAM Setup
D.4 Summary
D.4.1 Suggestions for Additional Reading
Appendix E: Open Source Resources
Source Repositories and Developer Information
Mailing Lists
Linux News and Developments
Open Source Legal Insight and Discussion
Appendix F: Sample BDI-2000 Configuration File
Index
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q – R
S
T
U
V
W
X – Z