Linux 设备驱动 中文 Edition 3 第三版 PDF 文档

以 Linux 为代表的自由操作系统的很多优点之一,是它们的内部是开放给所有人看的。操作系统,曾经是一个隐藏的神秘的地方,它的代码只局限于少数的程序员,现在已准备好让任何具备必要技能的人来检查,理解以及修改。

Linux 设备驱动 中文 Edition 3 第三版 PDF 文档

Linux 已经帮助使操作系统民主化,Linux 内核保留有大量的复杂的代码,但是,那些想要成为内核 hacker 的人需要一个入口点,这样他们可以进入代码中,不会被代码的复杂性压倒,通常,设备驱动提供了这样的门路。

目录

第 1 章 设备驱动简介…………………………….. 1

1.1. 驱动程序的角色………………………….. 1

1.2. 划分内核…………………………………….. 2

1.2.1. 可加载模块………………………….. 3

1.3. 设备和模块的分类………………………. 4

1.4. 安全问题…………………………………….. 6

1.5. 版本编号…………………………………….. 7

1.6. 版权条款…………………………………….. 8

1.7. 加入内核开发社团………………………. 9

1.8. 本书的内容…………………………………. 9

第 2 章 建立和运行模块…………………… 11

2.1. 设置你的测试系统…………………….. 11

2.2. HELLO WORLD 模块……………………. 11

2.3. 内核模块相比于应用程序…………… 13

2.3.1. 用户空间和内核空间…………… 14

2.3.2. 内核的并发………………………… 15

2.3.3. 当前进程……………………………. 15

2.3.4. 几个别的细节…………………….. 16

2.4. 编译和加载……………………………….. 16

2.4.1. 编译模块……………………………. 16

2.4.2. 加载和卸载模块…………………. 18

2.4.3. 版本依赖……………………………. 19

2.4.4. 平台依赖性………………………… 20

2.5. 内核符号表……………………………….. 21

2.6. 预备知识…………………………………… 22

2.7. 初始化和关停……………………………. 22

2.7.1. 清理函数……………………………. 23

2.7.2. 初始化中的错误处理…………… 24

2.7.3. 模块加载竞争…………………….. 26

2.8. 模块参数…………………………………… 26

2.9. 在用户空间做……………………………. 28

2.10. 快速参考…………………………………. 29

第 3 章 字符驱动……………………………… 32

3.1. SCULL 的设计…………………………….. 32

3.2. 主次编号…………………………………… 33

3.2.1. 设备编号的内部表示…………… 33

3.2.2. 分配和释放设备编号…………… 34

3.2.3. 主编号的动态分配……………… 35

3.3. 一些重要数据结构…………………….. 37

3.3.1. 文件操作……………………………. 37

3.3.2. 文件结构……………………………. 41

3.3.3. inode 结构………………………….. 43

3.4. 字符设备注册……………………………. 43

3.4.1. scull 中的设备注册……………… 44

3.4.2. 老方法……………………………….. 45

3.5. OPEN 和 RELEASE ………………………… 45

3.5.1. open 方法…………………………… 45

3.5.2. release 方法………………………… 47

3.6. SCULL 的内存使用……………………… 47

3.7. 读和写………………………………………. 50

3.7.1. read 方法……………………………. 52

3.7.2. write 方法…………………………… 53

3.7.3. readv 和 writev ……………………. 55

3.8. 使用新设备……………………………….. 55

3.9. 快速参考…………………………………… 56

第 4 章 调试技术……………………………… 58

4.1. 内核中的调试支持…………………….. 58

4.2. 用打印调试……………………………….. 60

4.2.1. printk………………………………….. 60

4.2.2. 重定向控制台消息……………… 62

4.2.3. 消息是如何记录的……………… 62

4.2.4. 打开和关闭消息…………………. 63

4.2.5. 速率限制……………………………. 65

4.2.6. 打印设备编号…………………….. 65

4.3. 用查询来调试……………………………. 66

4.3.1. 使用 /proc 文件系统……………. 66

4.3.2. ioctl 方法……………………………. 73

4.4. 使用观察来调试………………………… 73

4.5. 调试系统故障……………………………. 75

4.5.1. oops 消息……………………………. 76

4.5.2. 系统挂起……………………………. 78

4.6. 调试器和相关工具…………………….. 80

4.6.1. 使用 gdb …………………………….. 80

4.6.2. kdb 内核调试器………………….. 83

4.6.3. kgdb 补丁…………………………… 85

4.6.4. 用户模式 Linux 移植…………… 85

4.6.5. Linux 追踪工具…………………… 86

4.6.6. 动态探针……………………………. 86

第 5 章 并发和竞争情况…………………… 87

5.1. SCULL 中的缺陷…………………………. 87

5.2. 并发和它的管理………………………… 88

5.3. 旗标和互斥体……………………………. 89

5.3.1. Linux 旗标实现…………………… 89

5.3.2. 在 scull 中使用旗标…………….. 91

5.3.3. 读者/写者旗标……………………. 92

5.4. COMPLETIONS 机制…………………….. 93

5.5. 自旋锁………………………………………. 95

5.5.1. 自旋锁 API 简介…………………. 95

5.5.2. 自旋锁和原子上下文…………… 96

5.5.3. 自旋锁函数………………………… 97

5.5.4. 读者/写者自旋锁………………… 98

5.6. 锁陷阱………………………………………. 99

5.6.1. 模糊的规则………………………… 99

5.6.2. 加锁顺序规则…………………….. 99

5.6.3. 细 -粗- 粒度加锁……………….. 100

5.7. 加锁的各种选择………………………. 100

5.7.1. 不加锁算法………………………. 100

5.7.2. 原子变量………………………….. 101

5.7.3. 位操作……………………………… 103

5.7.4. seqlock 锁…………………………. 104

5.7.5. 读取-拷贝-更新…………………. 105

5.8. 快速参考…………………………………. 106

第 6 章 高级字符驱动操作……………… 111

6.1. IOCTL 接口……………………………….. 111

6.1.1. 选择 ioctl 命令………………….. 112

6.1.2. 返回值……………………………… 115

6.1.3. 预定义的命令…………………… 115

6.1.4. 使用 ioctl 参数………………….. 116

6.1.5. 兼容性和受限操作……………. 118

6.1.6. ioctl 命令的实现……………….. 119

6.1.7. 不用 ioctl 的设备控制………… 120

6.2. 阻塞 I/O…………………………………… 121

6.2.1. 睡眠的介绍………………………. 122

6.2.2. 简单睡眠………………………….. 122

6.2.3. 阻塞和非阻塞操作……………. 124

6.2.4. 一个阻塞 I/O 的例子………….. 125

6.2.5. 高级睡眠………………………….. 127

6.2.6. 测试 scullpipe 驱动……………. 134

6.3. POLL 和 SELECT…………………………. 135

6.3.1. 与 read 和 write 的交互………. 137

6.3.2. 底层的数据结构……………….. 139

6.4. 异步通知…………………………………. 140

6.4.1. 驱动的观点………………………. 141

6.5. 移位一个设备………………………….. 142

6.5.1. llseek 实现………………………… 143

6.6. 在一个设备文件上的存取控制….. 144

6.6.1. 单 open 设备…………………….. 144

6.6.2. 一次对一个用户限制存取….. 145

6.6.3. 阻塞 open 作为对 EBUSY 的替代………………………………………….. 146

6.6.4. 在 open 时复制设备…………… 148

6.7. 快速参考…………………………………. 150

第 7 章 时间, 延时, 和延后工作………… 154

7.1. 测量时间流失………………………….. 154

7.1.1. 使用 jiffies 计数器…………….. 154

7.1.2. 处理器特定的寄存器…………. 156

7.2. 获知当前时间………………………….. 158

7.3. 延后执行…………………………………. 159

7.3.1. 长延时……………………………… 160

7.3.2. 短延时……………………………… 164

7.4. 内核定时器……………………………… 165

7.4.1. 定时器 API ……………………….. 166

7.4.2. 内核定时器的实现……………. 169

7.5. TASKLETS 机制…………………………. 170

7.6. 工作队列…………………………………. 172

7.6.1. 共享队列………………………….. 174

7.7. 快速参考…………………………………. 176

7.7.1. 时间管理………………………….. 176

7.7.2. 延迟…………………………………. 177

7.7.3. 内核定时器………………………. 178

7.7.4. Tasklets 机制…………………….. 178

7.7.5. 工作队列………………………….. 179

第 8 章 分配内存……………………………. 181

8.1. KMALLOC 的真实故事………………. 181

8.1.1. flags 参数…………………………. 181

8.1.2. size 参数………………………….. 184

8.2. 后备缓存…………………………………. 184

8.2.1. 一个基于 Slab 缓存的 scull: scullc ………………………………………… 186

8.2.2. 内存池……………………………… 187

8.3. GET_FREE_PAGE 和其友…………….. 188

8.3.1. 一个使用整页的 scull: scullp . 189

8.3.2. alloc_pages 接口……………….. 190

8.3.3. vmalloc 和 其友…………………. 191

8.3.4. 一个使用虚拟地址的 scull : scullv ………………………………………… 193

8.4. 每-CPU 的变量………………………… 194

8.5. 获得大量缓冲………………………….. 196

8.5.1. 在启动时获得专用的缓冲….. 196

8.6. 快速参考…………………………………. 197

第 9 章 与硬件通讯………………………… 201

9.1. I/O 端口和 I/O 内存………………….. 201

9.1.1. I/O 寄存器和常规内存……….. 202

9.2. 使用 I/O 端口…………………………… 203

9.2.1. I/O 端口分配…………………….. 204

9.2.2. 操作 I/O 端口……………………. 204

9.2.3. 从用户空间的 I/O 存取………. 205

9.2.4. 字串操作………………………….. 206

9.2.5. 暂停 I/O……………………………. 206

9.2.6. 平台依赖性………………………. 207

9.3. 一个 I/O 端口例子……………………. 209

9.3.1. 并口纵览………………………….. 209

9.3.2. 一个例子驱动…………………… 210

9.4. 使用 I/O 内存…………………………… 211

9.4.1. I/O 内存分配和映射…………… 212

9.4.2. 存取 I/O 内存……………………. 213

9.4.3. 作为 I/O 内存的端口………….. 214

9.4.4. 重用 short 为 I/O 内存………… 215

9.4.5. 在 1 MB 之下的 ISA 内存……. 215

9.4.6. isa_readb 和其友………………. 217

9.5. 快速参考…………………………………. 217

第 10 章 中断处理………………………….. 220

10.1. 准备并口……………………………….. 220

10.2. 安装一个中断处理…………………. 220

10.2.1. /proc 接口……………………….. 223

10.2.2. 自动检测 IRQ 号……………… 224

10.2.3. 快速和慢速处理……………… 228

10.2.4. 实现一个处理…………………. 229

10.2.5. 处理者的参数和返回值……. 232

10.2.6. 使能和禁止中断……………… 233

10.3. 前和后半部……………………………. 234

10.3.1. Tasklet 实现…………………….. 235

10.3.2. 工作队列………………………… 236

10.4. 中断共享……………………………….. 237

10.4.1. 安装一个共享的处理者……. 237

10.4.2. 运行处理者…………………….. 238

10.4.3. /proc 接口和共享中断………. 239

10.5. 中断驱动 I/O………………………….. 239

10.5.1. 一个写缓存例子……………… 240

10.6. 快速参考……………………………….. 243

第 11 章 内核中的数据类型……………. 245

11.1. 标准 C 类型的使用…………………. 245

11.2. 安排一个明确大小给数据项……. 246

11.3. 接口特定的类型…………………….. 247

11.4. 其他移植性问题…………………….. 248

11.4.1. 时间间隔………………………… 248

11.4.2. 页大小……………………………. 248

11.4.3. 字节序……………………………. 248

11.4.4. 数据对齐………………………… 249

11.4.5. 指针和错误值…………………. 250

11.5. 链表………………………………………. 251

11.6. 快速参考……………………………….. 255

第 12 章 PCI 驱动…………………………… 257

12.1. PCI 接口………………………………… 257

12.1.1. PCI 寻址…………………………. 257

12.1.2. 启动时间………………………… 260

12.1.3. 配置寄存器和初始化……….. 261

12.1.4. MODULEDEVICETABLE 宏 264

12.1.5. 注册一个 PCI 驱动…………… 264

12.1.6. 老式 PCI 探测…………………. 266

12.1.7. 使能 PCI 设备…………………. 267

12.1.8. 存取配置空间…………………. 267

12.1.9. 存取 I/O 和内存空间………… 268

12.1.10. PCI 中断……………………….. 270

12.1.11. 硬件抽象………………………. 270

12.2. 回顾: ISA……………………………….. 272

12.2.1. 硬件资源………………………… 272

12.2.2. ISA 编程…………………………. 272

12.2.3. 即插即用规范…………………. 273

12.3. PC/104 和 PC/104+ …………………. 273

12.4. 其他的 PC 总线………………………. 274

12.4.1. MCA 总线……………………….. 274

12.4.2. EISA 总线……………………….. 274

12.4.3. VLB 总线………………………… 274

12.5. SBUS……………………………………… 275

12.6. NUBUS 总线…………………………… 275

12.7. 外部总线……………………………….. 275

12.8. 快速参考……………………………….. 276

第 13 章 USB 驱动…………………………. 278

13.1. USB 设备基础知识…………………. 279

13.1.1. 端点……………………………….. 279

13.1.2. 接口……………………………….. 281

13.1.3. 配置……………………………….. 282

13.2. USB 和 SYSFS …………………………. 282

13.3. USB 的 URBS………………………….. 284

13.3.1. 结构 struct urb…………………. 285

13.3.2. 创建和销毁 urb……………….. 291

13.3.3. 提交 urb………………………….. 294

13.3.4. 完成 urb: 完成回调处理者… 294

13.3.5. 取消 urb………………………….. 295

13.4. 编写一个 USB 驱动………………… 295

13.4.1. 驱动支持什么设备…………… 295

13.4.2. 注册一个 USB 驱动………….. 297

13.4.3. 提交和控制一个 urb………… 303

13.5. 无 URB 的 USB 传送………………… 304

13.5.1. usb_bulk_msg 接口…………… 305

13.5.2. usb_control_msg 接口……….. 306

13.5.3. 使用 USB 数据函数………….. 307

13.6. 快速参考……………………………….. 308

第 14 章 LINUX 设备模型………………… 311

14.1. KOBJECTS, KSETS 和 SUBSYSTEMS 312

14.1.1. Kobject 基础……………………. 313

14.1.2. kobject 层次, kset, 和子系统. 316

14.2. 低级 SYSFS 操作……………………… 319

14.2.1. 缺省属性………………………… 319

14.2.2. 非缺省属性…………………….. 321

14.2.3. 二进制属性…………………….. 321

14.2.4. 符号连接………………………… 322

14.3. 热插拔事件产生…………………….. 322

14.3.1. 热插拔操作…………………….. 323

14.4. 总线, 设备, 和驱动…………………. 324

14.4.1. 总线……………………………….. 324

14.4.2. 设备……………………………….. 327

14.4.3. 设备驱动………………………… 331

14.5. 类………………………………………….. 333

14.5.1. class_simple 接口…………….. 334

14.5.2. 完整的类接口…………………. 335

14.6. 集成起来……………………………….. 337

14.6.1. 添加一个设备…………………. 338

14.6.2. 去除一个设备…………………. 341

14.6.3. 添加一个驱动…………………. 341

14.6.4. 去除一个驱动…………………. 342

14.7. 热插拔…………………………………… 342

14.7.1. 动态设备………………………… 342

14.7.2. /sbin/hotplug 工具……………. 343

14.7.3. 使用 /sbin/hotplug ……………. 347

14.8. 处理固件……………………………….. 349

14.8.1. 内核固件接口…………………. 350

14.8.2. 它如何工作…………………….. 350

14.9. 快速参考……………………………….. 351

14.9.1. Kobjects结构…………………… 351

14.9.2. sysfs 操作………………………… 352

14.9.3. 总线, 设备, 和驱动…………… 352

14.9.4. 类…………………………………… 353

14.9.5. 固件……………………………….. 354

第 15 章 内存映射和 DMA……………… 355

15.1. LINUX 中的内存管理………………. 355

15.1.1. 地址类型………………………… 355

15.1.2. 物理地址和页…………………. 357

15.1.3. 高和低内存…………………….. 357

15.1.4. 内存映射和 struct page……… 358

15.1.5. 页表……………………………….. 360

15.1.6. 虚拟内存区…………………….. 360

15.1.7. 进程内存映射…………………. 363

15.2. MMAP 设备操作……………………… 363

15.2.1. 使用 remap_pfn_range………. 365

15.2.2. 一个简单的实现……………… 366

15.2.3. 添加 VMA 的操作……………. 366

15.2.4. 使用 nopage 映射内存………. 367

15.2.5. 重新映射特定 I/O 区………… 369

15.2.6. 重新映射 RAM………………… 370

15.2.7. 重映射内核虚拟地址……….. 373

15.3. 进行直接 I/O………………………….. 374

15.3.1. 异步 I/O………………………….. 376

15.4. 直接内存存取………………………… 379

15.4.1. 一个 DMA 数据传输的概况. 379

15.4.2. 分配 DMA 缓冲……………….. 380

15.4.3. 总线地址………………………… 381

15.4.4. 通用 DMA 层…………………… 382

15.4.5. ISA 设备的 DMA……………… 390

15.5. 快速参考……………………………….. 395

15.5.1. 介绍性材料…………………….. 395

15.5.2. 实现 mmap ……………………… 396

15.5.3. 实现直接 I/O…………………… 397

15.5.4. 直接内存存取…………………. 397

第 16 章 块驱动……………………………… 400

16.1. 注册………………………………………. 400

16.1.1. 块驱动注册…………………….. 400

16.1.2. 磁盘注册………………………… 401

16.1.3. 在 sbull 中的初始化………….. 403

16.1.4. 注意扇区大小…………………. 405

16.2. 块设备操作……………………………. 405

16.2.1. open 和 release 方法…………. 405

16.2.2. 支持可移出的介质…………… 407

16.2.3. ioctl 方法………………………… 407

16.3. 请求处理……………………………….. 408

16.3.1. 对请求方法的介绍…………… 408

16.3.2. 一个简单的请求方法……….. 409

16.3.3. 请求队列………………………… 411

16.3.4. 请求的分析…………………….. 414

16.3.5. 请求完成函数…………………. 419

16.4. 一些其他的细节…………………….. 423

16.4.1. 命令预准备…………………….. 423

16.4.2. 被标识的命令排队…………… 424

16.5. 快速参考……………………………….. 426

第 17 章 网络驱动………………………….. 430

17.1. SNULL 是如何设计的………………. 430

17.1.1. 分配 IP 号………………………. 431

17.1.2. 报文的物理传送……………… 433

17.2. 连接到内核……………………………. 433

17.2.1. 设备注册………………………… 433

17.2.2. 初始化每一个设备…………… 435

17.2.3. 模块卸载………………………… 436

17.3. NET_DEVICE 结构的详情………….. 437

17.3.1. 全局信息………………………… 437

17.3.2. 硬件信息………………………… 437

17.3.3. 接口信息………………………… 438

17.3.4. 设备方法………………………… 442

17.3.5. 公用成员………………………… 444

17.4. 打开与关闭……………………………. 445

17.5. 报文传送……………………………….. 446

17.5.1. 控制发送并发…………………. 448

17.5.2. 传送超时………………………… 448

17.5.3. 发散/汇聚 I/O………………….. 449

17.6. 报文接收……………………………….. 450

17.7. 中断处理……………………………….. 452

17.8. 接收中断缓解………………………… 454

17.9. 连接状态的改变…………………….. 456

17.10. SOCKET 缓存………………………… 457

17.10.1. 重要成员变量……………….. 457

17.10.2. 作用于 socket 缓存的函数. 458

17.11. MAC 地址解析…………………….. 460

17.11.1. 以太网使用 ARP……………. 460

17.11.2. 不考虑 ARP…………………… 461

17.11.3. 非以太网头部……………….. 461

17.12. 定制 IOCTL 命令……………………. 462

17.13. 统计信息……………………………… 463

17.14. 多播…………………………………….. 464

17.14.1. 多播的内核支持……………. 465

17.14.2. 典型实现………………………. 466

17.15. 几个其他细节………………………. 467

17.15.1. 独立于媒介的接口支持….. 467

17.15.2. ethtool 支持…………………… 468

17.15.3. netpoll …………………………… 468

17.16. 快速参考……………………………… 468

第 18 章 TTY 驱动…………………………. 472

18.1. 一个小 TTY 驱动……………………. 474

18.1.1. 结构 struct termios …………… 475

18.2. TTY_DRIVER 函数指针…………….. 478

18.2.1. open 和 close …………………… 478

18.2.2. 数据流……………………………. 481

18.2.3. 其他缓冲函数…………………. 482

18.2.4. 无 read 函数?………………….. 483

18.3. TTY 线路设置……………………….. 484

18.3.1. set_termios 函数………………. 484

18.3.2. tiocmget 和 tiocmset ………….. 486

18.4. IOCTLS 函数……………………………. 487

18.5. TTY 设备的 PROC 和 SYSFS 处理.. 490

18.6. TTY_DRIVER 结构的细节………….. 491

18.7. TTY_OPERAIONS 结构的细节…….. 493

18.8. TTY_STRUCT 结构的细节………….. 495

18.9. 快速参考……………………………….. 498

下载地址:https://www.wenjiangs.com/wp-content/uploads/2021/10/pIYBAFwnBwOAGVZDAHfaEiLTBrY196.zip

以上是 Linux 设备驱动 中文 Edition 3 第三版 PDF 文档 的全部内容, 来源链接: utcz.com/p/234012.html

回到顶部