前 言
多年来,Linux一直是嵌入式计算的中流砥柱。然而,涵盖该领域所有主题的书籍非常少,本书旨在填补这一空白。“嵌入式Linux”一词的定义并不明确,它可以应用于从恒温器到Wi-Fi路由器,再到工业控制单元的各种设备内的操作系统。但是,它们都建立在相同的基本开源软件之上。这些正是我们在本书中要描述的技术,本书的写作基于我们作为工程师的经验和为培训课程开发的资料。
技术不会停滞不前。基于嵌入式计算的行业与主流计算一样容易受到摩尔定律的影响。这种指数级的增长意味着自本书第一版出版以来发生了惊人的大量变化。你现在正在阅读的第三版经过全面修订,使用最新版本的主要开源组件,包括Linux 5.4、Yocto Project 3.1 Dunfell和Buildroot 2020.02 LTS。除了Autotools,本书还包含CMake,这是一种新构建系统,近年来得到了越来越多的采用。
本书大致按照你在实际项目中遇到的顺序来涵盖这些主题。第1篇包括第1~8章,涉及项目的早期阶段。本篇涵盖选择工具链、引导加载程序和内核等基础知识。我们以Buildroot和Yocto项目为例介绍嵌入式构建系统的概念。本篇以对Yocto Project的新深入研究结束。
第2篇包括第9~15章,着眼于在进行开发之前需要做出的各种设计决策。本篇涵盖文件系统、软件更新、设备驱动程序、init程序和电源管理等主题。第12章演示使用分线板进行快速原型设计的各种技术,包括如何使用逻辑分析仪读取原理图、焊接接头和排除信号故障等。第14章深入探讨Buildroot,你将学习如何使用BusyBox runit将系统软件划分为单独的服务。
第3篇包括第16~18章,将为你的项目实施阶段提供帮助。我们从Python打包和依赖管理开始,随着机器学习应用程序风靡全球,这个话题变得越来越重要。然后,我们讨论各种形式的进程间通信和多线程编程。本篇最后还仔细探讨Linux如何管理内存,并演示如何使用各种可用工具来测量内存使用情况和检测内存泄漏。
第4篇包括第19~21章,向你展示如何有效地利用Linux提供的许多调试和分析工具来检测问题和识别性能瓶颈。第19章介绍如何配置Visual Studio Code以使用GDB进行远程调试。第20章介绍BPF,这是一种在Linux内核中实现高级编程跟踪的新技术。最后一章则阐释如何在实时应用程序中使用Linux。
本书的每一章都介绍嵌入式Linux的一个主要领域。它描述知识背景,以便你可以了解一般原则,它还包括详细的有效示例来说明这些领域中的操作。你可以把它当作一本理论书籍,也可以将它作为一本实战操作指南。如果你能二者兼得,那么效果当然最好:你可以先熟悉理论,然后在现实生活中尝试。
本书读者
本书是为对嵌入式计算和Linux感兴趣的开发人员编写的。在编写本书时,我们假设你对Linux命令行有基本的了解;在编程示例中,我们假设你对C和Python语言的知识有一定的了解。其中还有几章侧重于嵌入式目标板的硬件,因此对于本书读者来说,熟悉硬件和硬件接口将是一个明显的优势。
内容介绍
本书分为4篇共21章,具体介绍如下。
第1篇:嵌入式Linux的要素,包括第1~8章。
第1章“初识嵌入式Linux开发”,详细阐释嵌入式Linux生态系统,介绍硬件选择和开发环境配置等准备工作。
第2章“关于工具链”,描述工具链的组件,演示如何为目标开发板的交叉编译代码创建工具链。本章还详细介绍从何处获取工具链,并提供有关如何从源代码中构建工具链的详细信息。
第3章“引导加载程序详解”,阐释引导加载程序在将Linux内核加载到内存这一过程中的作用,并以U-Boot为例演示其操作。本章还介绍设备树,它是一种对几乎所有嵌入式Linux系统中的硬件细节进行编码的机制。
第4章“配置和构建内核”,介绍如何为嵌入式系统选择Linux内核并为设备内的硬件配置它。本章还介绍如何将Linux移植到新的硬件上。
第5章“构建根文件系统”,通过有关如何配置根文件系统的分步指南,详细介绍嵌入式Linux实现的用户空间部分背后的思想。
第6章“选择构建系统”,涵盖两个常用的嵌入式Linux构建系统Buildroot和Yocto Project,它们可以自动执行此前4章中描述的步骤。
第7章“使用Yocto进行开发”,演示如何在现有板级支持包(BSP)层之上构建系统镜像,如何使用Yocto的可扩展SDK开发板载软件包,如何推出你自己的嵌入式Linux发行版,以及如何进行运行时包管理和配置远程包服务器等。
第8章“Yocto技术内幕”,介绍Yocto的构建工作流程和架构,包括对Yocto独特的多层方法的解释。本章还通过实际配方文件中的示例详细介绍BitBake语法和语义方面的基础知识。
第2篇:系统架构和设计决策,包括第9~15章。
第9章“创建存储策略”,讨论管理闪存带来的挑战,包括原始闪存芯片和嵌入式MMC(eMMC)封装。本章还描述适用于各种技术的文件系统。
第10章“现场更新软件”,介绍在设备部署后更新软件的各种方法,包括完全托管的无线(OTA)更新。本章讨论的关键主题是可靠性和安全性。
第11章“连接设备驱动程序”,描述内核设备驱动程序如何通过实现一个简单的驱动程序与硬件进行交互。本章还阐释从用户空间调用设备驱动程序的各种方法。
第12章“使用分线板进行原型设计”,演示如何使用BeagleBone Black开发板的预构建Debian镜像和外围分线板快速构建硬件和软件原型。你将了解如何阅读数据表、连接电路板、多路复用设备树绑定以及分析SPI信号。
第13章“init程序”,解释第一个用户空间程序init,讨论如何通过它启动系统的其余部分。本章描述init程序的3个版本(每个版本都适用于不同的嵌入式系统组):从简单的BusyBox init到System V init,再到当前最先进的方法systemd。
第14章“使用BusyBox runit启动”,演示如何使用Buildroot将系统划分为单独的BusyBox runit 服务,每个服务都有自己的专用进程监督和日志记录,就像 systemd 提供的那样。与System V init不同,BusyBox runit服务是同时启动而不是顺序启动,这可以显著加快启动速度。
第15章“管理电源”,考虑可以调整Linux以降低功耗的各种方法,包括动态频率和电压调整、选择更深的空闲状态和系统挂起等。其目的是使设备在电池充电时运行时间更长,并且运行温度更低。
第3篇:编写嵌入式应用程序,包括第16~18章。
第16章“打包Python程序”,解释哪些选项可用于将Python模块捆绑在一起进行部署,以及何时使用一种方法而不是另一种方法。本章涵盖pip、venv、conda和Docker。
第17章“了解进程和线程”,从应用程序开发人员的角度描述嵌入式系统。本章着眼于进程和线程、进程间通信和调度策略。
第18章“管理内存”,介绍虚拟内存背后的思想以及地址空间如何被划分为内存映射。本章还描述如何准确测量内存使用情况,以及如何检测内存泄漏。
第4篇:调试和优化性能,包括第19~21章。
第19章“使用GDB进行调试”,演示使用GNU调试器GDB和调试代理gdbserver来调试在目标设备上远程运行的应用程序。本章还介绍如何扩展这个模型来调试内核代码,即利用kgdb调试内核代码。
第20章“性能分析和跟踪”,涵盖可用于测量系统性能的技术。本章从整个系统的性能分析开始,介绍多种性能分析工具。本章还描述如何使用Valgrind检查应用程序在线程同步和内存分配方面的正确性。
第21章“实时编程”,提供Linux实时编程的详细指南,包括内核配置和 PREEMPT_RT实时内核补丁。内核跟踪工具Ftrace可用于测量内核调度延迟并显示各种内核配置的效果。
充分利用本书
本书中使用的软件是完全开源的。在几乎所有示例中,我们都使用了撰写本文时可用的最新稳定版本。虽然我们试图以不特定于版本的方式来描述主要功能,但不可避免的是一些示例需要适应以后的软件。
本书涵盖的软硬件如表P-1所示。
表P-1 本书涵盖的软硬件
本书涵盖的软硬件 操作系统需求
BeagleBone Black 不适用
Raspberry Pi 4 不适用
QEMU(32位ARM) Linux(任意版本)
Yocto Project 3.1(Dunfell) 兼容Linux发行版*
Buildroot 2020.02 LTS Linux(任意版本)
crosstool-NG 1.24.0 Linux(任意版本)
U-Boot v2021.01 Linux(任意版本)
Linux Kernel 5.4 Linux(任意版本)
* 有关更多详细信息,你可以参阅Yocto Project Quick Build(《Yocto Project快速构建》)指南的“Compatible Linux Distribution”(《兼容Linux发行版》)部分。其网址如下:
https://www.yoctoproject.org/docs/current/brief-yoctoprojectqs/brief-yoctoprojectqs.html
嵌入式开发涉及主机和目标两个系统:主机用于开发程序,目标用于运行程序。对于主机系统,我们使用的是Ubuntu 20.04 LTS,但大多数Linux发行版只需稍作修改即可工作。你可能决定在虚拟机中以访客身份运行Linux,但你应该知道,某些任务(如使用Yocto Project构建发行版)要求很高,最好在Linux的本机安装上运行。
本书选择了3个示例目标:QEMU模拟器、BeagleBone Black和Raspberry Pi 4。使用QEMU意味着你可以尝试大多数示例,而无须投资任何额外的硬件。另外,如果你有真正的硬件,有些事情会更好,为此,我们选择了BeagleBone Black,因为它较为便宜,广泛可用,并且有很好的社区支持。Raspberry Pi 4是在本书第3版中添加的,因为它内置了Wi-Fi和蓝牙。当然,你不仅限于这3个目标。本书背后的想法是为你提供问题的通用解决方案,以便你可以将它们应用到广泛的目标板上。
下载示例代码文件
本书随附的代码可以在GitHub上找到,其网址如下:
https://github.com/PacktPublishing/Mastering-Embedded-Linux-Programming-Third-Edition
如果代码有更新,那么它将在GitHub存储库中被更新。
下载彩色图像
我们还提供了一个PDF文件,其中包含本书中使用的屏幕截图/图表的彩色图像。你可以通过以下地址进行下载:
https://static.packt-cdn.com/downloads/9781789530384_ColorImages.pdf
本书约定
本书中使用了许多文本约定。
(1)有关代码块的设置如下:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
printf ("Hello, world!\n");
return 0;
}
(2)为了突出代码块,相关内容需要以粗体的形式进行显示:
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
(3)任何命令行的输入或输出都采用如下所示的粗体代码形式:
$ sudo tunctl -u $(whoami) -t tap0
(4)术语或重要单词采用中英文对照的形式给出,在括号内保留其英文原文。示例如下:
在嵌入式设备中最常见的架构是ARM、MIPS、PowerPC和x86,每一种都有32位和64位变体,它们都具有内存管理单元(memory management unit,MMU)。
(5)对于界面词汇或专有名词将保留其英文原文,在括号内添加其中文译文。示例如下:
最后,将BR2_ROOTFS_OVERLAY设置为指向覆盖层的路径。可以在menuconfig中使用System configuration(系统配置)| Root filesystem overlay directories(根文件系统覆盖层目录)选项进行配置。
(6)本书还使用了以下两个图标:
表示警告或重要的注意事项。
表示提示信息或操作技巧。