What this book covers
Mastering Embedded Linux Programming is organized along the lines of the life cycle of a typical embedded Linux project. The first six chapters tell you what you need to know about how to set up the project and how a Linux system is put together, culminating in selecting an appropriate Linux build system. Next, comes the stage where certain key decisions must be made about the system architecture and design choices, including flash memory, device drivers, and the init
system. Following this is the phase of writing applications to make use of the embedded platform you have built, and for which there are two chapters on processes, threads, and memory management. Finally, we come to the stage of debugging and optimizing the platform, which is discussed in chapters 12 and 13. The last chapter describes how to configure Linux for real-time applications.
Chapter 1, Starting Out, sets the scene by describing the choices available to the system designer at the start of a project.
Chapter 2, Learning About Toolchains, describes the components of a toolchain with an emphasis on cross-compiling. It describes where to get a toolchain and provides details on how to build one from the source code.
Chapter 3, All About Bootloaders, explains the role of the bootloader to initialize the hardware of the device and uses U-Boot and Bareboot as examples. It also describes the device tree, which is a means of encoding the hardware configuration, used in many embedded systems.
Chapter 4, Porting and Configuring the Kernel, provides information on how to select a Linux kernel for an embedded system and configure it for the hardware within the device. It also covers how to port Linux to the new hardware.
Chapter 5, Building a Root Filesystem, introduces the ideas behind the user space part of an embedded Linux implementation by means of a step-by-step guide on how to configure a root filesystem.
Chapter 6, Selecting a Build System, covers two embedded Linux build systems, which automate the steps described in the previous four chapters and conclude the first section of the book.
Chapter 7, Creating a Storage Strategy, discusses the challenges created by managing flash memory, including raw flash chips and embedded MMC or eMMC packages. It describes the filesystems that are applicable to each type of technology. It also covers techniques on how to update the device firmware in the field.
Chapter 8, Introducing Device Drivers, describes how kernel device drivers interact with the hardware with worked examples of a simple driver. It also describes the various ways of calling device drivers from the user space.
Chapter 9, Starting up - the init Program, shows how the first user space program, init
, which starts the rest of the system. It describes the three versions of the init
program, each suitable for a different group of embedded systems, with increasing complexity from BusyBox init
to systemd.
Chapter 10, Learning About Processes and Threads, describes embedded systems from the point of view of the application programmer. This chapter looks at processes and threads, inter-process communication, and scheduling policies.
Chapter 11, Managing Memory, introduces the ideas behind virtual memory and how the address space is divided into memory mappings. It also covers how to detect memory that is being used and memory leaks.
Chapter 12, Debugging with GDB, shows you how to use the GNU debugger, GDB, to interactively debug both the user space and kernel code. It also describes the kernel debugger, kdb
.
Chapter 13, Profiling and Tracing, covers the techniques available to measure the system performance, starting from whole system profiles and then zeroing in on particular areas where bottlenecks are causing poor performance. It also describes Valgrind as a tool to check the correctness of an application's use of thread synchronization and memory allocation.
Chapter 14, Real-time Programming, provides a detailed guide to real-time programming on Linux, including the configuration of the kernel and the real-time kernel patch, and also provides a description of tools to measure real-time latencies. It also covers information on how to reduce the number of page faults by locking the memory.