精通嵌入式Linux编程

精通嵌入式Linux编程
分享
扫描下方二维码分享到微信
打开微信,点击右上角”+“,
使用”扫一扫“即可将网页分享到朋友圈。
作者: [美] ,
2023-06
版次: 1
ISBN: 9787302635635
定价: 159.00
装帧: 其他
开本: 16开
纸张: 胶版纸
3人买过
  • 《精通嵌入式Linux编程》详细阐述了与嵌入式Linux开发相关的基本解决方案,主要包括初识嵌入式Linux开发、关于工具链、引导加载程序详解、配置和构建内核、构建根文件系统、选择构建系统、使用Yocto进行开发、Yocto技术内幕、创建存储策略、现场更新软件、连接设备驱动程序、使用分线板进行原型设计、init程序、使用BusyBox runit启动、管理电源、打包Python程序、了解进程和线程、管理内存、使用GDB进行调试、性能分析和跟踪、实时编程等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。 本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。 弗兰克·瓦斯奎兹是一位专注于消费电子产品的独立软件顾问。他在设计和构建嵌入式Linux系统方面拥有十多年的经验。在此期间,他完成了许多设备的开发,包括机架式DSP音频服务器、潜水员手持式声纳摄像机和消费者物联网热点。在成为嵌入式Linux开发工程师之前,Frank曾经是IBM的数据库内核开发人员,他在该公司主要从事DB2方面的工作。他目前住在硅谷。 第1篇  嵌入式Linux的要素

    第1章  初识嵌入式Linux开发 3

    1.1  选择Linux的原因 4

    1.2  不选择Linux的原因 5

    1.3  找到合适的玩家 5

    1.4  穿越项目生命周期 7

    1.4.1  篇章内容概述 7

    1.4.2  嵌入式Linux的4个基本要素 7

    1.5  开源的意义 8

    1.5.1  开源和免费有区别 8

    1.5.2  开源许可机制 8

    1.6  为嵌入式Linux开发选择硬件 10

    1.7  获取本书所需硬件 11

    1.7.1  Raspberry Pi 4 11

    1.7.2  BeagleBone Black 12

    1.7.3  QEMU 13

    1.8  配置开发环境 15

    1.9  小结 15

    第2章  关于工具链 17

    2.1  技术要求 17

    2.2  工具链简介 18

    2.2.1  工具链的类型 20

    2.2.2  CPU架构 21

    2.2.3  选择C库 22

    2.3  寻找工具链 24

    2.4  使用crosstool-NG构建工具链 26

    2.4.1  安装crosstool-NG 26

    2.4.2  为BeagleBone Black构建工具链 27

    2.4.3  为QEMU构建工具链 28

    2.5  工具链剖析 29

    2.5.1  了解你的交叉编译器 30

    2.5.2  sysroot、库和头文件 31

    2.5.3  工具链中的其他工具 32

    2.5.4  查看C库的组件 33

    2.6  与库链接—静态和动态链接 34

    2.6.1  静态库 34

    2.6.2  共享库 35

    2.6.3  了解共享库版本号 36

    2.7  交叉编译的技巧 37

    2.7.1  相对简单的makefile 38

    2.7.2  Autotools 38

    2.7.3  编译示例—SQLite 40

    2.7.4  包配置 42

    2.7.5  交叉编译带来的问题 43

    2.7.6  CMake 44

    2.8  小结 46

    2.9  延伸阅读 46

    第3章  引导加载程序详解 47

    3.1  技术要求 47

    3.2  引导加载程序的作用 48

    3.3  引导顺序 48

    3.3.1  阶段1—ROM代码 49

    3.3.2  阶段2—SPL 51

    3.3.3  阶段3—TPL 52

    3.4  从引导加载程序转移到内核中 53

    3.5  设备树简介 54

    3.5.1  有关设备树的基础知识 54

    3.5.2  reg属性 55

    3.5.3  标签和中断 56

    3.5.4  设备树包含文件 57

    3.5.5  编译设备树 59

    3.6  U-Boot 60

    3.6.1  构建U-Boot 60

    3.6.2  安装U-Boot 62

    3.6.3  使用U-Boot 64

    3.6.4  环境变量 65

    3.6.5  引导镜像格式 65

    3.6.6  加载镜像 67

    3.6.7  引导Linux 69

    3.6.8  使用U-Boot脚本自动化引导过程 69

    3.6.9  将U-Boot移植到新板上 69

    3.6.10  与特定开发板相关的文件 71

    3.6.11  配置头文件 73

    3.6.12  构建和测试 74

    3.6.13  Falcon模式 75

    3.7  小结 76

    第4章  配置和构建内核 77

    4.1  技术要求 77

    4.2  内核的作用 78

    4.3  选择内核 80

    4.3.1  内核开发周期 80

    4.3.2  稳定和长期支持版本 81

    4.3.3  供应商支持 82

    4.3.4  许可机制 82

    4.4  构建内核 83

    4.4.1  获取源 83

    4.4.2  了解内核配置—Kconfig 84

    4.4.3  使用LOCALVERSION识别内核 88

    4.4.4  使用内核模块的时机 89

    4.5  编译—Kbuild 90

    4.5.1  找出要构建的内核目标 90

    4.5.2  构建工件 91

    4.5.3  编译设备树 93

    4.5.4  编译模块 93

    4.5.5  清理内核源 94

    4.5.6  为Raspberry Pi 4构建64位内核 94

    4.5.7  为BeagleBone Black构建内核 96

    4.5.8  为QEMU构建内核 97

    4.6  引导内核 97

    4.6.1  引导Raspberry Pi 4 97

    4.6.2  引导BeagleBone Black 98

    4.6.3  引导QEMU 99

    4.6.4  内核恐慌 100

    4.6.5  早期用户空间 100

    4.6.6  内核消息 101

    4.6.7  内核命令行 101

    4.7  将Linux移植到新板上 102

    4.7.1  新的设备树 103

    4.7.2  设置开发板的兼容属性 104

    4.8  小结 106

    4.9  延伸阅读 107

    第5章  构建根文件系统 109

    5.1  技术要求 110

    5.2  根文件系统中应该包含的东西 110

    5.3  目录布局 111

    5.3.1  暂存目录 112

    5.3.2  POSIX文件访问权限 113

    5.3.3  暂存目录中的文件所有权权限 115

    5.4  根文件系统的程序 115

    5.4.1  init程序 115

    5.4.2  shell 115

    5.4.3  实用程序 116

    5.4.4  关于BusyBox 116

    5.4.5  构建BusyBox 117

    5.4.6  ToyBox—BusyBox的替代品 118

    5.5  根文件系统的库 119

    5.5.1  选择需要的库 119

    5.5.2  通过剥离减小尺寸 120

    5.6  设备节点 121

    5.7  proc和sysfs文件系统 122

    5.7.1  proc和sysfs文件系统的功能 123

    5.7.2  挂载文件系统 123

    5.7.3  内核模块 124

    5.8  将根文件系统传输到目标 124

    5.9  创建引导initramfs 125

    5.9.1  独立的initramfs 126

    5.9.2  引导initramfs 126

    5.9.3  使用QEMU引导 126

    5.9.4  引导BeagleBone Black 127

    5.9.5  挂载proc 127

    5.9.6  将initramfs构建到内核镜像中 128

    5.9.7  使用设备表构建initramfs 129

    5.9.8  旧的initrd格式 130

    5.10  init程序 130

    5.10.1  BusyBox的init程序 131

    5.10.2  启动守护进程 132

    5.11  配置用户账户 132

    5.11.1  配置账户 132

    5.11.2  将用户账户添加到根文件系统中 134

    5.12  管理设备节点的更好方法 134

    5.12.1  使用devtmpfs的示例 135

    5.12.2  使用mdev的示例 135

    5.12.3  静态设备节点的优劣 136

    5.13  配置网络 136

    5.13.1  BusyBox中的网络配置 136

    5.13.2  glibc的网络组件 137

    5.14  使用设备表创建文件系统镜像 138

    5.14.1  安装和使用genext2fs工具 138

    5.14.2  引导BeagleBone Black 139

    5.15  使用NFS挂载根文件系统 140

    5.15.1  使用QEMU进行测试 141

    5.15.2  使用BeagleBone Black进行测试 142

    5.15.3  文件权限问题 142

    5.16  使用TFTP加载内核 143

    5.17  小结 144

    5.18  延伸阅读 144

    第6章  选择构建系统 145

    6.1  技术要求 145

    6.2  比较构建系统 146

    6.3  分发二进制文件 148

    6.4  Buildroot简介 148

    6.4.1  Buildroot的背景知识 149

    6.4.2  稳定版本和长期支持版本 149

    6.4.3  安装Buildroot 149

    6.4.4  配置Buildroot 150

    6.4.5  运行 151

    6.4.6  以真实硬件为目标 153

    6.4.7  创建自定义BSP 154

    6.4.8  U-Boot配置 154

    6.4.9  Linux配置 155

    6.4.10  构建系统镜像 157

    6.4.11  添加自己的代码 159

    6.4.12  覆盖层 160

    6.4.13  添加包 160

    6.4.14  许可合规性 162

    6.5  Yocto Project简介 162

    6.5.1  Yocto Project的背景知识 163

    6.5.2  稳定版本和支持 164

    6.5.3  安装Yocto Project 165

    6.5.4  配置 165

    6.5.5  构建 166

    6.5.6  运行QEMU目标 167

    6.5.7  元层 167

    6.5.8  BitBake和配方 170

    6.5.9  通过local.conf自定义镜像 172

    6.5.10  编写镜像配方 173

    6.5.11  创建SDK 174

    6.5.12  许可证审核 176

    6.6  小结 176

    6.7  延伸阅读 177

    第7章  使用Yocto进行开发 179

    7.1  技术要求 179

    7.2  在现有BSP之上构建镜像 180

    7.2.1  构建现有的BSP 180

    7.2.2  控制Wi-Fi 186

    7.2.3  控制蓝牙 189

    7.2.4  添加自定义层 192

    7.3  使用devtool捕获更改 195

    7.3.1  开发工作流程 195

    7.3.2  创建新配方 197

    7.3.3  修改由配方构建的源 198

    7.3.4  将配方升级到较新版本 200

    7.4  构建自己的发行版 203

    7.4.1  推出发行版的合适时机 203

    7.4.2  创建一个新的发行层 203

    7.4.3  配置发行版 204

    7.4.4  向发行版添加更多配方 205

    7.4.5  运行时包管理 205

    7.5  配置远程包服务器 207

    7.5.1  配置包服务器 207

    7.5.2  配置目标客户端 208

    7.6  小结 209

    7.7  延伸阅读 209

    第8章  Yocto技术内幕 211

    8.1  技术要求 211

    8.2  Yocto架构和工作流程分解 212

    8.2.1  元数据 214

    8.2.2  构建任务 215

    8.2.3  镜像生成 217

    8.3  将元数据分层 218

    8.4  构建失败故障排除 220

    8.4.1  隔离错误 220

    8.4.2  检查和转储环境值 221

    8.4.3  读取任务日志 222

    8.4.4  添加更多日志记录 222

    8.4.5  从devshell中运行命令 223

    8.4.6  查看包的依赖关系 224

    8.5  了解BitBake语法和语义 225

    8.5.1  任务 225

    8.5.2  依赖项 226

    8.5.3  任务间依赖项 226

    8.5.4  构建时依赖项 226

    8.5.5  运行时依赖项 227

    8.5.6  变量 228

    8.5.7  赋值和扩展 228

    8.5.8  附加和前置 229

    8.5.9  覆盖 229

    8.5.10  内联Python 230

    8.5.11  函数 231

    8.5.12  shell 231

    8.5.13  Python 231

    8.5.14  纯Python函数 232

    8.5.15  BitBake风格的Python函数 232

    8.5.16  匿名Python函数 233

    8.5.17  RDEPENDS 234

    8.6  小结 235

    8.7  延伸阅读 235

    第2篇  系统架构和设计决策

    第9章  创建存储策略 239

    9.1  技术要求 239

    9.2  存储选项 240

    9.2.1  NOR闪存 241

    9.2.2  NAND闪存 241

    9.2.3  托管闪存 243

    9.2.4  多媒体卡和安全数字卡 244

    9.2.5  eMMC 245

    9.2.6  其他类型的托管闪存 245

    9.3  从引导加载程序中访问闪存 245

    9.3.1  U-Boot和NOR闪存 246

    9.3.2  U-Boot和NAND闪存 246

    9.3.3  U-Boot和MMC、SD和eMMC 246

    9.4  从Linux中访问闪存 247

    9.4.1  内存技术设备子系统 247

    9.4.2  MTD分区 248

    9.4.3  MTD设备驱动程序 251

    9.4.4  MTD字符设备 251

    9.4.5  MTD块设备mtdblock 252

    9.4.6  将内核错误记录到MTD上 253

    9.4.7  模拟NAND存储器 253

    9.4.8  MMC块驱动程序 253

    9.5  闪存文件系统 254

    9.5.1  闪存转换层的特点 254

    9.5.2  闪存转换层的部署方式 255

    9.6  NOR和NAND闪存的文件系统 255

    9.6.1  JFFS2 256

    9.6.2  摘要节点 257

    9.6.3  干净标记 257

    9.6.4  创建JFFS2文件系统 257

    9.6.5  YAFFS2 258

    9.6.6  创建YAFFS2文件系统 259

    9.6.7  UBI和UBIFS 260

    9.6.8  UBI 260

    9.6.9  UBIFS 263

    9.7  托管闪存的文件系统 264

    9.7.1  Flashbench 265

    9.7.2  丢弃和修剪 266

    9.7.3  Ext4 267

    9.7.4  F2FS 268

    9.7.5  FAT16/32 268

    9.8  只读压缩文件系统 269

    9.8.1  SquashFS 269

    9.8.2  在NAND闪存上使用SquashFS 269

    9.9  临时文件系统 270

    9.10  将根文件系统设为只读 271

    9.11  文件系统选择 272

    9.12  小结 273

    9.13  延伸阅读 273

    第10章  现场更新软件 275

    10.1  技术要求 275

    10.2  启动更新的方法 276

    10.3  更新的内容 276

    10.3.1  引导加载程序 277

    10.3.2  内核 277

    10.3.3  根文件系统 278

    10.3.4  系统应用程序 278

    10.3.5  与特定设备相关的数据 278

    10.3.6  需要更新的组件 279

    10.4  有关软件更新的基础知识 279

    10.4.1  使更新稳定可靠 279

    10.4.2  使更新不受故障影响 280

    10.4.3  确保更新安全 282

    10.5  更新机制的类型 283

    10.5.1  对称镜像更新 283

    10.5.2  非对称镜像更新 285

    10.5.3  原子文件更新 286

    10.6  OTA更新 288

    10.7  使用Mender进行本地更新 288

    10.7.1  构建Mender客户端 289

    10.7.2  安装更新 291

    10.8  使用Mender进行OTA更新 294

    10.8.1  设置更新服务器 294

    10.8.2  上传工件 297

    10.8.3  部署更新 299

    10.9  使用balena进行本地更新 301

    10.9.1  创建一个账户 302

    10.9.2  创建应用程序 303

    10.9.3  添加设备 304

    10.9.4  启用本地模式 306

    10.9.5  安装CLI 307

    10.9.6  推送一个项目 309

    10.9.7  修改和更新项目 310

    10.10  小结 311

    第11章  连接设备驱动程序 313

    11.1  技术要求 313

    11.2  设备驱动程序的作用 314

    11.3  字符设备 315

    11.4  块设备 317

    11.5  网络设备 318

    11.6  在运行时查找驱动程序 320

    11.6.1  从sysfs中获取信息 322

    11.6.2  设备 322

    11.6.3  驱动程序 323

    11.6.4  块驱动程序 324

    11.7  寻找合适的设备驱动程序 325

    11.8  用户空间中的设备驱动程序 325

    11.8.1  通用输入/输出接口 326

    11.8.2  处理来自GPIO的中断 327

    11.8.3  LED 329

    11.8.4  I2C 330

    11.8.5  SPI 332

    11.9  编写内核设备驱动程序 333

    11.9.1  设计字符设备驱动程序接口 333

    11.9.2  对于设备驱动程序的剖析 335

    11.9.3  编译内核模块 338

    11.9.4  加载内核模块 339

    11.10  发现硬件配置 339

    11.10.1  设备树 340

    11.10.2  平台数据 340

    11.10.3  将硬件与设备驱动程序链接在一起 341

    11.11  小结 343

    11.12  延伸阅读 344

    第12章  使用分线板进行原型设计 345

    12.1  技术要求 345

    12.2  将原理图映射到设备树的源中 346

    12.2.1  阅读原理图和数据表 347

    12.2.2  在BeagleBone Black上安装Debian 352

    12.2.3  启用spidev 353

    12.2.4  自定义设备树 359

    12.3  使用分线板进行原型设计 367

    12.3.1  闭合SPI跳线 368

    12.3.2  安装GNSS天线 370

    12.3.3  附加SPI接头 370

    12.3.4  连接SPI跳线 371

    12.4  使用逻辑分析仪探测SPI信号 375

    12.4.1  连接逻辑分析仪 376

    12.4.2  配置Logic 8 377

    12.5  通过SPI接收NMEA消息 383

    12.6  小结 387

    12.7  延伸阅读 387

    第13章  init程序 389

    13.1  技术要求 389

    13.2  内核引导后的操作 390

    13.3  init程序简介 391

    13.4  BusyBox init 392

    13.4.1  BusyBox init解析 392

    13.4.2  Buildroot init脚本 393

    13.5  System V init 393

    13.5.1  inittab 395

    13.5.2  init.d脚本 397

    13.5.3  添加新的守护进程 398

    13.5.4  启动和停止服务 399

    13.6  systemd 400

    13.6.1  使用Yocto Project和Buildroot构建systemd 400

    13.6.2  关于目标、服务和单元 401

    13.6.3  单元 401

    13.6.4  服务 402

    13.6.5  目标 402

    13.6.6  systemd引导系统的方式 403

    13.6.7  添加自己的服务 404

    13.6.8  添加看门狗 405

    13.6.9  对嵌入式Linux的影响 406

    13.7  小结 406

    13.8  延伸阅读 407

    第14章  使用BusyBox runit启动 409

    14.1  技术要求 409

    14.2  获取BusyBox runit 410

    14.3  创建服务目录和文件 416

    14.3.1  服务目录布局 417

    14.3.2  服务配置 418

    14.4  服务监督 425

    14.4.1  runsv脚本运行的服务 425

    14.4.2  控制服务 427

    14.5  服务依赖 429

    14.5.1  启动依赖项 429

    14.5.2  自定义启动依赖项 431

    14.5.3  简单总结 431

    14.6  专用服务日志记录 432

    14.6.1  专用日志记录器的工作方式 432

    14.6.2  向服务中添加专用日志记录 433

    14.6.3  日志轮转 434

    14.7  发出服务信号 435

    14.8  小结 436

    14.9  延伸阅读 437

    第15章  管理电源 439

    15.1  技术要求 439

    15.2  测量用电量 440

    15.3  调整时钟频率 443

    15.3.1  CPUFreq驱动程序 444

    15.3.2  使用CPUFreq 446

    15.4  选择最佳空闲状态 448

    15.4.1  CPUIdle驱动程序 449

    15.4.2  无滴答操作 452

    15.5  关闭外围设备 452

    15.6  使系统进入休眠状态 454

    15.6.1  电源状态 454

    15.6.2  唤醒事件 455

    15.6.3  从实时时钟定时唤醒 456

    15.7  小结 458

    15.8  延伸阅读 458

    第3篇  编写嵌入式应用程序

    第16章  打包Python程序 461

    16.1  技术要求 461

    16.1.1  安装venv 462

    16.1.2  安装Docker 462

    16.2  追溯Python打包的起源 463

    16.2.1  distutils 463

    16.2.2  setuptools 463

    16.2.3  setup.py 464

    16.3  使用pip安装Python包 466

    16.3.1  pip和pip3 466

    16.3.2  requirements.txt 469

    16.4  使用venv管理Python虚拟环境 471

    16.4.1  venv 472

    16.4.2  创建虚拟环境 473

    16.4.3  激活和验证虚拟环境 473

    16.4.4  在虚拟环境中安装测试库 474

    16.5  使用conda安装预编译的二进制文件 475

    16.5.1  环境管理 475

    16.5.2  验证根环境 476

    16.5.3  创建conda环境 477

    16.5.4  包管理 478

    16.5.5  导出虚拟环境 479

    16.6  使用Docker部署Python应用程序 480

    16.6.1  Dockerfile解析 481

    16.6.2  构建Docker镜像 483

    16.6.3  运行Docker镜像 484

    16.6.4  提取Docker镜像 485

    16.6.5  发布Docker镜像 485

    16.6.6  删除Docker容器 486

    16.6.7  删除Docker镜像 487

    16.6.8  Docker应用总结 487

    16.7  小结 488

    16.8  延伸阅读 488

    第17章  了解进程和线程 489

    17.1  技术要求 489

    17.2  进程和线程的抉择 490

    17.3  进程 492

    17.3.1  创建新进程 492

    17.3.2  终止进程 493

    17.3.3  运行不同的程序 494

    17.3.4  守护进程 497

    17.3.5  进程间通信 497

    17.3.6  基于消息的IPC 498

    17.3.7  UNIX套接字 498

    17.3.8  FIFO和命名管道 499

    17.3.9  POSIX消息队列 499

    17.3.10  基于消息的IPC总结 499

    17.3.11  基于共享内存的IPC 500

    17.3.12  POSIX共享内存 500

    17.4  线程 503

    17.4.1  创建一个新线程 503

    17.4.2  终止线程 505

    17.4.3  用线程编译程序 505

    17.4.4  线程间通信 505

    17.4.5  互斥锁 506

    17.4.6  不断变化的条件 506

    17.4.7  进程和线程应用规则 508

    17.5  ZeroMQ 509

    17.5.1  获取pyzmq 510

    17.5.2  进程之间的消息传递 510

    17.5.3  进程内的消息传递 512

    17.6  调度 514

    17.6.1  公平与确定性 514

    17.6.2  分时策略 515

    17.6.3  nice值 516

    17.6.4  实时策略 516

    17.6.5  选择策略 517

    17.6.6  选择实时优先级 518

    17.7  小结 518

    17.8  延伸阅读 518

    第18章  管理内存 521

    18.1  技术要求 521

    18.2  虚拟内存基础知识 522

    18.3  内核空间内存布局 523

    18.3.1  内核日志消息分析 523

    18.3.2  内核的内存使用情况 524

    18.4  用户空间内存布局 526

    18.5  进程内存映射 528

    18.6  交换 529

    18.6.1  交换的利弊 529

    18.6.2  交换到压缩内存 530

    18.7  使用mmap映射内存 530

    18.7.1  使用mmap分配私有内存 531

    18.7.2  使用mmap共享内存 531

    18.7.3  使用mmap访问设备内存 532

    18.8  应用程序的内存使用情况 532

    18.9  每个进程的内存使用情况 533

    18.9.1  使用top和ps 534

    18.9.2  使用smem 534

    18.9.3  其他工具 536

    18.10  识别内存泄漏 537

    18.10.1  mtrace 537

    18.10.2  Valgrind 538

    18.11  内存不足 540

    18.12  小结 541

    18.13  延伸阅读 542

    第4篇  调试和优化性能

    第19章  使用GDB进行调试 545

    19.1  技术要求 545

    19.2  GNU调试器 546

    19.3  准备调试 547

    19.4  调试应用程序 547

    19.4.1  使用gdbserver进行远程调试 548

    19.4.2  设置Yocto Project以进行远程调试 549

    19.4.3  为远程调试设置Buildroot 550

    19.5  启动调试 550

    19.5.1  连接GDB和gdbserver 550

    19.5.2  设置sysroot 551

    19.5.3  GDB命令文件 553

    19.5.4  GDB命令概述 554

    19.5.5  运行到断点 555

    19.5.6  用Python扩展GDB 556

    19.5.7  构建包含Python支持的GDB 556

    19.5.8  使用GDB远程调试bsdiff 559

    19.6  本机调试 560

    19.6.1  Yocto Project 560

    19.6.2  Buildroot 561

    19.7  即时调试 561

    19.8  调试分叉和线程 562

    19.9  核心文件 562

    19.9.1  观察核心文件 563

    19.9.2  使用GDB查看核心文件 564

    19.10  GDB用户界面 565

    19.10.1  终端用户界面 565

    19.10.2  数据显示调试器 566

    19.11  Visual Studio Code 567

    19.11.1  安装Visual Studio Code 567

    19.11.2  安装工具链 567

    19.11.3  安装CMake 569

    19.11.4  创建一个Visual Studio Code项目 569

    19.11.5  安装Visual Studio Code扩展 569

    19.11.6  配置CMake 570

    19.11.7  配置项目设置 571

    19.11.8  配置远程调试的启动设置 573

    19.12  调试内核代码 574

    19.12.1  使用kgdb调试内核代码 575

    19.12.2  调试会话示例 576

    19.12.3  调试早期代码 577

    19.12.4  调试模块 578

    19.12.5  使用kdb调试内核代码 579

    19.12.6  查看内核Oops消息 580

    19.12.7  保存Oops消息 583

    19.13  小结 584

    19.14  延伸阅读 585

    第20章  性能分析和跟踪 587

    20.1  技术要求 588

    20.2  观察者效应 588

    20.2.1  关于观察者效应 588

    20.2.2  符号表和编译标志 589

    20.3  开始性能分析 589

    20.4  使用top进行性能分析 590

    20.5  穷人的性能分析器 591

    20.6  perf简介 592

    20.6.1  为perf配置内核 593

    20.6.2  使用Yocto Project构建perf 593

    20.6.3  使用Buildroot构建perf 594

    20.6.4  使用perf进行性能分析 594

    20.6.5  调用图 596

    20.6.6  perf annotate 597

    20.7  跟踪事件 598

    20.8  Ftrace简介 599

    20.8.1  准备使用Ftrace 599

    20.8.2  使用Ftrace 600

    20.8.3  动态Ftrace和跟踪过滤器 602

    20.8.4  跟踪事件 603

    20.9  使用LTTng 604

    20.9.1  LTTng和Yocto Project 605

    20.9.2  LTTng和Buildroot 605

    20.9.3  使用LTTng进行内核跟踪 606

    20.10  使用BPF 608

    20.10.1  为BPF配置内核 608

    20.10.2  使用Buildroot构建BCC工具包 611

    20.10.3  使用BPF跟踪工具 612

    20.11  使用Valgrind 615

    20.11.1  Callgrind 615

    20.11.2  Helgrind 616

    20.12  使用strace 616

    20.13  小结 619

    20.14  延伸阅读 619

    第21章  实时编程 621

    21.1  技术要求 621

    21.2  关于实时 622

    21.3  识别非确定性的来源 624

    21.4  了解调度延迟 625

    21.5  内核抢占 626

    21.5.1  实时Linux内核(PREEMPT_RT) 627

    21.5.2  线程化中断处理程序 628

    21.6  可抢占内核锁 630

    21.6.1  获取PREEMPT_RT补丁 631

    21.6.2  Yocto Project和PREEMPT_RT 632

    21.7  高分辨率定时器 632

    21.8  避免页面错误 633

    21.9  中断屏蔽 634

    21.10  测量调度延迟 634

    21.10.1  cyclictest 635

    21.10.2  使用Ftrace 638

    21.10.3  结合cyclictest和Ftrace 639

    21.11  小结 640

    21.12  延伸阅读 641

     
  • 内容简介:
    《精通嵌入式Linux编程》详细阐述了与嵌入式Linux开发相关的基本解决方案,主要包括初识嵌入式Linux开发、关于工具链、引导加载程序详解、配置和构建内核、构建根文件系统、选择构建系统、使用Yocto进行开发、Yocto技术内幕、创建存储策略、现场更新软件、连接设备驱动程序、使用分线板进行原型设计、init程序、使用BusyBox runit启动、管理电源、打包Python程序、了解进程和线程、管理内存、使用GDB进行调试、性能分析和跟踪、实时编程等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。 本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册。
  • 作者简介:
    弗兰克·瓦斯奎兹是一位专注于消费电子产品的独立软件顾问。他在设计和构建嵌入式Linux系统方面拥有十多年的经验。在此期间,他完成了许多设备的开发,包括机架式DSP音频服务器、潜水员手持式声纳摄像机和消费者物联网热点。在成为嵌入式Linux开发工程师之前,Frank曾经是IBM的数据库内核开发人员,他在该公司主要从事DB2方面的工作。他目前住在硅谷。
  • 目录:
    第1篇  嵌入式Linux的要素

    第1章  初识嵌入式Linux开发 3

    1.1  选择Linux的原因 4

    1.2  不选择Linux的原因 5

    1.3  找到合适的玩家 5

    1.4  穿越项目生命周期 7

    1.4.1  篇章内容概述 7

    1.4.2  嵌入式Linux的4个基本要素 7

    1.5  开源的意义 8

    1.5.1  开源和免费有区别 8

    1.5.2  开源许可机制 8

    1.6  为嵌入式Linux开发选择硬件 10

    1.7  获取本书所需硬件 11

    1.7.1  Raspberry Pi 4 11

    1.7.2  BeagleBone Black 12

    1.7.3  QEMU 13

    1.8  配置开发环境 15

    1.9  小结 15

    第2章  关于工具链 17

    2.1  技术要求 17

    2.2  工具链简介 18

    2.2.1  工具链的类型 20

    2.2.2  CPU架构 21

    2.2.3  选择C库 22

    2.3  寻找工具链 24

    2.4  使用crosstool-NG构建工具链 26

    2.4.1  安装crosstool-NG 26

    2.4.2  为BeagleBone Black构建工具链 27

    2.4.3  为QEMU构建工具链 28

    2.5  工具链剖析 29

    2.5.1  了解你的交叉编译器 30

    2.5.2  sysroot、库和头文件 31

    2.5.3  工具链中的其他工具 32

    2.5.4  查看C库的组件 33

    2.6  与库链接—静态和动态链接 34

    2.6.1  静态库 34

    2.6.2  共享库 35

    2.6.3  了解共享库版本号 36

    2.7  交叉编译的技巧 37

    2.7.1  相对简单的makefile 38

    2.7.2  Autotools 38

    2.7.3  编译示例—SQLite 40

    2.7.4  包配置 42

    2.7.5  交叉编译带来的问题 43

    2.7.6  CMake 44

    2.8  小结 46

    2.9  延伸阅读 46

    第3章  引导加载程序详解 47

    3.1  技术要求 47

    3.2  引导加载程序的作用 48

    3.3  引导顺序 48

    3.3.1  阶段1—ROM代码 49

    3.3.2  阶段2—SPL 51

    3.3.3  阶段3—TPL 52

    3.4  从引导加载程序转移到内核中 53

    3.5  设备树简介 54

    3.5.1  有关设备树的基础知识 54

    3.5.2  reg属性 55

    3.5.3  标签和中断 56

    3.5.4  设备树包含文件 57

    3.5.5  编译设备树 59

    3.6  U-Boot 60

    3.6.1  构建U-Boot 60

    3.6.2  安装U-Boot 62

    3.6.3  使用U-Boot 64

    3.6.4  环境变量 65

    3.6.5  引导镜像格式 65

    3.6.6  加载镜像 67

    3.6.7  引导Linux 69

    3.6.8  使用U-Boot脚本自动化引导过程 69

    3.6.9  将U-Boot移植到新板上 69

    3.6.10  与特定开发板相关的文件 71

    3.6.11  配置头文件 73

    3.6.12  构建和测试 74

    3.6.13  Falcon模式 75

    3.7  小结 76

    第4章  配置和构建内核 77

    4.1  技术要求 77

    4.2  内核的作用 78

    4.3  选择内核 80

    4.3.1  内核开发周期 80

    4.3.2  稳定和长期支持版本 81

    4.3.3  供应商支持 82

    4.3.4  许可机制 82

    4.4  构建内核 83

    4.4.1  获取源 83

    4.4.2  了解内核配置—Kconfig 84

    4.4.3  使用LOCALVERSION识别内核 88

    4.4.4  使用内核模块的时机 89

    4.5  编译—Kbuild 90

    4.5.1  找出要构建的内核目标 90

    4.5.2  构建工件 91

    4.5.3  编译设备树 93

    4.5.4  编译模块 93

    4.5.5  清理内核源 94

    4.5.6  为Raspberry Pi 4构建64位内核 94

    4.5.7  为BeagleBone Black构建内核 96

    4.5.8  为QEMU构建内核 97

    4.6  引导内核 97

    4.6.1  引导Raspberry Pi 4 97

    4.6.2  引导BeagleBone Black 98

    4.6.3  引导QEMU 99

    4.6.4  内核恐慌 100

    4.6.5  早期用户空间 100

    4.6.6  内核消息 101

    4.6.7  内核命令行 101

    4.7  将Linux移植到新板上 102

    4.7.1  新的设备树 103

    4.7.2  设置开发板的兼容属性 104

    4.8  小结 106

    4.9  延伸阅读 107

    第5章  构建根文件系统 109

    5.1  技术要求 110

    5.2  根文件系统中应该包含的东西 110

    5.3  目录布局 111

    5.3.1  暂存目录 112

    5.3.2  POSIX文件访问权限 113

    5.3.3  暂存目录中的文件所有权权限 115

    5.4  根文件系统的程序 115

    5.4.1  init程序 115

    5.4.2  shell 115

    5.4.3  实用程序 116

    5.4.4  关于BusyBox 116

    5.4.5  构建BusyBox 117

    5.4.6  ToyBox—BusyBox的替代品 118

    5.5  根文件系统的库 119

    5.5.1  选择需要的库 119

    5.5.2  通过剥离减小尺寸 120

    5.6  设备节点 121

    5.7  proc和sysfs文件系统 122

    5.7.1  proc和sysfs文件系统的功能 123

    5.7.2  挂载文件系统 123

    5.7.3  内核模块 124

    5.8  将根文件系统传输到目标 124

    5.9  创建引导initramfs 125

    5.9.1  独立的initramfs 126

    5.9.2  引导initramfs 126

    5.9.3  使用QEMU引导 126

    5.9.4  引导BeagleBone Black 127

    5.9.5  挂载proc 127

    5.9.6  将initramfs构建到内核镜像中 128

    5.9.7  使用设备表构建initramfs 129

    5.9.8  旧的initrd格式 130

    5.10  init程序 130

    5.10.1  BusyBox的init程序 131

    5.10.2  启动守护进程 132

    5.11  配置用户账户 132

    5.11.1  配置账户 132

    5.11.2  将用户账户添加到根文件系统中 134

    5.12  管理设备节点的更好方法 134

    5.12.1  使用devtmpfs的示例 135

    5.12.2  使用mdev的示例 135

    5.12.3  静态设备节点的优劣 136

    5.13  配置网络 136

    5.13.1  BusyBox中的网络配置 136

    5.13.2  glibc的网络组件 137

    5.14  使用设备表创建文件系统镜像 138

    5.14.1  安装和使用genext2fs工具 138

    5.14.2  引导BeagleBone Black 139

    5.15  使用NFS挂载根文件系统 140

    5.15.1  使用QEMU进行测试 141

    5.15.2  使用BeagleBone Black进行测试 142

    5.15.3  文件权限问题 142

    5.16  使用TFTP加载内核 143

    5.17  小结 144

    5.18  延伸阅读 144

    第6章  选择构建系统 145

    6.1  技术要求 145

    6.2  比较构建系统 146

    6.3  分发二进制文件 148

    6.4  Buildroot简介 148

    6.4.1  Buildroot的背景知识 149

    6.4.2  稳定版本和长期支持版本 149

    6.4.3  安装Buildroot 149

    6.4.4  配置Buildroot 150

    6.4.5  运行 151

    6.4.6  以真实硬件为目标 153

    6.4.7  创建自定义BSP 154

    6.4.8  U-Boot配置 154

    6.4.9  Linux配置 155

    6.4.10  构建系统镜像 157

    6.4.11  添加自己的代码 159

    6.4.12  覆盖层 160

    6.4.13  添加包 160

    6.4.14  许可合规性 162

    6.5  Yocto Project简介 162

    6.5.1  Yocto Project的背景知识 163

    6.5.2  稳定版本和支持 164

    6.5.3  安装Yocto Project 165

    6.5.4  配置 165

    6.5.5  构建 166

    6.5.6  运行QEMU目标 167

    6.5.7  元层 167

    6.5.8  BitBake和配方 170

    6.5.9  通过local.conf自定义镜像 172

    6.5.10  编写镜像配方 173

    6.5.11  创建SDK 174

    6.5.12  许可证审核 176

    6.6  小结 176

    6.7  延伸阅读 177

    第7章  使用Yocto进行开发 179

    7.1  技术要求 179

    7.2  在现有BSP之上构建镜像 180

    7.2.1  构建现有的BSP 180

    7.2.2  控制Wi-Fi 186

    7.2.3  控制蓝牙 189

    7.2.4  添加自定义层 192

    7.3  使用devtool捕获更改 195

    7.3.1  开发工作流程 195

    7.3.2  创建新配方 197

    7.3.3  修改由配方构建的源 198

    7.3.4  将配方升级到较新版本 200

    7.4  构建自己的发行版 203

    7.4.1  推出发行版的合适时机 203

    7.4.2  创建一个新的发行层 203

    7.4.3  配置发行版 204

    7.4.4  向发行版添加更多配方 205

    7.4.5  运行时包管理 205

    7.5  配置远程包服务器 207

    7.5.1  配置包服务器 207

    7.5.2  配置目标客户端 208

    7.6  小结 209

    7.7  延伸阅读 209

    第8章  Yocto技术内幕 211

    8.1  技术要求 211

    8.2  Yocto架构和工作流程分解 212

    8.2.1  元数据 214

    8.2.2  构建任务 215

    8.2.3  镜像生成 217

    8.3  将元数据分层 218

    8.4  构建失败故障排除 220

    8.4.1  隔离错误 220

    8.4.2  检查和转储环境值 221

    8.4.3  读取任务日志 222

    8.4.4  添加更多日志记录 222

    8.4.5  从devshell中运行命令 223

    8.4.6  查看包的依赖关系 224

    8.5  了解BitBake语法和语义 225

    8.5.1  任务 225

    8.5.2  依赖项 226

    8.5.3  任务间依赖项 226

    8.5.4  构建时依赖项 226

    8.5.5  运行时依赖项 227

    8.5.6  变量 228

    8.5.7  赋值和扩展 228

    8.5.8  附加和前置 229

    8.5.9  覆盖 229

    8.5.10  内联Python 230

    8.5.11  函数 231

    8.5.12  shell 231

    8.5.13  Python 231

    8.5.14  纯Python函数 232

    8.5.15  BitBake风格的Python函数 232

    8.5.16  匿名Python函数 233

    8.5.17  RDEPENDS 234

    8.6  小结 235

    8.7  延伸阅读 235

    第2篇  系统架构和设计决策

    第9章  创建存储策略 239

    9.1  技术要求 239

    9.2  存储选项 240

    9.2.1  NOR闪存 241

    9.2.2  NAND闪存 241

    9.2.3  托管闪存 243

    9.2.4  多媒体卡和安全数字卡 244

    9.2.5  eMMC 245

    9.2.6  其他类型的托管闪存 245

    9.3  从引导加载程序中访问闪存 245

    9.3.1  U-Boot和NOR闪存 246

    9.3.2  U-Boot和NAND闪存 246

    9.3.3  U-Boot和MMC、SD和eMMC 246

    9.4  从Linux中访问闪存 247

    9.4.1  内存技术设备子系统 247

    9.4.2  MTD分区 248

    9.4.3  MTD设备驱动程序 251

    9.4.4  MTD字符设备 251

    9.4.5  MTD块设备mtdblock 252

    9.4.6  将内核错误记录到MTD上 253

    9.4.7  模拟NAND存储器 253

    9.4.8  MMC块驱动程序 253

    9.5  闪存文件系统 254

    9.5.1  闪存转换层的特点 254

    9.5.2  闪存转换层的部署方式 255

    9.6  NOR和NAND闪存的文件系统 255

    9.6.1  JFFS2 256

    9.6.2  摘要节点 257

    9.6.3  干净标记 257

    9.6.4  创建JFFS2文件系统 257

    9.6.5  YAFFS2 258

    9.6.6  创建YAFFS2文件系统 259

    9.6.7  UBI和UBIFS 260

    9.6.8  UBI 260

    9.6.9  UBIFS 263

    9.7  托管闪存的文件系统 264

    9.7.1  Flashbench 265

    9.7.2  丢弃和修剪 266

    9.7.3  Ext4 267

    9.7.4  F2FS 268

    9.7.5  FAT16/32 268

    9.8  只读压缩文件系统 269

    9.8.1  SquashFS 269

    9.8.2  在NAND闪存上使用SquashFS 269

    9.9  临时文件系统 270

    9.10  将根文件系统设为只读 271

    9.11  文件系统选择 272

    9.12  小结 273

    9.13  延伸阅读 273

    第10章  现场更新软件 275

    10.1  技术要求 275

    10.2  启动更新的方法 276

    10.3  更新的内容 276

    10.3.1  引导加载程序 277

    10.3.2  内核 277

    10.3.3  根文件系统 278

    10.3.4  系统应用程序 278

    10.3.5  与特定设备相关的数据 278

    10.3.6  需要更新的组件 279

    10.4  有关软件更新的基础知识 279

    10.4.1  使更新稳定可靠 279

    10.4.2  使更新不受故障影响 280

    10.4.3  确保更新安全 282

    10.5  更新机制的类型 283

    10.5.1  对称镜像更新 283

    10.5.2  非对称镜像更新 285

    10.5.3  原子文件更新 286

    10.6  OTA更新 288

    10.7  使用Mender进行本地更新 288

    10.7.1  构建Mender客户端 289

    10.7.2  安装更新 291

    10.8  使用Mender进行OTA更新 294

    10.8.1  设置更新服务器 294

    10.8.2  上传工件 297

    10.8.3  部署更新 299

    10.9  使用balena进行本地更新 301

    10.9.1  创建一个账户 302

    10.9.2  创建应用程序 303

    10.9.3  添加设备 304

    10.9.4  启用本地模式 306

    10.9.5  安装CLI 307

    10.9.6  推送一个项目 309

    10.9.7  修改和更新项目 310

    10.10  小结 311

    第11章  连接设备驱动程序 313

    11.1  技术要求 313

    11.2  设备驱动程序的作用 314

    11.3  字符设备 315

    11.4  块设备 317

    11.5  网络设备 318

    11.6  在运行时查找驱动程序 320

    11.6.1  从sysfs中获取信息 322

    11.6.2  设备 322

    11.6.3  驱动程序 323

    11.6.4  块驱动程序 324

    11.7  寻找合适的设备驱动程序 325

    11.8  用户空间中的设备驱动程序 325

    11.8.1  通用输入/输出接口 326

    11.8.2  处理来自GPIO的中断 327

    11.8.3  LED 329

    11.8.4  I2C 330

    11.8.5  SPI 332

    11.9  编写内核设备驱动程序 333

    11.9.1  设计字符设备驱动程序接口 333

    11.9.2  对于设备驱动程序的剖析 335

    11.9.3  编译内核模块 338

    11.9.4  加载内核模块 339

    11.10  发现硬件配置 339

    11.10.1  设备树 340

    11.10.2  平台数据 340

    11.10.3  将硬件与设备驱动程序链接在一起 341

    11.11  小结 343

    11.12  延伸阅读 344

    第12章  使用分线板进行原型设计 345

    12.1  技术要求 345

    12.2  将原理图映射到设备树的源中 346

    12.2.1  阅读原理图和数据表 347

    12.2.2  在BeagleBone Black上安装Debian 352

    12.2.3  启用spidev 353

    12.2.4  自定义设备树 359

    12.3  使用分线板进行原型设计 367

    12.3.1  闭合SPI跳线 368

    12.3.2  安装GNSS天线 370

    12.3.3  附加SPI接头 370

    12.3.4  连接SPI跳线 371

    12.4  使用逻辑分析仪探测SPI信号 375

    12.4.1  连接逻辑分析仪 376

    12.4.2  配置Logic 8 377

    12.5  通过SPI接收NMEA消息 383

    12.6  小结 387

    12.7  延伸阅读 387

    第13章  init程序 389

    13.1  技术要求 389

    13.2  内核引导后的操作 390

    13.3  init程序简介 391

    13.4  BusyBox init 392

    13.4.1  BusyBox init解析 392

    13.4.2  Buildroot init脚本 393

    13.5  System V init 393

    13.5.1  inittab 395

    13.5.2  init.d脚本 397

    13.5.3  添加新的守护进程 398

    13.5.4  启动和停止服务 399

    13.6  systemd 400

    13.6.1  使用Yocto Project和Buildroot构建systemd 400

    13.6.2  关于目标、服务和单元 401

    13.6.3  单元 401

    13.6.4  服务 402

    13.6.5  目标 402

    13.6.6  systemd引导系统的方式 403

    13.6.7  添加自己的服务 404

    13.6.8  添加看门狗 405

    13.6.9  对嵌入式Linux的影响 406

    13.7  小结 406

    13.8  延伸阅读 407

    第14章  使用BusyBox runit启动 409

    14.1  技术要求 409

    14.2  获取BusyBox runit 410

    14.3  创建服务目录和文件 416

    14.3.1  服务目录布局 417

    14.3.2  服务配置 418

    14.4  服务监督 425

    14.4.1  runsv脚本运行的服务 425

    14.4.2  控制服务 427

    14.5  服务依赖 429

    14.5.1  启动依赖项 429

    14.5.2  自定义启动依赖项 431

    14.5.3  简单总结 431

    14.6  专用服务日志记录 432

    14.6.1  专用日志记录器的工作方式 432

    14.6.2  向服务中添加专用日志记录 433

    14.6.3  日志轮转 434

    14.7  发出服务信号 435

    14.8  小结 436

    14.9  延伸阅读 437

    第15章  管理电源 439

    15.1  技术要求 439

    15.2  测量用电量 440

    15.3  调整时钟频率 443

    15.3.1  CPUFreq驱动程序 444

    15.3.2  使用CPUFreq 446

    15.4  选择最佳空闲状态 448

    15.4.1  CPUIdle驱动程序 449

    15.4.2  无滴答操作 452

    15.5  关闭外围设备 452

    15.6  使系统进入休眠状态 454

    15.6.1  电源状态 454

    15.6.2  唤醒事件 455

    15.6.3  从实时时钟定时唤醒 456

    15.7  小结 458

    15.8  延伸阅读 458

    第3篇  编写嵌入式应用程序

    第16章  打包Python程序 461

    16.1  技术要求 461

    16.1.1  安装venv 462

    16.1.2  安装Docker 462

    16.2  追溯Python打包的起源 463

    16.2.1  distutils 463

    16.2.2  setuptools 463

    16.2.3  setup.py 464

    16.3  使用pip安装Python包 466

    16.3.1  pip和pip3 466

    16.3.2  requirements.txt 469

    16.4  使用venv管理Python虚拟环境 471

    16.4.1  venv 472

    16.4.2  创建虚拟环境 473

    16.4.3  激活和验证虚拟环境 473

    16.4.4  在虚拟环境中安装测试库 474

    16.5  使用conda安装预编译的二进制文件 475

    16.5.1  环境管理 475

    16.5.2  验证根环境 476

    16.5.3  创建conda环境 477

    16.5.4  包管理 478

    16.5.5  导出虚拟环境 479

    16.6  使用Docker部署Python应用程序 480

    16.6.1  Dockerfile解析 481

    16.6.2  构建Docker镜像 483

    16.6.3  运行Docker镜像 484

    16.6.4  提取Docker镜像 485

    16.6.5  发布Docker镜像 485

    16.6.6  删除Docker容器 486

    16.6.7  删除Docker镜像 487

    16.6.8  Docker应用总结 487

    16.7  小结 488

    16.8  延伸阅读 488

    第17章  了解进程和线程 489

    17.1  技术要求 489

    17.2  进程和线程的抉择 490

    17.3  进程 492

    17.3.1  创建新进程 492

    17.3.2  终止进程 493

    17.3.3  运行不同的程序 494

    17.3.4  守护进程 497

    17.3.5  进程间通信 497

    17.3.6  基于消息的IPC 498

    17.3.7  UNIX套接字 498

    17.3.8  FIFO和命名管道 499

    17.3.9  POSIX消息队列 499

    17.3.10  基于消息的IPC总结 499

    17.3.11  基于共享内存的IPC 500

    17.3.12  POSIX共享内存 500

    17.4  线程 503

    17.4.1  创建一个新线程 503

    17.4.2  终止线程 505

    17.4.3  用线程编译程序 505

    17.4.4  线程间通信 505

    17.4.5  互斥锁 506

    17.4.6  不断变化的条件 506

    17.4.7  进程和线程应用规则 508

    17.5  ZeroMQ 509

    17.5.1  获取pyzmq 510

    17.5.2  进程之间的消息传递 510

    17.5.3  进程内的消息传递 512

    17.6  调度 514

    17.6.1  公平与确定性 514

    17.6.2  分时策略 515

    17.6.3  nice值 516

    17.6.4  实时策略 516

    17.6.5  选择策略 517

    17.6.6  选择实时优先级 518

    17.7  小结 518

    17.8  延伸阅读 518

    第18章  管理内存 521

    18.1  技术要求 521

    18.2  虚拟内存基础知识 522

    18.3  内核空间内存布局 523

    18.3.1  内核日志消息分析 523

    18.3.2  内核的内存使用情况 524

    18.4  用户空间内存布局 526

    18.5  进程内存映射 528

    18.6  交换 529

    18.6.1  交换的利弊 529

    18.6.2  交换到压缩内存 530

    18.7  使用mmap映射内存 530

    18.7.1  使用mmap分配私有内存 531

    18.7.2  使用mmap共享内存 531

    18.7.3  使用mmap访问设备内存 532

    18.8  应用程序的内存使用情况 532

    18.9  每个进程的内存使用情况 533

    18.9.1  使用top和ps 534

    18.9.2  使用smem 534

    18.9.3  其他工具 536

    18.10  识别内存泄漏 537

    18.10.1  mtrace 537

    18.10.2  Valgrind 538

    18.11  内存不足 540

    18.12  小结 541

    18.13  延伸阅读 542

    第4篇  调试和优化性能

    第19章  使用GDB进行调试 545

    19.1  技术要求 545

    19.2  GNU调试器 546

    19.3  准备调试 547

    19.4  调试应用程序 547

    19.4.1  使用gdbserver进行远程调试 548

    19.4.2  设置Yocto Project以进行远程调试 549

    19.4.3  为远程调试设置Buildroot 550

    19.5  启动调试 550

    19.5.1  连接GDB和gdbserver 550

    19.5.2  设置sysroot 551

    19.5.3  GDB命令文件 553

    19.5.4  GDB命令概述 554

    19.5.5  运行到断点 555

    19.5.6  用Python扩展GDB 556

    19.5.7  构建包含Python支持的GDB 556

    19.5.8  使用GDB远程调试bsdiff 559

    19.6  本机调试 560

    19.6.1  Yocto Project 560

    19.6.2  Buildroot 561

    19.7  即时调试 561

    19.8  调试分叉和线程 562

    19.9  核心文件 562

    19.9.1  观察核心文件 563

    19.9.2  使用GDB查看核心文件 564

    19.10  GDB用户界面 565

    19.10.1  终端用户界面 565

    19.10.2  数据显示调试器 566

    19.11  Visual Studio Code 567

    19.11.1  安装Visual Studio Code 567

    19.11.2  安装工具链 567

    19.11.3  安装CMake 569

    19.11.4  创建一个Visual Studio Code项目 569

    19.11.5  安装Visual Studio Code扩展 569

    19.11.6  配置CMake 570

    19.11.7  配置项目设置 571

    19.11.8  配置远程调试的启动设置 573

    19.12  调试内核代码 574

    19.12.1  使用kgdb调试内核代码 575

    19.12.2  调试会话示例 576

    19.12.3  调试早期代码 577

    19.12.4  调试模块 578

    19.12.5  使用kdb调试内核代码 579

    19.12.6  查看内核Oops消息 580

    19.12.7  保存Oops消息 583

    19.13  小结 584

    19.14  延伸阅读 585

    第20章  性能分析和跟踪 587

    20.1  技术要求 588

    20.2  观察者效应 588

    20.2.1  关于观察者效应 588

    20.2.2  符号表和编译标志 589

    20.3  开始性能分析 589

    20.4  使用top进行性能分析 590

    20.5  穷人的性能分析器 591

    20.6  perf简介 592

    20.6.1  为perf配置内核 593

    20.6.2  使用Yocto Project构建perf 593

    20.6.3  使用Buildroot构建perf 594

    20.6.4  使用perf进行性能分析 594

    20.6.5  调用图 596

    20.6.6  perf annotate 597

    20.7  跟踪事件 598

    20.8  Ftrace简介 599

    20.8.1  准备使用Ftrace 599

    20.8.2  使用Ftrace 600

    20.8.3  动态Ftrace和跟踪过滤器 602

    20.8.4  跟踪事件 603

    20.9  使用LTTng 604

    20.9.1  LTTng和Yocto Project 605

    20.9.2  LTTng和Buildroot 605

    20.9.3  使用LTTng进行内核跟踪 606

    20.10  使用BPF 608

    20.10.1  为BPF配置内核 608

    20.10.2  使用Buildroot构建BCC工具包 611

    20.10.3  使用BPF跟踪工具 612

    20.11  使用Valgrind 615

    20.11.1  Callgrind 615

    20.11.2  Helgrind 616

    20.12  使用strace 616

    20.13  小结 619

    20.14  延伸阅读 619

    第21章  实时编程 621

    21.1  技术要求 621

    21.2  关于实时 622

    21.3  识别非确定性的来源 624

    21.4  了解调度延迟 625

    21.5  内核抢占 626

    21.5.1  实时Linux内核(PREEMPT_RT) 627

    21.5.2  线程化中断处理程序 628

    21.6  可抢占内核锁 630

    21.6.1  获取PREEMPT_RT补丁 631

    21.6.2  Yocto Project和PREEMPT_RT 632

    21.7  高分辨率定时器 632

    21.8  避免页面错误 633

    21.9  中断屏蔽 634

    21.10  测量调度延迟 634

    21.10.1  cyclictest 635

    21.10.2  使用Ftrace 638

    21.10.3  结合cyclictest和Ftrace 639

    21.11  小结 640

    21.12  延伸阅读 641

     
查看详情
12
相关图书 / 更多
精通嵌入式Linux编程
精通 Power Query
(加拿大)肯·普尔斯
精通嵌入式Linux编程
精通套期保值
李录林 著
精通嵌入式Linux编程
精通STM32F4(HAL库版)(上)
刘军 凌柱宁 徐伟健 江荧
精通嵌入式Linux编程
精通FrontPage XP(中文版)
中国IT培训工程编委会 编
精通嵌入式Linux编程
精通咬合重建——解读牙列不齐、牙周病、多牙缺失
吴松涛 周茂强 译;[日]上田 秀朗
精通嵌入式Linux编程
精通Veeam Backup & Replication(原书第2版)
克里斯·奇尔德霍森(Chris Childerhose)
精通嵌入式Linux编程
精通Shiny(Mastering Shiny)
Hadley Wickham
精通嵌入式Linux编程
精通区块链开发技术(第2版)
[美]伊姆兰·巴希尔 著;王烈征 译
精通嵌入式Linux编程
精通Apache Pulsar:可伸缩云原生事件流实践
[美]Jowanza Joseph(乔万扎·约瑟夫
精通嵌入式Linux编程
精通机器学习算法
[意]朱塞佩·博纳科尔索(Giuseppe Bonaccorso)
精通嵌入式Linux编程
精通Transformer:从零开始构建最先进的NLP模型
[伊朗]梅萨姆·阿斯加里-切纳格卢 著;江红 余青松 余靖 译;[土耳其]萨瓦斯·伊尔蒂利姆
精通嵌入式Linux编程
精通Neo4j
张帜 庞国明 叶伟民 宋建栋 马延超 杨志
您可能感兴趣 / 更多
精通嵌入式Linux编程
无辜者的谎言(相信我!看到结局你一定会头皮发麻;全美读者推荐的悬疑神作,GOODREADS高分作品)
[美]A.R.托雷 著;梁颂宇 译;星文文化 出品
精通嵌入式Linux编程
孩子,把你的手给我1:怎么说孩子才爱听,怎么教孩子才肯学?帮助每一位3-12岁孩子的父母结束与孩子的所有冲突!
[美]海姆·G.吉诺特
精通嵌入式Linux编程
哲学、历史与僭政——重审施特劳斯与科耶夫之争
[美]弗罗斯特(Bryan-Paul Frost) 编;[美]伯恩斯(Timothy W. Burns)
精通嵌入式Linux编程
怎样做成大事
[美]丹·加德纳(Dan Gardner) 著;贾拥民 译;湛庐文化 出品;[丹麦]傅以斌(Bent Flyvbjerg)
精通嵌入式Linux编程
力量训练的科学基础与实践应用(第三版)
[美]弗拉基米尔· M.扎齐奥尔斯基;[美]威廉·J.克雷默;[美]安德鲁· C.弗赖伊
精通嵌入式Linux编程
1200年希腊罗马神话
[美]伊迪丝·汉密尔顿
精通嵌入式Linux编程
爱情心理学(新编本)
[美]罗伯特·J. 斯腾伯格 (美)凯琳·斯腾伯格 倪爱萍 译
精通嵌入式Linux编程
黄金圈法则
[美]西蒙·斯涅克 著;磨铁文化 出品
精通嵌入式Linux编程
最后一章
[美]厄尼·派尔
精通嵌入式Linux编程
汤姆·索亚历险记 彩图注音版 一二三四年级5-6-7-8-9岁小学生课外阅读经典 儿童文学无障碍有声伴读世界名著童话故事
[美]马克 吐温
精通嵌入式Linux编程
富兰克林自传 名家全译本 改变无数人命运的励志传奇 埃隆马斯克反复推荐 赠富兰克林签名照及精美插图
[美]本杰明·富兰克林 著;李自修 译
精通嵌入式Linux编程
国际大奖图画书系列 共11册(小老鼠的恐惧的大书,大灰狼,红豆与菲比,别烦我,下雪了 ,穿靴子的猫 ,先有蛋,绿 ,特别快递,如果你想看鲸鱼 ,一个部落的孩子 ) 麦克米伦世纪
[美]莱恩·史密斯 (英)埃米莉·格雷维特 (美)劳拉·瓦卡罗·等/文 (英)埃米莉·格雷维特 等/图 彭懿 杨玲玲 阿甲 孙慧阳 白薇 译