奔跑吧Linux内核入门篇(第2版)

奔跑吧Linux内核入门篇(第2版)
分享
扫描下方二维码分享到微信
打开微信,点击右上角”+“,
使用”扫一扫“即可将网页分享到朋友圈。
作者:
2021-02
版次: 2
ISBN: 9787115555601
定价: 129.00
装帧: 其他
开本: 其他
纸张: 胶版纸
页数: 360页
23人买过
  • 本书基于Linux 5.0和ARM64处理器循序渐进地讲述Linux内核的理论与实验。本书共16章,主要介绍Linux系统基础知识、Linux内核基础知识、ARM64架构基础知识、内核编译和调试、内核模块、简单的字符设备驱动、系统调用、进程管理、内存管理、同步管理、中断管理、调试和性能优化、开源社区、文件系统、虚拟化与云计算等方面的内容,并通过一个综合能力训练来引导读者动手实现一个小的操作系统。
      本书适合Linux开发人员、嵌入式开发人员以及对Linux感兴趣的程序员阅读,也适合作为高等院校计算机相关专业的教材。 笨叔,Linux内核爱好者,出版过《奔跑吧Linux内核》《奔跑吧Linux内核 入门篇》。

    陈悦,Linux内核爱好者,南昌大学教师,主要负责计算机方面的“操作系统”“汇编语言”与“计算机组成原理”等课程的教学与研究。 目 录

    第1章 Linux系统基础知识 1

    1.1 Linux系统的发展历史 1

    1.2 Linux发行版 2

    1.2.1 Red Hat Linux 2

    1.2.2 Debian Linux 3

    1.2.3 SuSE Linux 4

    1.2.4 优麒麟Linux 4

    1.3 Linux内核介绍 5

    1.3.1 Linux内核目录结构 5

    1.3.2 宏内核和微内核 7

    1.3.3 Linux内核概貌 8

    1.4 如何学习Linux内核 11

    1.5 Linux内核实验入门 12

    1.5.1 实验1-1:在虚拟机中安装

    优麒麟Linux 20.04系统 12

    1.5.2 实验1-2:给优麒麟Linux

    系统更换“心脏” 15

    1.5.3 实验1-3:使用QEMU虚拟机

    来运行Linux系统 17

    1.5.4 实验1-4:创建基于Ubuntu

    Linux的根文件系统 22

    1.5.5 实验1-5:创建基于QEMU  

    RISC-V的Linux系统 22

    第2章 Linux内核基础知识 24

    2.1 Linux常用的编译工具 24

    2.1.1 GCC 24

    2.1.2 ARM GCC 25

    2.1.3 GCC编译 26

    2.2 Linux内核中常用的C语言

    技巧 27

    2.3 Linux内核中常用的数据结构和

    算法 33

    2.3.1 链表 33

    2.3.2 红黑树 36

    2.3.3 无锁环形缓冲区 38

    2.4 Vim工具的使用 40

    2.4.1 Vim 8介绍 40

    2.4.2 Vim的基本模式 41

    2.4.3 Vim中3种模式的切换 41

    2.4.4 Vim光标的移动 42

    2.4.5 删除、复制和粘贴 43

    2.4.6 查找和替换 43

    2.4.7 与文件相关的命令 44

    2.5 git工具的使用 44

    2.5.1 安装git 45

    2.5.2 git基本操作 45

    2.5.3 分支管理 48

    2.6 实验 50

    2.6.1 实验2-1:GCC编译 50

    2.6.2 实验2-2:内核链表 54

    2.6.3 实验2-3:红黑树 54

    2.6.4 实验2-4:使用Vim

    工具 54

    2.6.5 实验2-5:把Vim打造成一个

    强大的IDE编辑工具 55

    2.6.6 实验2-6:建立一个git本地

    仓库 63

    2.6.7 实验2-7:解决分支合并

    冲突 65

    2.6.8 实验2-8:利用git来管理

    Linux内核开发 67

    2.6.9 实验2-9:利用git来管理

    项目代码 69

    第3章 ARM64架构基础知识 75

    3.1 ARM64架构介绍 76

    3.1.1 ARMv8-A架构介绍 76

    3.1.2 常见的ARMv8处理器 76

    3.1.3 ARM64的基本概念 77

    3.1.4 ARMv8处理器的运行

    状态 78

    3.1.5 ARMv8架构支持的数据

    宽度 79

    3.1.6 不对齐访问 79

    3.2 ARMv8寄存器 79

    3.2.1 通用寄存器 79

    3.2.2 处理器状态寄存器 80

    3.2.3 特殊寄存器 82

    3.2.4 系统寄存器 84

    3.3 A64指令集 85

    3.3.1 算术和移位操作指令 85

    3.3.2 乘和除操作指令 86

    3.3.3 移位操作指令 87

    3.3.4 位操作指令 87

    3.3.5 条件操作指令 87

    3.3.6 内存加载指令 89

    3.3.7 多字节内存加载和存储

    指令 91

    3.3.8 非特权访问级别的加载和

    存储指令 91

    3.3.9 内存屏障指令 92

    3.3.10 独占访存指令 92

    3.3.11 跳转指令 92

    3.3.12 异常处理指令 93

    3.3.13 系统寄存器访问指令 93

    3.4 ARM64异常处理 95

    3.4.1 异常类型 95

    3.4.2 同步异常和异步异常 96

    3.4.3 异常的发生和退出 96

    3.4.4 异常向量表 97

    3.5 ARM64内存管理 99

    3.5.1 页表 100

    3.5.2 页表映射 101

    3.6 实验平台:树莓派 102

    3.6.1 树莓派4介绍 103

    3.6.2 实验3-1:在树莓派上安装

    优麒麟Linux 20.04

    系统 104

    3.6.3 实验3-2:汇编语言

    练习—查找最大数 105

    3.6.4 实验3-3:汇编语言

    练习—通过C语言

    调用汇编函数 105

    3.6.5 实验3-4:汇编语言

    练习—通过汇编语言

    调用C函数 106

    3.6.6 实验3-5:汇编语言

    练习—GCC内联汇编 106

    3.6.7 实验3-6:在树莓派上编写

    一个裸机程序 106

    第4章 内核编译和调试 107

    4.1 内核配置 107

    4.1.1 内核配置工具 107

    4.1.2 .config文件 108

    4.2 实验4-1:通过QEMU虚拟机

    调试ARMv8的Linux内核 110

    4.3 实验4-2:通过Eclipse   QEMU

    单步调试内核 111

    第5章 内核模块 116

    5.1 从一个内核模块开始 116

    5.2 模块参数 120

    5.3 符号共享 122

    5.4 实验 123

    5.4.1 实验5-1:编写一个简单的

    内核模块 123

    5.4.2 实验5-2:向内核模块传递

    参数 124

    5.4.3 实验5-3:在模块之间导出

    符号 124

    第6章 简单的字符设备驱动 125

    6.1 从一个简单的字符设备开始 126

    6.1.1 一个简单的字符设备 126

    6.1.2 实验6-1:写一个简单的

    字符设备驱动 131

    6.2 字符设备驱动详解 131

    6.2.1 字符设备驱动的抽象 131

    6.2.2 设备号的管理 133

    6.2.3 设备节点 133

    6.2.4 字符设备操作方法集 134

    6.3 misc机制 136

    6.3.1 misc机制介绍 136

    6.3.2 实验6-2:使用misc机制

    来创建设备驱动 136

    6.4 一个简单的虚拟设备 138

    6.4.1 实验6-3:为虚拟设备

    编写驱动 138

    6.4.2 实验6-4:使用KFIFO环形

    缓冲区改进设备驱动 141

    6.5 阻塞I O和非阻塞I O 143

    6.5.1 实验6-5:把虚拟设备驱动

    改成非阻塞模式 144

    6.5.2 实验6-6:把虚拟设备驱动

    改成阻塞模式 147

    6.6 I O多路复用 151

    6.6.1 Linux内核的I O多路

    复用 151

    6.6.2 实验6-7:向虚拟设备中

    添加I O多路复用支持 152

    6.6.3 实验6-8:为什么不能唤醒

    读写进程 157

    6.7 添加异步通知 159

    6.7.1 异步通知介绍 159

    6.7.2 实验6-9:向虚拟设备添加

    异步通知 159

    6.7.3 实验6-10:解决驱动的

    宕机难题 163

    6.8 本章小结 164

    第7章 系统调用 166

    7.1 系统调用的概念 166

    7.1.1 系统调用和POSIX标准 167

    7.1.2 系统调用表 167

    7.1.3 用程序访问系统调用 169

    7.1.4 新增系统调用 170

    7.2 实验 170

    7.2.1 实验7-1:在树莓派上新增

    一个系统调用 170

    7.2.2 实验7-2:在Linux主机上

    新增一个系统调用 170

    第8章 进程管理 172

    8.1 进程 172

    8.1.1 进程的由来 172

    8.1.2 进程描述符 174

    8.1.3 进程的生命周期 176

    8.1.4 进程标识 178

    8.1.5 进程间的家族关系 179

    8.1.6 获取当前进程 181

    8.2 进程的创建和终止 183

    8.2.1 写时复制技术 185

    8.2.2 fork()函数 186

    8.2.3 vfork()函数 187

    8.2.4 clone()函数 187

    8.2.5 内核线程 188

    8.2.6 do_fork()函数 189

    8.2.7 终止进程 191

    8.2.8 僵尸进程和托孤进程 191

    8.2.9 进程0和进程1 192

    8.3 进程调度 193

    8.3.1 进程的分类 193

    8.3.2 进程的优先级和权重 193

    8.3.3 调度策略 195

    8.3.4 时间片 198

    8.3.5 经典调度算法 198

    8.3.6 Linux O(n)调度算法 200

    8.3.7 Linux O(1)调度算法 200

    8.3.8 Linux CFS算法 201

    8.3.9 进程切换 204

    8.3.10 与调度相关的数据结构 210

    8.4 多核调度 214

    8.4.1 调度域和调度组 215

    8.4.2 负载的计算 218

    8.4.3 负载均衡算法 221

    8.4.4 Per-CPU变量 222

    8.5 实验 223

    8.5.1 实验8-1:fork和clone系统

    调用 223

    8.5.2 实验8-2:内核线程 224

    8.5.3 实验8-3:后台守护进程 224

    8.5.4 实验8-4:进程权限 224

    8.5.5 实验8-5:设置优先级 224

    8.5.6 实验8-6:Per-CPU变量 225

    第9章 内存管理 226

    9.1 从硬件角度看内存管理 226

    9.1.1 内存管理的“远古

    时代” 226

    9.1.2 地址空间的抽象 228

    9.1.3 分段机制 229

    9.1.4 分页机制 230

    9.2 从软件角度看内存管理 234

    9.2.1 free命令 234

    9.2.2 从应用编程角度看内存

    管理 235

    9.2.3 从内存布局图角度看内存

    管理 236

    9.2.4 从进程角度看内存管理 239

    9.2.5 从内核角度看内存管理 243

    9.3 物理内存管理 244

    9.3.1 物理页面 244

    9.3.2 内存管理区 250

    9.3.3 分配和释放页面 252

    9.3.4 关于内存碎片化 258

    9.3.5 分配小块内存 260

    9.4 虚拟内存管理 268

    9.4.1 进程地址空间 268

    9.4.2 内存描述符mm_struct 269

    9.4.3 VMA管理 270

    9.4.4 VMA属性 273

    9.4.5 VMA查找操作 276

    9.4.6 malloc()函数 277

    9.4.7 mmap() munmap()函数 280

    9.5 缺页异常 284

    9.5.1 do_page_fault()函数 285

    9.5.2 匿名页面缺页异常 286

    9.5.3 文件映射缺页中断 286

    9.5.4 写时复制缺页异常 287

    9.6 内存短缺 287

    9.6.1 页面回收算法 287

    9.6.2 OOM Killer机制 289

    9.7 内存管理日志信息以及调试

    信息 289

    9.7.1 vm_stat计数 289

    9.7.2 meminfo分析 291

    9.7.3 伙伴系统信息 293

    9.7.4 查看内存管理区的信息 294

    9.7.5 查看进程相关的内存

    信息 296

    9.7.6 查看系统内存信息的

    工具 298

    9.8 内存管理实验 300

    9.8.1 实验9-1:查看系统内存

    信息 301

    9.8.2 实验9-2:获取系统的物理

    内存信息 301

    9.8.3 实验9-3:分配内存 301

    9.8.4 实验9-4:slab 302

    9.8.5 实验9-5:VMA 302

    9.8.6 实验9-6:mmap 302

    9.8.7 实验9-7:映射用户

    内存 303

    9.8.8 实验9-8:OOM 303

    第10章 同步管理 304

    10.1 原子操作与内存屏障 305

    10.1.1 原子操作 305

    10.1.2 内存屏障 309

    10.2 自旋锁机制 310

    10.2.1 自旋锁的定义 310

    10.2.2 Qspinlock的实现 311

    10.2.3 自旋锁的变种 312

    10.2.4 自旋锁和raw_spin_lock 313

    10.3 信号量 314

    10.4 互斥锁 315

    10.5 读写锁 317

    10.5.1 读写锁的定义 317

    10.5.2 读写信号量 318

    10.6 RCU 320

    10.7 等待队列 323

    10.7.1 等待队列头 323

    10.7.2 等待队列节点 324

    10.8 实验 324

    10.8.1 实验10-1:自旋锁 324

    10.8.2 实验10-2:互斥锁 325

    10.8.3 实验10-3:RCU锁 325

    第11章 中断管理 326

    11.1 Linux中断管理机制 326

    11.1.1 ARM中断控制器 327

    11.1.2 关于ARM Vexpress V2P

    开发板的例子 327

    11.1.3 关于Virt开发板的例子 329

    11.1.4 硬件中断号和Linux中断号

    的映射 330

    11.1.5 注册中断 331

    11.2 软中断和tasklet 333

    11.2.1 软中断 334

    11.2.2 tasklet 335

    11.2.3 local_bh_disable() local_

    bh_enable() 336

    11.2.4 小结 337

    11.3 工作队列机制 337

    11.3.1 工作队列的类型 338

    11.3.2 使用工作队列 340

    11.3.3 小结 340

    11.4 实验 341

    11.4.1 实验11-1:tasklet 341

    11.4.2 实验11-2:工作队列 341

    11.4.3 实验11-3:定时器和

    内核线程 341

    第12章 调试和性能优化 343

    12.1 printk()输出函数和动态输出 343

    12.1.1 printk()输出函数 343

    12.1.2 动态输出 345

    12.1.3 实验12-1:使用printk()

    输出函数 347

    12.1.4 实验12-2:使用动态

    输出 347

    12.2 proc和debugfs 347

    12.2.1 proc文件系统 347

    12.2.2 sys文件系统 350

    12.2.3 debugfs文件系统 351

    12.2.4 实验12-3:使用procfs 351

    12.2.5 实验12-4:使用sysfs 353

    12.2.6 实验12-5:使用

    debugfs 355

    12.3 ftrace 355

    12.3.1 irqsoff跟踪器 357

    12.3.2 function跟踪器 358

    12.3.3 动态ftrace 359

    12.3.4 事件跟踪 361

    12.3.5 实验12-6:使用ftrace 363

    12.3.6 实验12-7:添加新的

    跟踪点 363

    12.3.7 实验12-8:使用示踪

    标志 366

    12.3.8 实验12-9:使用kernelshark

    分析数据 369

    12.4 分析Oops错误 371

    12.4.1 Oops错误介绍 371

    12.4.2 实验12-10 :分析Oops

    错误 371

    12.5 perf性能分析工具 375

    12.5.1 perf list命令 376

    12.5.2 利用perf采集数据 377

    12.5.3 perf stat 378

    12.5.4 perf top 379

    12.5.5 实验12-11:使用perf工具

    进行性能分析 380

    12.5.6 实验12-12:采集perf数据

    以生成火焰图 381

    12.6 内存检测 381

    12.6.1 实验12-13:使用slub_debug

    检查内存泄漏 382

    12.6.2 实验12-14:使用kmemleak

    检查内存泄漏 387

    12.6.3 实验12-15:使用kasan检查

    内存泄漏 389

    12.6.4 实验12-16:使用valgrind

    检查内存泄漏 393

    12.7 使用kdump解决死机问题 394

    12.7.1 kdump介绍 394

    12.7.2 实验12-17:搭建ARM64的

    kdump实验环境 395

    12.7.3 实验12-18:分析一个简单的

    宕机案例 398

    12.8 性能和测试 401

    12.8.1 性能和测试概述 401

    12.8.2 eBPF介绍 402

    12.8.3 BCC介绍 403

    12.8.4 实验12-19:运行BCC

    工具进行性能测试 404

    第13章 开源社区 405

    13.1 什么是开源社区 405

    13.1.1 开源软件的发展历史 405

    13.1.2 Linux基金会 406

    13.1.3 开源协议 406

    13.1.4 Linux内核社区 408

    13.1.5 国内开源社区 409

    13.2 参与开源社区 409

    13.2.1 参与开源项目的

    好处 409

    13.2.2 如何参与开源项目 410

    13.3 实验13-1:使用cppcheck检查

    代码 411

    13.4 实验13-2:提交第一个Linux

    内核补丁 412

    13.5 实验13-3:管理和提交多个补丁

    组成的补丁集 414

    第14章 文件系统 419

    14.1 文件系统的基本概念 419

    14.1.1 文件 419

    14.1.2 目录 422

    14.2 文件系统的基本概念和

    知识 423

    14.2.1 文件系统的布局 423

    14.2.2 索引数据块 428

    14.2.3 管理空闲块 430

    14.2.4 高速缓存 430

    14.3 虚拟文件系统层 431

    14.4 文件系统的一致性 436

    14.5 一次写磁盘的全过程 439

    14.6 文件系统实验 440

    14.6.1 实验14-1:查看文件

    系统 440

    14.6.2 实验14-2:删除文件

    内容 441

    14.6.3 实验14-3:块设备 441

    14.6.4 实验14-4:动手写一个简单

    的文件系统 441

    第15章 虚拟化与云计算 442

    15.1 虚拟化技术 442

    15.1.1 虚拟化技术的发展

    历史 442

    15.1.2 虚拟机管理程序的

    分类 444

    15.1.3 内存虚拟化 445

    15.1.4 I O虚拟化 445

    15.2 容器技术 446

    15.3 云计算 448

    15.3.1 云编排 450

    15.3.2 OpenStack介绍 451

    15.3.3 Kubernetes介绍 451

    15.4 实验 452

    15.4.1 实验15-1:制作Docker

    镜像并发布 452

    15.4.2 实验15-2:部署Kubernetes

    服务 452

    第16章 综合能力训练:动手写一个

    小OS 453

    16.1 实验准备 454

    16.1.1 开发流程 454

    16.1.2 配置串口线 454

    16.1.3 寄存器地址 457

    16.2 入门动手篇 457

    16.2.1 实验16-1:输出

    “Welcome BenOS!” 457

    16.2.2 使用GDB   QEMU调试

    BenOS 465

    16.2.3 使用J-Link仿真器调试树

    莓派 466

    16.2.4 实验16-2:切换异常

    等级 473

    16.2.5 实验16-3:实现简易的

    printk()函数 473

    16.2.6 实验16-4:中断 473

    16.2.7 实验16-5:创建

    进程 475

    16.3 进阶挑战篇 475

    16.4 高手完善篇 476
  • 内容简介:
    本书基于Linux 5.0和ARM64处理器循序渐进地讲述Linux内核的理论与实验。本书共16章,主要介绍Linux系统基础知识、Linux内核基础知识、ARM64架构基础知识、内核编译和调试、内核模块、简单的字符设备驱动、系统调用、进程管理、内存管理、同步管理、中断管理、调试和性能优化、开源社区、文件系统、虚拟化与云计算等方面的内容,并通过一个综合能力训练来引导读者动手实现一个小的操作系统。
      本书适合Linux开发人员、嵌入式开发人员以及对Linux感兴趣的程序员阅读,也适合作为高等院校计算机相关专业的教材。
  • 作者简介:
    笨叔,Linux内核爱好者,出版过《奔跑吧Linux内核》《奔跑吧Linux内核 入门篇》。

    陈悦,Linux内核爱好者,南昌大学教师,主要负责计算机方面的“操作系统”“汇编语言”与“计算机组成原理”等课程的教学与研究。
  • 目录:
    目 录

    第1章 Linux系统基础知识 1

    1.1 Linux系统的发展历史 1

    1.2 Linux发行版 2

    1.2.1 Red Hat Linux 2

    1.2.2 Debian Linux 3

    1.2.3 SuSE Linux 4

    1.2.4 优麒麟Linux 4

    1.3 Linux内核介绍 5

    1.3.1 Linux内核目录结构 5

    1.3.2 宏内核和微内核 7

    1.3.3 Linux内核概貌 8

    1.4 如何学习Linux内核 11

    1.5 Linux内核实验入门 12

    1.5.1 实验1-1:在虚拟机中安装

    优麒麟Linux 20.04系统 12

    1.5.2 实验1-2:给优麒麟Linux

    系统更换“心脏” 15

    1.5.3 实验1-3:使用QEMU虚拟机

    来运行Linux系统 17

    1.5.4 实验1-4:创建基于Ubuntu

    Linux的根文件系统 22

    1.5.5 实验1-5:创建基于QEMU  

    RISC-V的Linux系统 22

    第2章 Linux内核基础知识 24

    2.1 Linux常用的编译工具 24

    2.1.1 GCC 24

    2.1.2 ARM GCC 25

    2.1.3 GCC编译 26

    2.2 Linux内核中常用的C语言

    技巧 27

    2.3 Linux内核中常用的数据结构和

    算法 33

    2.3.1 链表 33

    2.3.2 红黑树 36

    2.3.3 无锁环形缓冲区 38

    2.4 Vim工具的使用 40

    2.4.1 Vim 8介绍 40

    2.4.2 Vim的基本模式 41

    2.4.3 Vim中3种模式的切换 41

    2.4.4 Vim光标的移动 42

    2.4.5 删除、复制和粘贴 43

    2.4.6 查找和替换 43

    2.4.7 与文件相关的命令 44

    2.5 git工具的使用 44

    2.5.1 安装git 45

    2.5.2 git基本操作 45

    2.5.3 分支管理 48

    2.6 实验 50

    2.6.1 实验2-1:GCC编译 50

    2.6.2 实验2-2:内核链表 54

    2.6.3 实验2-3:红黑树 54

    2.6.4 实验2-4:使用Vim

    工具 54

    2.6.5 实验2-5:把Vim打造成一个

    强大的IDE编辑工具 55

    2.6.6 实验2-6:建立一个git本地

    仓库 63

    2.6.7 实验2-7:解决分支合并

    冲突 65

    2.6.8 实验2-8:利用git来管理

    Linux内核开发 67

    2.6.9 实验2-9:利用git来管理

    项目代码 69

    第3章 ARM64架构基础知识 75

    3.1 ARM64架构介绍 76

    3.1.1 ARMv8-A架构介绍 76

    3.1.2 常见的ARMv8处理器 76

    3.1.3 ARM64的基本概念 77

    3.1.4 ARMv8处理器的运行

    状态 78

    3.1.5 ARMv8架构支持的数据

    宽度 79

    3.1.6 不对齐访问 79

    3.2 ARMv8寄存器 79

    3.2.1 通用寄存器 79

    3.2.2 处理器状态寄存器 80

    3.2.3 特殊寄存器 82

    3.2.4 系统寄存器 84

    3.3 A64指令集 85

    3.3.1 算术和移位操作指令 85

    3.3.2 乘和除操作指令 86

    3.3.3 移位操作指令 87

    3.3.4 位操作指令 87

    3.3.5 条件操作指令 87

    3.3.6 内存加载指令 89

    3.3.7 多字节内存加载和存储

    指令 91

    3.3.8 非特权访问级别的加载和

    存储指令 91

    3.3.9 内存屏障指令 92

    3.3.10 独占访存指令 92

    3.3.11 跳转指令 92

    3.3.12 异常处理指令 93

    3.3.13 系统寄存器访问指令 93

    3.4 ARM64异常处理 95

    3.4.1 异常类型 95

    3.4.2 同步异常和异步异常 96

    3.4.3 异常的发生和退出 96

    3.4.4 异常向量表 97

    3.5 ARM64内存管理 99

    3.5.1 页表 100

    3.5.2 页表映射 101

    3.6 实验平台:树莓派 102

    3.6.1 树莓派4介绍 103

    3.6.2 实验3-1:在树莓派上安装

    优麒麟Linux 20.04

    系统 104

    3.6.3 实验3-2:汇编语言

    练习—查找最大数 105

    3.6.4 实验3-3:汇编语言

    练习—通过C语言

    调用汇编函数 105

    3.6.5 实验3-4:汇编语言

    练习—通过汇编语言

    调用C函数 106

    3.6.6 实验3-5:汇编语言

    练习—GCC内联汇编 106

    3.6.7 实验3-6:在树莓派上编写

    一个裸机程序 106

    第4章 内核编译和调试 107

    4.1 内核配置 107

    4.1.1 内核配置工具 107

    4.1.2 .config文件 108

    4.2 实验4-1:通过QEMU虚拟机

    调试ARMv8的Linux内核 110

    4.3 实验4-2:通过Eclipse   QEMU

    单步调试内核 111

    第5章 内核模块 116

    5.1 从一个内核模块开始 116

    5.2 模块参数 120

    5.3 符号共享 122

    5.4 实验 123

    5.4.1 实验5-1:编写一个简单的

    内核模块 123

    5.4.2 实验5-2:向内核模块传递

    参数 124

    5.4.3 实验5-3:在模块之间导出

    符号 124

    第6章 简单的字符设备驱动 125

    6.1 从一个简单的字符设备开始 126

    6.1.1 一个简单的字符设备 126

    6.1.2 实验6-1:写一个简单的

    字符设备驱动 131

    6.2 字符设备驱动详解 131

    6.2.1 字符设备驱动的抽象 131

    6.2.2 设备号的管理 133

    6.2.3 设备节点 133

    6.2.4 字符设备操作方法集 134

    6.3 misc机制 136

    6.3.1 misc机制介绍 136

    6.3.2 实验6-2:使用misc机制

    来创建设备驱动 136

    6.4 一个简单的虚拟设备 138

    6.4.1 实验6-3:为虚拟设备

    编写驱动 138

    6.4.2 实验6-4:使用KFIFO环形

    缓冲区改进设备驱动 141

    6.5 阻塞I O和非阻塞I O 143

    6.5.1 实验6-5:把虚拟设备驱动

    改成非阻塞模式 144

    6.5.2 实验6-6:把虚拟设备驱动

    改成阻塞模式 147

    6.6 I O多路复用 151

    6.6.1 Linux内核的I O多路

    复用 151

    6.6.2 实验6-7:向虚拟设备中

    添加I O多路复用支持 152

    6.6.3 实验6-8:为什么不能唤醒

    读写进程 157

    6.7 添加异步通知 159

    6.7.1 异步通知介绍 159

    6.7.2 实验6-9:向虚拟设备添加

    异步通知 159

    6.7.3 实验6-10:解决驱动的

    宕机难题 163

    6.8 本章小结 164

    第7章 系统调用 166

    7.1 系统调用的概念 166

    7.1.1 系统调用和POSIX标准 167

    7.1.2 系统调用表 167

    7.1.3 用程序访问系统调用 169

    7.1.4 新增系统调用 170

    7.2 实验 170

    7.2.1 实验7-1:在树莓派上新增

    一个系统调用 170

    7.2.2 实验7-2:在Linux主机上

    新增一个系统调用 170

    第8章 进程管理 172

    8.1 进程 172

    8.1.1 进程的由来 172

    8.1.2 进程描述符 174

    8.1.3 进程的生命周期 176

    8.1.4 进程标识 178

    8.1.5 进程间的家族关系 179

    8.1.6 获取当前进程 181

    8.2 进程的创建和终止 183

    8.2.1 写时复制技术 185

    8.2.2 fork()函数 186

    8.2.3 vfork()函数 187

    8.2.4 clone()函数 187

    8.2.5 内核线程 188

    8.2.6 do_fork()函数 189

    8.2.7 终止进程 191

    8.2.8 僵尸进程和托孤进程 191

    8.2.9 进程0和进程1 192

    8.3 进程调度 193

    8.3.1 进程的分类 193

    8.3.2 进程的优先级和权重 193

    8.3.3 调度策略 195

    8.3.4 时间片 198

    8.3.5 经典调度算法 198

    8.3.6 Linux O(n)调度算法 200

    8.3.7 Linux O(1)调度算法 200

    8.3.8 Linux CFS算法 201

    8.3.9 进程切换 204

    8.3.10 与调度相关的数据结构 210

    8.4 多核调度 214

    8.4.1 调度域和调度组 215

    8.4.2 负载的计算 218

    8.4.3 负载均衡算法 221

    8.4.4 Per-CPU变量 222

    8.5 实验 223

    8.5.1 实验8-1:fork和clone系统

    调用 223

    8.5.2 实验8-2:内核线程 224

    8.5.3 实验8-3:后台守护进程 224

    8.5.4 实验8-4:进程权限 224

    8.5.5 实验8-5:设置优先级 224

    8.5.6 实验8-6:Per-CPU变量 225

    第9章 内存管理 226

    9.1 从硬件角度看内存管理 226

    9.1.1 内存管理的“远古

    时代” 226

    9.1.2 地址空间的抽象 228

    9.1.3 分段机制 229

    9.1.4 分页机制 230

    9.2 从软件角度看内存管理 234

    9.2.1 free命令 234

    9.2.2 从应用编程角度看内存

    管理 235

    9.2.3 从内存布局图角度看内存

    管理 236

    9.2.4 从进程角度看内存管理 239

    9.2.5 从内核角度看内存管理 243

    9.3 物理内存管理 244

    9.3.1 物理页面 244

    9.3.2 内存管理区 250

    9.3.3 分配和释放页面 252

    9.3.4 关于内存碎片化 258

    9.3.5 分配小块内存 260

    9.4 虚拟内存管理 268

    9.4.1 进程地址空间 268

    9.4.2 内存描述符mm_struct 269

    9.4.3 VMA管理 270

    9.4.4 VMA属性 273

    9.4.5 VMA查找操作 276

    9.4.6 malloc()函数 277

    9.4.7 mmap() munmap()函数 280

    9.5 缺页异常 284

    9.5.1 do_page_fault()函数 285

    9.5.2 匿名页面缺页异常 286

    9.5.3 文件映射缺页中断 286

    9.5.4 写时复制缺页异常 287

    9.6 内存短缺 287

    9.6.1 页面回收算法 287

    9.6.2 OOM Killer机制 289

    9.7 内存管理日志信息以及调试

    信息 289

    9.7.1 vm_stat计数 289

    9.7.2 meminfo分析 291

    9.7.3 伙伴系统信息 293

    9.7.4 查看内存管理区的信息 294

    9.7.5 查看进程相关的内存

    信息 296

    9.7.6 查看系统内存信息的

    工具 298

    9.8 内存管理实验 300

    9.8.1 实验9-1:查看系统内存

    信息 301

    9.8.2 实验9-2:获取系统的物理

    内存信息 301

    9.8.3 实验9-3:分配内存 301

    9.8.4 实验9-4:slab 302

    9.8.5 实验9-5:VMA 302

    9.8.6 实验9-6:mmap 302

    9.8.7 实验9-7:映射用户

    内存 303

    9.8.8 实验9-8:OOM 303

    第10章 同步管理 304

    10.1 原子操作与内存屏障 305

    10.1.1 原子操作 305

    10.1.2 内存屏障 309

    10.2 自旋锁机制 310

    10.2.1 自旋锁的定义 310

    10.2.2 Qspinlock的实现 311

    10.2.3 自旋锁的变种 312

    10.2.4 自旋锁和raw_spin_lock 313

    10.3 信号量 314

    10.4 互斥锁 315

    10.5 读写锁 317

    10.5.1 读写锁的定义 317

    10.5.2 读写信号量 318

    10.6 RCU 320

    10.7 等待队列 323

    10.7.1 等待队列头 323

    10.7.2 等待队列节点 324

    10.8 实验 324

    10.8.1 实验10-1:自旋锁 324

    10.8.2 实验10-2:互斥锁 325

    10.8.3 实验10-3:RCU锁 325

    第11章 中断管理 326

    11.1 Linux中断管理机制 326

    11.1.1 ARM中断控制器 327

    11.1.2 关于ARM Vexpress V2P

    开发板的例子 327

    11.1.3 关于Virt开发板的例子 329

    11.1.4 硬件中断号和Linux中断号

    的映射 330

    11.1.5 注册中断 331

    11.2 软中断和tasklet 333

    11.2.1 软中断 334

    11.2.2 tasklet 335

    11.2.3 local_bh_disable() local_

    bh_enable() 336

    11.2.4 小结 337

    11.3 工作队列机制 337

    11.3.1 工作队列的类型 338

    11.3.2 使用工作队列 340

    11.3.3 小结 340

    11.4 实验 341

    11.4.1 实验11-1:tasklet 341

    11.4.2 实验11-2:工作队列 341

    11.4.3 实验11-3:定时器和

    内核线程 341

    第12章 调试和性能优化 343

    12.1 printk()输出函数和动态输出 343

    12.1.1 printk()输出函数 343

    12.1.2 动态输出 345

    12.1.3 实验12-1:使用printk()

    输出函数 347

    12.1.4 实验12-2:使用动态

    输出 347

    12.2 proc和debugfs 347

    12.2.1 proc文件系统 347

    12.2.2 sys文件系统 350

    12.2.3 debugfs文件系统 351

    12.2.4 实验12-3:使用procfs 351

    12.2.5 实验12-4:使用sysfs 353

    12.2.6 实验12-5:使用

    debugfs 355

    12.3 ftrace 355

    12.3.1 irqsoff跟踪器 357

    12.3.2 function跟踪器 358

    12.3.3 动态ftrace 359

    12.3.4 事件跟踪 361

    12.3.5 实验12-6:使用ftrace 363

    12.3.6 实验12-7:添加新的

    跟踪点 363

    12.3.7 实验12-8:使用示踪

    标志 366

    12.3.8 实验12-9:使用kernelshark

    分析数据 369

    12.4 分析Oops错误 371

    12.4.1 Oops错误介绍 371

    12.4.2 实验12-10 :分析Oops

    错误 371

    12.5 perf性能分析工具 375

    12.5.1 perf list命令 376

    12.5.2 利用perf采集数据 377

    12.5.3 perf stat 378

    12.5.4 perf top 379

    12.5.5 实验12-11:使用perf工具

    进行性能分析 380

    12.5.6 实验12-12:采集perf数据

    以生成火焰图 381

    12.6 内存检测 381

    12.6.1 实验12-13:使用slub_debug

    检查内存泄漏 382

    12.6.2 实验12-14:使用kmemleak

    检查内存泄漏 387

    12.6.3 实验12-15:使用kasan检查

    内存泄漏 389

    12.6.4 实验12-16:使用valgrind

    检查内存泄漏 393

    12.7 使用kdump解决死机问题 394

    12.7.1 kdump介绍 394

    12.7.2 实验12-17:搭建ARM64的

    kdump实验环境 395

    12.7.3 实验12-18:分析一个简单的

    宕机案例 398

    12.8 性能和测试 401

    12.8.1 性能和测试概述 401

    12.8.2 eBPF介绍 402

    12.8.3 BCC介绍 403

    12.8.4 实验12-19:运行BCC

    工具进行性能测试 404

    第13章 开源社区 405

    13.1 什么是开源社区 405

    13.1.1 开源软件的发展历史 405

    13.1.2 Linux基金会 406

    13.1.3 开源协议 406

    13.1.4 Linux内核社区 408

    13.1.5 国内开源社区 409

    13.2 参与开源社区 409

    13.2.1 参与开源项目的

    好处 409

    13.2.2 如何参与开源项目 410

    13.3 实验13-1:使用cppcheck检查

    代码 411

    13.4 实验13-2:提交第一个Linux

    内核补丁 412

    13.5 实验13-3:管理和提交多个补丁

    组成的补丁集 414

    第14章 文件系统 419

    14.1 文件系统的基本概念 419

    14.1.1 文件 419

    14.1.2 目录 422

    14.2 文件系统的基本概念和

    知识 423

    14.2.1 文件系统的布局 423

    14.2.2 索引数据块 428

    14.2.3 管理空闲块 430

    14.2.4 高速缓存 430

    14.3 虚拟文件系统层 431

    14.4 文件系统的一致性 436

    14.5 一次写磁盘的全过程 439

    14.6 文件系统实验 440

    14.6.1 实验14-1:查看文件

    系统 440

    14.6.2 实验14-2:删除文件

    内容 441

    14.6.3 实验14-3:块设备 441

    14.6.4 实验14-4:动手写一个简单

    的文件系统 441

    第15章 虚拟化与云计算 442

    15.1 虚拟化技术 442

    15.1.1 虚拟化技术的发展

    历史 442

    15.1.2 虚拟机管理程序的

    分类 444

    15.1.3 内存虚拟化 445

    15.1.4 I O虚拟化 445

    15.2 容器技术 446

    15.3 云计算 448

    15.3.1 云编排 450

    15.3.2 OpenStack介绍 451

    15.3.3 Kubernetes介绍 451

    15.4 实验 452

    15.4.1 实验15-1:制作Docker

    镜像并发布 452

    15.4.2 实验15-2:部署Kubernetes

    服务 452

    第16章 综合能力训练:动手写一个

    小OS 453

    16.1 实验准备 454

    16.1.1 开发流程 454

    16.1.2 配置串口线 454

    16.1.3 寄存器地址 457

    16.2 入门动手篇 457

    16.2.1 实验16-1:输出

    “Welcome BenOS!” 457

    16.2.2 使用GDB   QEMU调试

    BenOS 465

    16.2.3 使用J-Link仿真器调试树

    莓派 466

    16.2.4 实验16-2:切换异常

    等级 473

    16.2.5 实验16-3:实现简易的

    printk()函数 473

    16.2.6 实验16-4:中断 473

    16.2.7 实验16-5:创建

    进程 475

    16.3 进阶挑战篇 475

    16.4 高手完善篇 476
查看详情
您可能感兴趣 / 更多