Linux设备驱动开发详解:基于最新的Linux 4.0内核

Linux设备驱动开发详解:基于最新的Linux 4.0内核 pdf epub mobi txt 电子书 下载 2025

宋宝华 著
图书标签:
  • Linux
  • 设备驱动
  • 内核开发
  • Linux 4
  • 0
  • 驱动程序
  • 嵌入式
  • 操作系统
  • C语言
  • 硬件
  • 开发指南
想要找书就要到 新城书站
立刻按 ctrl+D收藏本页
你会得到大惊喜!!
出版社: 机械工业出版社
ISBN:9787111507895
版次:1
商品编码:11752798
品牌:机工出版
包装:平装
丛书名: 电子与嵌入式系统设计丛书
开本:16开
出版时间:2015-08-01
用纸:胶版纸
页数:618

具体描述

编辑推荐

  历时8年,三次重构,内容愈加炉火纯青。

  全部代码更新至全新的Linux 4.0版本。

  全面讲解ARM Linux新版本内核架构,如设备树等。

  不仅仅注重知识和程序的讲解,更注重程序的思想、演变、架构和算法

  对于嵌入式工程师来说,进入更高阶段后,学习Linux设备驱动开发无疑就是职业生涯的一次“重生”。这是因为Linux设备驱动开发不仅仅涉及操作系统的转换,开发方式的转换,更重要的是思维上的转变。对于Linux这样一个复杂系统,如何从复杂的代码中抓住设备驱动开发的关键是任何一个Linux设备驱动开发者入门时需要面对的挑战。除了知识、工具之外,往往还需要思路上的指导。本书不但帮助Linux设备驱动开发的初学者厘清必要的概念,还从具体的实例、设备驱动开发的指导原则循序渐进地引导读者渐入学习佳境。为了让读者能够达到Linux设备驱动开发的至臻境界,作者更是从软件工程的角度抽象出设备驱动开发的一般思想。毫无疑问,本书将成为读者学习Linux设备驱动开发过程中的一座“灯塔”。



内容简介

  本书介绍了Linux设备驱动开发理论、框架与实例,详细说明了自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/O映射以及异步通知、阻塞I/O、非阻塞I/O等Linux设备驱动理论,以及字符设备、块设备、tty设备、I2c设备、LCD设备、音频设备、USB设备、网络设备、PCI设备等Linux设备驱动架构中各个复杂数据结构和函数的关系,并讲解了Linux驱动开发的大量实例,使读者能够独立开发各类Linux设备驱动。


【备注:本书第11页,第六行链接已经失效,替换为:http://pan.baidu.com/s/1cFrl2e 密码:ezs2】

作者简介

  宋宝华,Linux布道者,知名嵌入式系统专家,《Essential Linux Device Drivers》译者。作为较早从事Linux内核与设备驱动研究的专家之一,他在众多国内外知名企业开展Linux技术培训。他也是一位活跃的Linux开发者和深度实践者,为Linux官方内核贡献了大量的Linux源码并承担代码审核工作。至今已向Linux官方内核提交逾数万行代码和几百个补丁。他的《Linux设备驱动开发详解》系列书在嵌入式Linux开发者中有口皆碑,是众多Linux书籍中为数不多的畅销书。

精彩书评

  ★理解软件一定是从某个逻辑起点开始,通过逻辑的延伸和数据的堆叠,首先在框架上获知软件是如何解决目标问题的。然后通过这个框架性的理解来进一步熟知程序中更加小的细节以添加新功能或修复已遇到的问题。我之前想,如果有一本书能在讲解程序之前先详细地介绍此程序的思想、演变、架构和主要算法,然后再遍历评论程序实现的代码,那绝对是秘籍。现在终于有了,谢谢@宋宝华即将带给我们的绝学圣典!

  —— CSR(Cambridge Silicon Radio)平台软件高级经理 刘永生


  ★“宋宝华老师的这本书是国内少有的可与《Linux Device Driver》和《Linux Kernel Development》相媲美的Linux内核类书籍,甚至在所有技术类图书中都是精品之作。相比国内大量技术类图书的呆板教条和抄袭,以及让人读来困倦,不知所云,该书文风生动而不失深刻,知识点全面精炼。书中不但介绍各常见驱动的架构,更深入剖析内核相关的底层实现机制,“授人以鱼”更“授人以渔”,让读者真正领会和学习内核社区大牛们的设计思想和技巧,从而快速提升自己的能力。愿本书的读者通过学习能够真正实现从“码农”到"内核大牛”的华丽转变。”

  —— 中科院上海微系统所 朱军


  ★“Linux内核的书籍不少,可是为什么好书少,与时俱进的好书更加少。这是因为Linux内核每到两三个月就更新一次,不断有新的技术、新的框架加入。试问有哪个作者可以一直坚持写作关于Linux内核新的变化和技术。就连国外的经典之作《Linux Device Driver》、《Understanding Linux Kernel》都早就没有更新的作品了,可是宋宝华老师一直在用他独特的视角和一线Linux内核开发的工作实践不断地给大家带来新好的《Linux设备驱动开发详解》。希望每一位Linux内核的开发者和爱好者都能好好学习宋老师的新作,同时学习他坚持不懈的精神,多为Linux内核社区提供好的技术和作品。”

  —— NVIDIA高级系统软件工程师 伍鹏 (Bryan Wu)

目录

赞誉

推荐序一

推荐序二

前言

第1章 Linux设备驱动概述及开发环境构建 1

1.1 设备驱动的作用 1

1.2 无操作系统时的设备驱动 2

1.3 有操作系统时的设备驱动 4

1.4 Linux设备驱动 5

1.4.1 设备的分类及特点 5

1.4.2 Linux设备驱动与整个软硬件系统的关系 6

1.4.3 Linux设备驱动的重点、难点 7

1.5 Linux设备驱动的开发环境构建 8

1.5.1 PC上的Linux环境 8

1.5.2 QEMU实验平台 11

1.5.3 源代码阅读和编辑 13

1.6 设备驱动Hello World:LED驱动 15

1.6.1 无操作系统时的LED驱动 15

1.6.2 Linux下的LED驱动 15

第2章 驱动设计的硬件基础 20

2.1 处理器 20

2.1.1 通用处理器 20

2.1.2 数字信号处理器 22

2.2 存储器 24

2.3 接口与总线 28

2.3.1 串口 28

2.3.2 I2C 29

2.3.3 SPI 30

2.3.4 USB 31

2.3.5 以太网接口 33

2.3.6 PCI和PCI-E 34

2.3.7 SD和SDIO 36

2.4 CPLD和FPGA 37

2.5 原理图分析 40

2.6 硬件时序分析 42

2.6.1 时序分析的概念 42

2.6.2 典型的硬件时序 43

2.7 芯片数据手册阅读方法 44

2.8 仪器仪表使用 47

2.8.1 万用表 47

2.8.2 示波器 47

2.8.3 逻辑分析仪 49

2.9 总结 51

第3章 Linux内核及内核编程 52

3.1 Linux内核的发展与演变 52

3.2 Linux 2.6后的内核特点 56

3.3 Linux内核的组成 59

3.3.1 Linux内核源代码的目录结构 59

3.3.2 Linux内核的组成部分 60

3.3.3 Linux内核空间与用户空间 64

3.4 Linux内核的编译及加载 64

3.4.1 Linux内核的编译 64

3.4.2 Kconfig和Makefile 66

3.4.3 Linux内核的引导 74

3.5 Linux下的C编程特点 75

3.5.1 Linux编码风格 75

3.5.2 GNU C与ANSI C 78

3.5.3 do { } while(0) 语句 83

3.5.4 goto语句 85

3.6 工具链 85

3.7 实验室建设 88

3.8 串口工具 89

3.9 总结 91

第4章 Linux内核模块 92

4.1 Linux内核模块简介 92

4.2 Linux内核模块程序结构 95

4.3 模块加载函数 95

4.4 模块卸载函数 97

4.5 模块参数 97

4.6 导出符号 99

4.7 模块声明与描述 100

4.8 模块的使用计数 100

4.9 模块的编译 101

4.10 使用模块“绕开”GPL 102

4.11 总结 103

第5章 Linux文件系统与设备文件 104

5.1 Linux文件操作 104

5.1.1 文件操作系统调用 104

5.1.2 C库文件操作 108

5.2 Linux文件系统 109

5.2.1 Linux文件系统目录结构 109

5.2.2 Linux文件系统与设备驱动 110

5.3 devfs 114

5.4 udev用户空间设备管理 116

5.4.1 udev与devfs的区别 116

5.4.2 sysfs文件系统与Linux设备模型 119

5.4.3 udev的组成 128

5.4.4 udev规则文件 129

5.5 总结 133

第6章 字符设备驱动 134

6.1 Linux字符设备驱动结构 134

6.1.1 cdev结构体 134

6.1.2 分配和释放设备号 136

6.1.3 f?ile_operations结构体 136

6.1.4 Linux字符设备驱动的组成 138

6.2 globalmem虚拟设备实例描述 142

6.3 globalmem设备驱动 142

6.3.1 头文件、宏及设备结构体 142

6.3.2 加载与卸载设备驱动 143

6.3.3 读写函数 144

6.3.4 seek函数 146

6.3.5 ioctl函数 146

6.3.6 使用文件私有数据 148

6.4 globalmem驱动在用户空间中的验证 156

6.5 总结 157

第7章 Linux设备驱动中的并发控制 158

7.1 并发与竞态 158

7.2 编译乱序和执行乱序 160

7.3 中断屏蔽 165

7.4 原子操作 166

7.4.1 整型原子操作 167

7.4.2 位原子操作 168

7.5 自旋锁 169

7.5.1 自旋锁的使用 169

7.5.2 读写自旋锁 173

7.5.3 顺序锁 174

7.5.4 读-复制-更新 176

7.6 信号量 181

7.7 互斥体 183

7.8 完成量 184

7.9 增加并发控制后的globalmem的设备驱动 185

7.10 总结 188

第8章 Linux设备驱动中的阻塞与非阻塞I/O 189

8.1 阻塞与非阻塞I/O 189

8.1.1 等待队列 191

8.1.2 支持阻塞操作的globalf?ifo设备驱动 194

8.1.3 在用户空间验证globalf?ifo的读写 198

8.2 轮询操作 198

8.2.1 轮询的概念与作用 198

8.2.2 应用程序中的轮询编程 199

8.2.3 设备驱动中的轮询编程 201

8.3 支持轮询操作的globalf?ifo驱动 202

8.3.1 在globalf?ifo驱动中增加轮询操作 202

8.3.2 在用户空间中验证globalf?ifo设备的轮询 203

8.4 总结 205

第9章 Linux设备驱动中的异步通知与异步I/O 206

9.1 异步通知的概念与作用 206

9.2 Linux异步通知编程 207

9.2.1 Linux信号 207

9.2.2 信号的接收 208

9.2.3 信号的释放 210

9.3 支持异步通知的globalf?ifo驱动 212

9.3.1 在globalf?ifo驱动中增加异步通知 212

9.3.2 在用户空间中验证globalf?ifo的异步通知 214

9.4 Linux异步I/O 215

9.4.1 AIO概念与GNU C库AIO 215

9.4.2 Linux内核AIO与libaio 219

9.4.3 AIO与设备驱动 222

9.5 总结 223

第10章 中断与时钟 224

10.1 中断与定时器 224

10.2 Linux中断处理程序架构 227

10.3 Linux中断编程 228

10.3.1 申请和释放中断 228

10.3.2 使能和屏蔽中断 230

10.3.3 底半部机制 230

10.3.4 实例:GPIO按键的中断 235

10.4 中断共享 237

10.5 内核定时器 238

10.5.1 内核定时器编程 238

10.5.2 内核中延迟的工作delayed_work 242

10.5.3 实例:秒字符设备 243

10.6 内核延时 247

10.6.1 短延迟 247

10.6.2 长延迟 248

10.6.3 睡着延迟 248

10.7 总结 250

第11章 内存与I/O访问 251

11.1 CPU与内存、I/O 251

11.1.1 内存空间与I/O空间 251

11.1.2 内存管理单元 252

11.2 Linux内存管理 256

11.3 内存存取 261

11.3.1 用户空间内存动态申请 261

11.3.2 内核空间内存动态申请 262

11.4 设备I/O端口和I/O内存的访问 267

11.4.1 Linux I/O端口和I/O内存访问接口 267

11.4.2 申请与释放设备的I/O端口和I/O内存 268

11.4.3 设备I/O端口和I/O内存访问流程 269

11.4.4 将设备地址映射到用户空间 270

11.5 I/O内存静态映射 276

11.6 DMA 277

11.6.1 DMA与Cache一致性 278

11.6.2 Linux下的DMA编程 279

11.7 总结 285

第12章 Linux设备驱动的软件架构思想 286

12.1 Linux驱动的软件架构 286

12.2 platform设备驱动 290

12.2.1 platform总线、设备与驱动 290

12.2.2 将globalf?ifo作为platform设备 293

12.2.3 platform设备资源和数据 295

12.3 设备驱动的分层思想 299

12.3.1 设备驱动核心层和例化 299

12.3.2 输入设备驱动 301

12.3.3 RTC设备驱动 306

12.3.4 Framebuffer设备驱动 309

12.3.5 终端设备驱动 311

12.3.6 misc设备驱动 316

12.3.7 驱动核心层 321

12.4 主机驱动与外设驱动分离的设计思想 321

12.4.1 主机驱动与外设驱动分离 321

12.4.2 Linux SPI主机和设备驱动 322

12.5 总结 330

第13章 Linux块设备驱动 331

13.1 块设备的I/O操作特点 331

13.2 Linux块设备驱动结构 332

13.2.1 block_device_operations结构体 332

13.2.2 gendisk结构体 334

13.2.3 bio、request和request_queue 335

13.2.4 I/O调度器 339

13.3 Linux块设备驱动的初始化 340

13.4 块设备的打开与释放 342

13.5 块设备驱动的ioctl函数 342

13.6 块设备驱动的I/O请求处理 343

13.6.1 使用请求队列 343

13.6.2 不使用请求队列 347

13.7 实例:vmem_disk驱动 349

13.7.1 vmem_disk的硬件原理 349

13.7.2 vmem_disk驱动模块的加载与卸载 349

13.7.3 vmem_disk设备驱动的block_device_operations 351

13.7.4 vmem_disk的I/O请求处理 352

13.8 Linux MMC子系统 354

13.9 总结 357

第14章 Linux网络设备驱动 358

14.1 Linux网络设备驱动的结构 358

14.1.1 网络协议接口层 359

14.1.2 网络设备接口层 363

14.1.3 设备驱动功能层 367

14.2 网络设备驱动的注册与注销 367

14.3 网络设备的初始化 369

14.4 网络设备的打开与释放 370

14.5 数据发送流程 371

14.6 数据接收流程 372

14.7 网络连接状态 375

14.8 参数设置和统计数据 377

14.9 DM9000网卡设备驱动实例 380

14.9.1 DM9000网卡硬件描述 380

14.9.2 DM9000网卡驱动设计分析 380

14.10 总结 386

第15章 Linux I2C核心、总线与设备驱动 387

15.1 Linux I2C体系结构 387

15.2 Linux I2C核心 394

15.3 Linux I2C适配器驱动 396

15.3.1 I2C适配器驱动的注册与注销 396

15.3.2 I2C总线的通信方法 397

15.4 Linux I2C设备驱动 399

15.4.1 Linux I2C设备驱动的模块加载与卸载 400

15.4.2 Linux I2C设备驱动的数据传输 400

15.4.3 Linux的i2c-dev.c文件分析 400

15.5 Tegra I2C总线驱动实例 405

15.6 AT24xx EEPROM的I2C设备驱动实例 410

15.7 总结 413

第16章 USB主机、设备与Gadget驱动 414

16.1 Linux USB驱动层次 414

16.1.1 主机侧与设备侧USB驱动 414

16.1.2 设备、配置、接口、端点 415

16.2 USB主机控制器驱动 420

16.2.1 USB主机控制器驱动的整体结构 420

16.2.2 实例:Chipidea USB主机驱动 425

16.3 USB设备驱动 425

16.3.1 USB设备驱动的整体结构 425

16.3.2 USB请求块 430

16.3.3 探测和断开函数 435

16.3.4 USB骨架程序 436

16.3.5 实例:USB键盘驱动 443

16.4 USB UDC与Gadget驱动 446

16.4.1 UDC和Gadget驱动的关键数据结构与API 446

16.4.2 实例:Chipidea USB UDC驱动 451

16.4.3 实例:Loopback Function驱动 453

16.5 USB OTG驱动 456

16.6 总结 458

第17章 I2C、SPI、USB驱动架构类比 459

17.1 I2C、SPI、USB驱动架构 459

17.2 I2C主机和外设眼里的Linux世界 460

第18章 ARM Linux设备树 461

18.1 ARM设备树起源 461

18.2 设备树的组成和结构 462

18.2.1 DTS、DTC和DTB等 462

18.2.2 根节点兼容性 468

18.2.3 设备节点兼容性 470

18.2.4 设备节点及label的命名 475

18.2.5 地址编码 477

18.2.6 中断连接 479

18.2.7 GPIO、时钟、pinmux连接 480

18.3 由设备树引发的BSP和驱动变更 484

18.4 常用的OF API 490

18.5 总结 493

第19章 Linux电源管理的系统架构和驱动 494

19.1 Linux电源管理的全局架构 494

19.2 CPUFreq驱动 495

19.2.1 SoC的CPUFreq驱动实现 495

19.2.2 CPUFreq的策略 501

19.2.3 CPUFreq的性能测试和调优 501

19.2.4 CPUFreq通知 502

19.3 CPUIdle驱动 504

19.4 PowerTop 508

19.5 Regulator驱动 508

19.6 OPP 511

19.7 PM QoS 515

19.8 CPU热插拔 518

19.9 挂起到RAM 522

19.10 运行时的PM 528

19.11 总结 534

第20章 Linux芯片级移植及底层驱动 535

20.1 ARM Linux底层驱动的组成和现状 535

20.2 内核节拍驱动 536

20.3 中断控制器驱动 541

20.4 SMP多核启动以及CPU热插拔驱动 549

20.5 DEBUG_LL和EARLY_PRINTK的设置 556

20.6 GPIO驱动 557

20.7 pinctrl驱动 560

20.8 时钟驱动 572

20.9 dmaengine驱动 578

20.10 总结 580

第21章 Linux设备驱动的调试 581

21.1 GDB调试器的用法 581

21.1.1 GDB的基本用法 581

21.1.2 DDD图形界面调试工具 591

21.2 Linux内核调试 594

21.3 内核打印信息——printk() 596

21.4 DEBUG_LL和EARLY_PRINTK 599

21.5 使用“/proc” 600

21.6 Oops 606

21.7 BUG_ON()和WARN_ON() 608

21.8 strace 609

21.9 KGDB 610

21.10 使用仿真器调试内核 612

21.11 应用程序调试 613

21.12 Linux性能监控与调优工具 616

21.13 总结 618

前言/序言

  Linux从未停歇前进的脚步。Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,现在仍然在没日没夜地合并补丁、升级内核。做技术的人,从来没有终南捷径,拼得就是坐冷板凳的傻劲。

  这是一个连阅读都被碎片化的时代,在这样一个时代,人们趋向于激进、浮躁,内心的不安宁使我们极难静下心来研究什么。我见过许多Linux工程师,他们的简历上写着“精通”Linux内核,有多年的工作经验,而他们的“精通”却只是把某个寄存器从0改成1,从1改成0的不断重复;我也见过许多Linux工程师,他们终日埋头苦干,敲打着自己的机器和电路板,却从未冷静下来思考,并不断重构和升华自己的知识体系。

  这是要把“牢底”坐穿的程序员,这样“忙忙碌碌”的程序员,从来都不算是好程序员。

  对于优秀的程序员,其最优秀的品质是能够心平气和地学习与思考问题,透析代码背后的架构、原理和设计思想。没有思想的代码是垃圾代码,没有思想的程序员,只是在完成低水平重复建设的体力活。很多程序员从不过问自己写的代码最后在机器里面是怎么跑的,很多事情莫名其妙地发生了,很多bug莫名其妙地消失了……他们永远都在得过且过。

  由此,衍生出了本书的第一个出发点,那就是带给读者更多关于Linux开发思想的讲解,帮助读者奠定根基。本书呈现给读者的更多的是一种思考方法,而不是知识点的简单罗列。

  本书除对基础理论部分进行了详细的讲解外,还加强了对驱动编程所涉及的Linux内核最底层机理的讲解,内容包括中断、定时器、进程生命周期、uevent、并发、编译乱序、执行乱序、等待队列、I/O模型、内存管理等。这些知识点非常重要,是真正证明程序员理解了Linux的部分内容,程序员只有打好根基,才能游刃有余。

  本书没有大量描述各种具体驱动类型的章节,如Sound、PCI、MTD、tty等,而将更多的焦点转移到了驱动编程背后的内核原理,并试图从Linux内核的上百个驱动子系统中寻找出内部规律,以培养读者举一反三的能力。

  Linux内核有上百个驱动子系统,这一点从内核的drivers子目录中就可以看出来:

  好吧,傻子才会一个目录一个目录地去看,一个目录一个目录地从头学起。我们势必要寻找各种驱动子系统的共性,摸索规律。在本书中,我们将更多地看到各驱动子系统的类比,以及驱动子系统的层次化设计。

  技术工作从来都不能一劳永逸。世界变化得太快,当前技术革新的速度数倍于我们父辈、祖辈、祖祖辈经历过的任何时代。证明你是“真球迷”还是“伪球迷”的时候到了,这个时代是伪程序员的地狱,也是真程序员的天堂。

  从浩如烟海的知识体系、不断更新的软件版本中终生学习,不断攻克一个个挑战,获取新养分,寻找新灵感,这实在是黑暗的码农生涯中不断闪现的璀璨光芒。

  Linux的内核版本不断更新,出现了Linux 3.0、Linux 3.1、Linux 3.2、…、Linux 3.19、Linux 4.0、Linux 4.1,变化的是软件的架构,不变的是Linus的热情。

  这无疑也是本书的第二个出发点,更新Linux驱动编程的知识体系以迎合最新的时代需求。因此,本书有大量关于设备树、ARM Linux移植、Linux电源管理、GPIO、时钟、定时器、pinmux、DMA等内容。我们的操作平台也转移到了QEMU模拟的4核Cortex-A9电路板上,书中的实例基本都转移到了市面流行的新芯片上。

  最近两三年,老是听许多程序员抱怨,市面上缺乏讲解新内核的资料、缺乏从头到尾讲解设备树的资料,但是我想说,这实在不是什么难点。难点仍然是本书基于第一个出发点要解决的问题,如果有好的基础,以优秀程序员极强的学习能力,应该很快就可以掌握这些新知识。机制没有变,变化的只是策略。

  因此学习能力也是优秀程序员的又一个重要品质。没有人生下来就是天才,良好的学习能力也是通过后天的不断学习培养的。可以说,学得越多的人,学新东西的速度一定越快,学习能力也变得越强。因为,知识的共通性实在太多。

  读者在阅读本书时,不应该企图把它当成一本工具书和查API的书,而是应该把它当作一本梳理理论体系、开发思想、软件架构的书。唯如此,我们才能适应未来新的变化。

  时代的滚滚车轮推动着Linux内核的版本不断向前,也推动着每个人的人生。红尘滚滚,我不去想是否能够成功,既然选择了远方,便只顾风雨兼程。

  最后,本书能得以出版,要感谢带领我向前的人生导师和我的众多小伙伴,他们或者在我人生的关键时刻改变了我,或者给我黑暗的程序生涯带来了无尽的快乐和动力。我的小伙伴,他们力挺我、鼓励我,也辱骂我、奚落我,这些都是真挚的友情。

  谨以此书,致以对杨平先生、何昭然、方毅伟、李华毅、宋志武、杜向龙、叶祥振、刘昊、王榕、何晔、王立赛、曾过、刘永生、段丙华、章君义、王文琪、卢鹏、刘涛、徐西宁、吴赫、任桥伟、秦龙廷、胡良兵、张家旺、王雷、Bryan Wu、Eric Miao、Cliff Cai、Qipan Li、Guoying Zhang、陈健松、Haoyu Zhong、刘洪涛、季久峰、邴杰、孙志忠、吴国举、Bob Liu、赵小吾、EJ Zhao、贺亚锋、刘仕杰、Hao Yin等老师和小伙伴的深深感激;谨以此书,致以对我的父母大人、老婆大人、兄长和姐姐、伟大丈母娘的深深感激,本书的写作时间超过一年,其过程是一种巨大的肉体和精神折磨,没有他们的默默支持和不断鞭策,本书是不可能完成的;谨以此书,对为本书做出巨大贡献的编辑、策划老师,尤其是张国强老师致以深深的感激!

  由于篇幅的关系,我没有办法一一列举我要感激的所有人,但是,这些年从你们那里获得的,远远大于我付出的,所以,在内心深处,唯有怀着对你们的深深感恩,不断前行。岁月如歌,吾歌狂行。

  全书结构本书首先介绍Linux设备驱动的基础。第1章简要地介绍了设备驱动,并从无操作系统的设备驱动引出了Linux操作系统下的设备驱动,介绍了本书所基于的开发环境。第2章系统地讲解了Linux驱动工程师应该掌握的硬件知识,为工程师打下Linux驱动编程的硬件基础,详细介绍了各种类型的CPU、存储器和常见的外设,并阐述了硬件时序分析方法和数据手册阅读方法。第3章将Linux设备驱动放在Linux 2.6内核背景中进行讲解,说明Linux内核的编程方法。由于驱动编程也在内核编程的范畴,因此,这一章实质是为编写Linux设备驱动打下软件基础。

  其次,讲解Linux设备驱动编程的基础理论、字符设备驱动及设备驱动设计中涉及的并发控制、同步等问题。第4、5章分别讲解Linux内核模块和Linux设备文件系统;第6~9章以虚拟设备globalmem和globalfifo为主线,逐步给其添加高级控制功能;第10、11章分别阐述Linux驱动编程中所涉及的中断和定时器、内核和I/O操作处理方法。

  接着,剖析复杂设备驱动的体系结构以及块设备、网络设备驱动。该篇讲解了设备与驱动的分离、主机控制器驱动与外设驱动的分离,并以大量实例(如input、tty、LCD、platform、I2C、SPI、USB等)来佐证。其中第12章和第17章遥相呼应,力图全面地展示驱动的架构。Linux有100多个驱动子系统,逐个讲解和学习都是不现实的,授人以鱼不如授人以渔,因此我们将更多的焦点放在了架构讲解方面,以便读者可以举一反三。

  本书最后4章分析了Linux的设备树、Linux移植到新的SoC上的具体工作以及Linux内核和驱动的一些调试方法。这些内容,对于理解如何从头开始搭建一个Linux,以及整个Linux板级支持包上上下下的关系尤为重要。

  另外,本书的主要代码都引用自Linux源代码,为保留原汁原味,均延用了代码的英文注释,而其他非引用的代码则使用了中文注释或无注释,特此说明。

  本书配套的相关素材和代码,读者均可从与本书相关的微信公众号中获得,相关公众号是:Linuxer,欢迎扫描二维码。

  宋宝华2015年4月于上海浦东



《深入理解Linux设备驱动:从底层机制到实践应用》 一、 书籍定位与核心价值 《深入理解Linux设备驱动:从底层机制到实践应用》是一本旨在为广大Linux开发者、嵌入式系统工程师以及对操作系统底层原理感兴趣的读者提供全面、深入的设备驱动开发指导的著作。本书并非简单罗列API,而是着重于剖析Linux内核中设备驱动的运行机制、核心概念以及设计模式,帮助读者构建扎实的理论基础,并能灵活运用到实际开发场景中。 本书的核心价值在于: 系统性: 从宏观的Linux内核架构入手,逐步深入到设备驱动的各个层面,确保读者能够构建完整的知识体系,而非碎片化的学习。 深刻性: 不仅讲解“如何做”,更强调“为什么这样做”,深入探讨Linux内核在设备管理、资源分配、并发控制等方面的设计哲学,让读者理解驱动设计的内在逻辑。 实践性: 理论与实践紧密结合,通过丰富的代码示例、详细的调试技巧和实际项目案例,引导读者将理论知识转化为解决实际问题的能力。 前瞻性: 关注Linux内核的最新发展趋势,在讲解核心概念的同时,也会适时引入一些新的机制和特性,为读者未来的学习和开发打下基础。 二、 内容概览与章节设计 本书共分为五个主要部分,层层递进,环环相扣: 第一部分:Linux内核与设备驱动基础 本部分旨在为读者打下坚实的Linux内核理论基础,使其能够理解设备驱动在整个内核体系中的位置和作用。 第一章:Linux内核概览与模块化设计 Linux内核的宏观结构:用户空间与内核空间、核心层、驱动层、文件系统层等。 进程管理与调度机制:了解进程的生命周期、调度策略对驱动开发的影响。 内存管理:虚拟内存、物理内存、页面回收、伙伴系统、slab分配器等,理解驱动中内存的申请、释放与管理。 中断机制:中断向量表、中断处理流程、中断上下文与进程上下文的区别,以及如何高效处理中断。 内核对象与同步机制:锁(自旋锁、互斥锁)、信号量、原子操作、事件等,讲解如何在多任务环境下保证数据安全。 Linux内核模块(LKM)机制:模块的加载、卸载、符号导出与导入,掌握开发动态可加载驱动的基本方法。 第二章:设备模型与总线、设备、驱动 Linux设备模型的核心概念:总线(Bus)、设备(Device)、驱动(Driver)之间的关系。 Kobject、Kset、Ktype:理解内核对象管理机制,以及它们在设备模型中的作用。 Bus类型与枚举:PCI、USB、I2C、SPI等常见总线的特性与驱动模型。 Device的注册与管理:如何向内核注册一个设备,分配资源,并与其驱动进行匹配。 Driver的注册与匹配:驱动如何描述自身支持的设备,以及内核如何进行自动匹配。 sysfs文件系统:理解sysfs如何暴露设备模型信息,以及用户空间如何与设备进行交互。 第二部分:核心设备驱动开发技术 本部分将深入讲解Linux设备驱动开发中最常用、最核心的技术。 第三章:字符设备驱动开发 字符设备驱动的基本框架:file_operations结构体的详解,包括open, read, write, ioctl, release等操作。 设备号的分配与管理:静态分配、动态分配,以及register_chrdev()、unregister_chrdev()的使用。 文件操作中的同步与并发:如何处理多个进程同时访问设备文件,使用锁保证数据一致性。 ioctl命令的设计与实现:如何设计通用的ioctl接口,以及传递用户空间数据。 阻塞与非阻塞I/O:理解read/write操作的阻塞性,以及如何实现非阻塞访问。 poll/select/epoll机制:实现事件通知,让用户空间能够及时感知设备状态变化。 常用字符设备驱动实例:如串口驱动、按键驱动、LED驱动等。 第四章:块设备驱动开发 块设备驱动的特点与需求:与字符设备的区别,数据以块为单位进行读写。 块设备I/O调度器:了解request_queue、blkdev_ioctl等关键结构和函数。 bio结构体与request结构体:理解块设备I/O请求的表示和处理流程。 块设备驱动的注册与注销:register_blkdev()、unregister_blkdev()的使用。 处理I/O请求:如何接收、处理、完成块设备I/O请求。 性能优化:如何通过I/O调度器、合并请求等手段提升块设备性能。 块设备驱动实例:如模拟磁盘驱动、SD卡驱动等。 第五章:网络设备驱动开发 网络协议栈与驱动接口:Ethernet、WiFi等网络设备在Linux网络协议栈中的位置。 net_device结构体:详解其各个字段以及常用的操作。 数据包的收发流程:理解sk_buff结构体,以及数据包在内核中的传递。 中断处理与DMA:高效处理网络数据包,利用DMA加速数据传输。 多队列网卡(Multi-Queue NIC)与RSS:提升高并发网络场景下的性能。 常用的网络驱动开发工具与调试方法。 网络设备驱动实例:如一个简单的网卡驱动示例。 第三部分:高级设备驱动技术与机制 本部分将深入探讨Linux设备驱动开发中的一些高级话题,帮助读者应对更复杂的场景。 第六章:平台设备与设备树 平台设备(Platform Devices):理解这种不与特定总线绑定的设备模型,以及如何使用。 设备树(Device Tree)基础:DTB、DTS、DTC的概念,以及设备树在ARM等体系结构中的重要性。 设备树节点与属性:学习如何描述硬件资源、中断、GPIO等。 设备树在驱动中的解析:使用`of_match_device`、`of_property_read_xxx`等API。 无设备树(No Device Tree)与设备树并存的场景。 第七章:内存映射与DMA 虚拟地址与物理地址:理解两者之间的映射关系。 用户空间与内核空间内存映射:mmap()、remap_pfn_range()等函数的使用。 Direct Memory Access (DMA):DMA的原理、优势以及在设备驱动中的应用。 DMA API:`dma_alloc_coherent()`、`dma_map_single()`、`dma_unmap_single()`等函数的使用。 IOMMU(Input/Output Memory Management Unit):理解其在DMA安全与管理中的作用。 第八章:中断与延迟控制 中断服务例程(ISR)与底半部(Bottom Half):理解中断处理的两个阶段。 软中断(Softirqs)与任务队列(Tasklets):实现中断处理的延迟执行。 工作队列(Workqueues):更灵活的延迟执行机制,可以运行在进程上下文中。 中断上下文与进程上下文的边界:强调在不同上下文中执行代码的注意事项。 忙等(Busy Waiting)与定时器(Timers):避免不必要的CPU占用,实现延时操作。 第九章:Linux驱动调试与性能优化 内核日志(printk):掌握日志的级别、输出方式以及查看方法。 动态调试技术:ftrace、kprobes、perf等工具的使用。 内核调试器(GDB+QEMU):搭建交叉编译与调试环境。 内存泄漏检测:kmemleak、valgrind等工具。 性能瓶颈分析:CPU占用、I/O延迟、内存使用等。 驱动性能优化策略:中断处理优化、DMA利用、算法改进等。 第四部分:特定领域设备驱动 本部分将聚焦于一些特定应用场景下的设备驱动开发,展示Linux驱动设计的灵活性和强大能力。 第十章:USB设备驱动开发 USB协议基础:USB总线拓扑、设备描述符、配置描述符、接口描述符、端点描述符。 Linux USB驱动模型:USB类、USB设备、USB接口、USB端点。 USB核心API:`usb_register_driver()`、`usb_deregister()`、`usb_get_dev()`等。 URB(USB Request Block):理解URB的作用以及如何构建和提交。 USB设备驱动开发流程:枚举、绑定、数据传输。 USB HID、Mass Storage、CDC等常见设备类驱动的开发思路。 第十一章:I2C/SPI设备驱动开发 I2C/SPI总线协议:通信方式、时序、地址等。 Linux I2C/SPI子系统:`i2c_driver`、`spi_driver`等结构体。 I2C/SPI设备树描述:如何使用设备树描述I2C/SPI设备及其连接关系。 I2C/SPI客户端驱动开发:`i2c_client`、`spi_device`等。 读写I2C/SPI设备:`i2c_transfer()`、`spi_sync()`等函数。 传感器、显示屏等I2C/SPI设备驱动实例。 第十二章:GPIO驱动开发 GPIO(General Purpose Input/Output)基础:输入、输出、上拉/下拉。 Linux GPIO子系统:`gpio_request()`、`gpio_set_value()`、`gpio_get_value()`等API。 GPIO在设备树中的配置与使用。 GPIO复用与中断:如何将GPIO配置为中断源。 LED、按键、蜂鸣器等GPIO控制设备驱动开发。 第五部分:驱动工程化与实践 本部分将回归工程实践,讨论驱动开发的整个生命周期以及如何构建高质量的驱动。 第十三章:驱动的Licensing与社区贡献 Linux内核的Licensing机制:GPL协议及其对驱动开发的影响。 驱动代码的规范与风格。 如何向Linux内核提交代码:patch的生成、发送、review流程。 参与Linux社区的意义与价值。 第十四章:嵌入式Linux驱动开发实践 交叉编译与目标板调试:针对嵌入式平台的开发环境搭建。 Bootloader与Kernel的交互:驱动如何被加载和初始化。 Root Filesystem与驱动集成。 嵌入式系统中的常见驱动问题与解决方案。 硬件抽象层(HAL)在驱动开发中的作用。 第十五章:总结与展望 Linux设备驱动开发中的关键挑战与机遇。 对未来Linux内核发展趋势的展望,如eBPF在驱动领域的应用潜力。 持续学习与提升的建议。 三、 目标读者 Linux系统开发者: 希望深入理解Linux内核,并能独立开发和维护设备驱动的开发者。 嵌入式系统工程师: 需要为嵌入式设备开发驱动,特别是基于Linux的嵌入式系统。 操作系统原理爱好者: 对操作系统底层工作原理有浓厚兴趣,希望通过设备驱动开发来加深理解的读者。 有C语言基础的开发者: 熟悉C语言编程,并希望将其应用于内核开发领域。 四、 阅读建议 本书内容连贯,建议按照章节顺序阅读,以便逐步构建起完整的知识体系。在阅读过程中,积极动手实践书中的代码示例,并通过虚拟机或真实硬件进行测试,加深理解。遇到疑难问题时,善用本书提供的调试技巧,并参考Linux内核文档和社区资源。 《深入理解Linux设备驱动:从底层机制到实践应用》 将是您掌握Linux设备驱动开发、征服底层技术、提升工程能力的得力助手。

用户评价

评分

这本书的排版和逻辑清晰度给我留下了深刻的印象。在阅读过程中,我发现作者非常注重细节,无论是对某个函数的参数解释,还是对某个概念的细致剖析,都力求做到准确无误。更重要的是,作者能够将复杂的内核源码剥离出来,用易于理解的语言和生动的比喻进行阐释,使得原本晦涩难懂的驱动开发知识变得触手可及。我特别欣赏书中通过代码示例来解释理论的方式,这比单纯的文字描述要高效得多。书中提供的代码片段不仅可以运行,而且经过了作者的精心设计,能够清晰地展示出关键的驱动开发流程和技术要点。我尤其看重书中关于编写可移植性好、健壮性强的驱动的指导。在实际开发中,驱动的稳定性和可维护性往往比实现基本功能更为重要,而这本书在这方面提供了很多实用的建议和技巧。我迫不及待地想要深入学习书中关于异步 I/O、内存映射以及各种字符设备、块设备和网络设备驱动的实现细节,相信这会极大地提升我的驱动开发能力。

评分

我一直觉得,学习技术最好的方式就是“动手实践”,而一本优秀的参考书,应该能够激发读者的实践热情,并提供坚实的基础。这本书在这方面做得非常出色。它不仅仅是理论的讲解,更像是一位经验丰富的导师,在引导你一步步构建自己的设备驱动。我注意到书中包含了大量的图示和流程图,这对于理解内核中复杂的对象关系和数据流动非常有帮助。例如,关于内核如何查找并匹配设备和驱动的图解,就清晰地展现了整个过程,让我茅塞顿开。此外,书中提到的许多内核提供的调试工具和技巧,也为我今后的调试工作指明了方向。我一直对如何有效地调试驱动程序感到头疼,希望这本书能提供一些行之有效的解决方案。书中对不同类型硬件驱动的分类介绍,也帮助我系统地梳理了设备驱动开发的全貌,让我能够更有针对性地去学习和掌握。我对书中关于编写内核模块的章节尤其感兴趣,这让我能够独立地开发和测试我的驱动代码,而无需每次都重新编译整个内核。

评分

我是一个对底层技术充满好奇心的开发者,尤其是 Linux 内核,那是一个充满奥秘的世界。设备驱动开发更是连接硬件和软件的关键桥梁,其重要性不言而喻。当我看到这本书的标题,尤其是“基于最新的Linux 4.0内核”这个字样时,我立刻被吸引住了。这意味着这本书的内容是与时俱进的,能够帮助我掌握当前最前沿的驱动开发技术。我特别关注书中对于设备树(Device Tree)的讲解,这在现代 Linux 系统中是配置硬件不可或缺的一部分。如何正确地编写和解析设备树,并将其与驱动程序结合,是我一直想要深入了解的。这本书的出现,无疑为我提供了一个绝佳的学习机会。书中对各种硬件资源的抽象和管理,以及驱动程序如何访问和使用这些资源,都将是我学习的重点。我希望通过这本书,能够更深入地理解 Linux 内核的运作机制,并能独立完成各种复杂的设备驱动程序开发任务。这本书不仅是一本技术手册,更是一扇通往 Linux 内核深层世界的窗口。

评分

作为一名从 Linux 2.6 内核时代过来的开发者,我深知内核更新带来的变化。许多曾经熟练使用的 API 和概念,在新的内核版本中可能已经被弃用或重构。寻找一本能够跟上最新内核步伐的书籍,对我来说意义非凡。这本书能深入到 Linux 4.0 内核的方方面面,并且能将其与设备驱动开发紧密结合,这本身就是一个巨大的亮点。我尤其对书中关于内核同步机制(如自旋锁、互斥锁、信号量)在驱动开发中的应用讲解抱有很高的期望,因为并发和同步问题是驱动开发中最容易出现 bug 的地方。书中对这些概念的深入剖析,以及如何规避常见的同步陷阱,相信会对我今后的开发工作大有裨益。我非常期待书中关于驱动模型中各种回调函数的具体实现和作用的讲解,这对于理解驱动程序的生命周期以及如何与内核进行交互至关重要。这本书的深度和广度,完全超出了我的预期,我坚信它将成为我未来设备驱动开发道路上的重要参考。

评分

这本书的出现,无疑是我在 Linux 内核开发领域摸索许久后的一道曙光。作为一名长期在嵌入式领域奋斗的开发者,我深知设备驱动开发的重要性,也曾因此踩过无数的坑。市面上的资料汗牛充栋,但真正能深入浅出、紧跟最新内核版本、并且提供大量实战案例的书籍却凤毛麟角。当我翻开这本书的第一页,就被其严谨的结构和详实的论述所吸引。它没有空泛的概念堆砌,而是从最基础的硬件交互原理出发,逐步深入到 Linux 内核的驱动模型、总线、设备、驱动的注册与匹配机制。尤其是对于最新 4.0 内核的适配,这对于像我这样需要维护和开发新硬件支持的工程师来说,简直是雪中送炭。以往很多教程都是基于较老的内核版本,很多 API 和框架都发生了变化,导致学习成本倍增。这本书恰好弥补了这一缺憾,让我能够安心地将精力投入到核心的驱动开发逻辑中,而不是被零碎的内核版本差异所困扰。我特别期待书中关于中断处理、DMA、电源管理以及各类总线(如 I2C、SPI、PCIe)的驱动开发章节,这些都是实际项目中经常会遇到的关键技术点,相信这本书会提供非常有价值的指导。

评分

书的质量不错,纸张挺好。正规出版社出品。挺不错喜欢。

评分

评分

很好的产品,相信京东自营的品质,好评

评分

评分

收到的书不错,是正版,很划得来

评分

书不错,内容详细,值得学习

评分

好!!!!!!!!!!!!

评分

*...

评分

快递很快 支持京东618

相关图书

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 book.cndgn.com All Rights Reserved. 新城书站 版权所有