图书目录

第1篇  基础知识

第1章  Linux驱动开发概述 2

1.1  Linux设备驱动基础知识 2

1.1.1  设备驱动程序概述 2

1.1.2  设备驱动程序的作用 2

1.1.3  设备驱动的分类 3

1.2  Linux操作系统与驱动的关系 4

1.3  Linux驱动程序开发简介 4

1.3.1  用户态和内核态 5

1.3.2  模块机制 5

1.3.3  编写设备驱动程序需要了解的知识 6

1.4  编写设备驱动程序的注意事项 6

1.4.1  应用程序开发与驱动程序开发的差异 6

1.4.2  使用GUN C开发驱动程序 7

1.4.3  不能使用C函数库开发驱动程序 7

1.4.4  没有内存保护机制 8

1.4.5  小内核栈 8

1.4.6  重视可移植性 8

1.5  Linux驱动的发展趋势 9

1.5.1  Linux驱动的发展前景 9

1.5.2  驱动的应用 9

1.5.3  相关学习资源 9

1.6  小结 10

1.7  习题 10

第2章  嵌入式处理器和开发板 11

2.1  处理器 11

2.1.1  处理器简介 11

2.1.2  处理器的种类 11

2.2  ARM处理器 12

2.2.1  ARM处理器简介 12

2.2.2  ARM处理器系列 13

2.2.3  ARM处理器的应用 14

2.2.4  ARM处理器的选型 15

2.2.5  ARM处理器选型举例 18

2.3  S3C2440开发板 19

2.3.1  S3C2440开发板简介 19

2.3.2  S3C2440开发板的特性 19

2.3.3  其他开发板 21

2.4  小结 21

2.5  习题 21

第3章  构建嵌入式驱动程序开发环境 23

3.1  安装虚拟机和Linux系统 23

3.1.1  在Windows上安装虚拟机 23

3.1.2  在虚拟机上安装Linux系统 27

3.1.3  设置共享目录 29

3.2  代码阅读工具Source Insight 30

3.2.1  Source Insight简介 31

3.2.2  阅读源代码 31

3.3  小结 34

3.4  习题 35

第4章  构建嵌入式Linux操作系统 36

4.1  Linux操作系统简介 36

4.2  Linux操作系统的优点 37

4.3  Linux内核子系统 38

4.3.1  进程管理 38

4.3.2  内存管理 39

4.3.3  文件系统 39

4.3.4  设备管理 40

4.3.5  网络管理 40

4.4  Linux源代码结构分析 40

4.4.1  arch目录 40

4.4.2  drivers目录 41

4.4.3  fs目录 41

4.4.4  其他目录 42

4.5  内核配置选项 43

4.5.1  配置编译过程 43

4.5.2  常规配置 44

4.5.3  模块配置 46

4.5.4  块设备层配置 47

4.5.5  CPU类型和特性配置 47

4.5.6  电源管理配置 48

4.5.7  总线配置 49

4.5.8  网络配置 49

4.5.9  设备驱动配置 50

4.5.10  文件系统配置 54

4.5.11  其他配置 56

4.6  嵌入式文件系统简介 56

4.6.1  嵌入式系统的存储介质 57

4.6.2  JFFS文件系统 57

4.6.3  YAFFS文件系统 58

4.7  构建根文件系统简介 58

4.7.1  Linux根文件系统目录结构 59

4.7.2  使用BusyBox构建根文件系统 60

4.8  小结 65

4.9  习题 65

第5章  构建第一个驱动程序 67

5.1  升级内核 67

5.1.1  为什么要升级内核 67

5.1.2  升级内核的方式 68

5.2  编写Hello World驱动程序 70

5.2.1  驱动模块的组成 70

5.2.2  编写Hello World模块 71

5.2.3  编译Hello World模块 72

5.2.4  模块的操作命令 74

5.2.5  Hello World模块对文件系统的影响 75

5.3  模块参数和模块之间的通信 76

5.3.1  模块参数 76

5.3.2  模块使用的文件格式ELF 76

5.3.3  模块之间的通信 77

5.3.4  模块之间的通信实例 78

5.4  将模块加入内核 81

5.4.1  向内核添加模块 81

5.4.2  Kconfig文件 81

5.4.3  Kconfig文件的语法 83

5.4.4  应用实例:在内核中增加add_sub模块 86

5.4.5  对add_sub模块进行配置 87

5.5  小结 89

5.6  习题 89

第6章  简单的字符设备驱动程序 91

6.1  字符设备驱动程序框架 91

6.1.1  字符设备和块设备 91

6.1.2  主设备号和次设备号 92

6.1.3  申请和释放设备号 94

6.2  初识cdev结构体 95

6.2.1  cdev结构体简介 95

6.2.2  file_operations结构体简介 96

6.2.3  cdev和file_operations结构体的关系 97

6.2.4  inode结构体简介 98

6.3  字符设备驱动程序的组成 99

6.3.1  字符设备驱动程序的加载和卸载函数 99

6.3.2  file_operations结构体成员函数 100

6.3.3  驱动程序与应用程序的数据交换 100

6.3.4  字符设备驱动程序组成小结 101

6.4  VirtualDisk字符设备驱动程序 101

6.4.1  VirtualDisk的头文件、宏和设备结构体 102

6.4.2  加载和卸载驱动程序 102

6.4.3  初始化和注册cdev 104

6.4.4  打开和释放函数 104

6.4.5  读写函数 105

6.4.6  seek()函数 106

6.5  小结 108

6.6  习题 108

第2篇  核心技术

第7章  设备驱动的并发控制 110

7.1  并发与竞争 110

7.2  原子变量操作 110

7.2.1  定义原子变量 110

7.2.2  原子整型操作 111

7.2.3  原子位操作 113

7.3  自旋锁 114

7.3.1  自旋锁的操作方法 114

7.3.2  自旋锁的注意事项 115

7.4  信号量 116

7.4.1  信号量的实现 116

7.4.2  信号量的操作方法 117

7.4.3  自旋锁与信号量的对比 119

7.5  完成量 119

7.5.1  完成量的实现 120

7.5.2  完成量的操作方法 120

7.6  小结 122

7.7  习题 122

第8章  设备驱动的阻塞和同步机制 123

8.1  阻塞和非阻塞 123

8.2  等待队列 123

8.2.1  等待队列的实现 123

8.2.2  等待队列操作方法 124

8.3  同步机制实验 126

8.3.1  同步机制设计 126

8.3.2  同步机制验证 129

8.4  小结 131

8.5  习题 131

第9章  中断与时钟机制 133

9.1  中断简述 133

9.1.1  中断的概念 133

9.1.2  中断的宏观分类 134

9.1.3  中断产生的位置分类 134

9.1.4  同步和异步中断 135

9.2  中断的实现过程 135

9.2.1  中断信号线 136

9.2.2  中断控制器 136

9.2.3  中断处理过程 136

9.2.4  中断的安装与释放 137

9.3  按键中断实例 138

9.3.1  按键设备原理图 138

9.3.2  有寄存器设备和无寄存器设备 139

9.3.3  G端口控制寄存器 139

9.4  按键驱动程序实例分析 141

9.4.1  初始化函数s3c2440_buttons_init() 142

9.4.2  中断处理函数isr_button() 143

9.4.3  退出函数s3c2440_buttons_exit() 144

9.5  时钟机制 144

9.5.1  时间度量 144

9.5.2  延时 145

9.6  小结 146

9.7  习题 146

第10章  内外存访问 147

10.1  内存分配 147

10.1.1  kmalloc()函数 147

10.1.2  vmalloc()函数 148

10.1.3  后备高速缓存 150

10.2  页面分配 151

10.2.1  内存分配 151

10.2.2  物理地址和虚拟地址之间的转换 154

10.3  设备I/O端口的访问 155

10.3.1  Linux I/O端口读写函数 155

10.3.2  I/O内存读写 155

10.3.3  使用I/O端口 157

10.4  小结 159

10.5  习题 159

第3篇  应用实战

第11章  设备驱动模型 162

11.1  设备驱动模型概述 162

11.1.1  设备驱动模型的功能 162

11.1.2  sysfs文件系统 163

11.1.3  sysfs文件系统的目录结构 164

11.2  设备驱动模型的核心数据结构 166

11.2.1  kobject结构体 166

11.2.2  设备属性kobj_type 170

11.3  kobject对象的应用 173

11.3.1  设备驱动模型结构 173

11.3.2  kset集合 174

11.3.3  kset与kobject的关系 176

11.3.4  kset的相关操作函数 176

11.3.5  注册kobject到sysfs实例 177

11.3.6  实例测试 181

11.4  设备驱动模型的三大组件 182

11.4.1  总线 182

11.4.2  总线属性和总线方法 186

11.4.3  设备 187

11.4.4  驱动 188

11.5  小结 191

11.6  习题 192

第12章  实时时钟驱动程序 193

12.1  RTC实时时钟的硬件原理 193

12.1.1  实时时钟简介 193

12.1.2  RTC实时时钟的功能 193

12.1.3  RTC实时时钟的工作原理 195

12.2  RTC实时时钟架构 199

12.2.1  注册和卸载平台设备驱动 199

12.2.2  RTC实时时钟的平台设备驱动 200

12.2.3  RTC驱动探测函数 201

12.2.4  RTC设备注册函数devm_rtc_device_register() 204

12.3  RTC文件系统接口 204

12.3.1  文件系统接口rtc_class_ops 205

12.3.2  RTC实时时钟获得时间函数s3c_rtc_gettime() 206

12.3.3  RTC实时时钟设置时间函数s3c_rtc_settime() 207

12.3.4  RTC驱动探测函数s3c_rtc_getalarm() 208

12.3.5  RTC实时时钟设置报警时间函数s3c_rtc_setalarm() 209

12.4  小结 210

12.5  习题 211

第13章  看门狗驱动程序 212

13.1  看门狗概述 212

13.1.1  看门狗的功能 212

13.1.2  看门狗的工作原理 212

13.2  设备模型 214

13.2.1  平台设备模型 214

13.2.2  平台设备 215

13.2.3  平台设备驱动 217

13.2.4  平台设备驱动的注册和注销 218

13.2.5  混杂设备 219

13.2.6  混杂设备的注册和注销 220

13.3  看门狗设备驱动程序分析 220

13.3.1  看门狗驱动程序的一些变量定义 220

13.3.2  注册和卸载看门狗驱动 221

13.3.3  看门狗驱动程序探测函数 221

13.3.4  设置看门狗复位时间函数s3c2410wdt_set_heartbeat() 223

13.3.5  看门狗的开始函数s3c2410wdt_start()和停止函数s3c2410wdt_stop() 224

13.3.6  看门狗驱动程序移除函数s3c2410wdt_remove() 225

13.3.7  平台设备驱动s3c2410wdt_driver中的其他重要函数 226

13.3.8  看门狗中断处理函数s3c2410wdt_irq() 227

13.4  小结 227

13.5  习题 227

第14章  IIC设备驱动程序 229

14.1  IIC设备的总线及其协议 229

14.1.1  IIC总线的特点 229

14.1.2  IIC总线的信号类型 230

14.1.3  IIC总线的数据传输 230

14.2  IIC设备的硬件结构 230

14.3  IIC设备驱动程序的层次结构 232

14.3.1  IIC设备驱动概述 232

14.3.2  IIC设备层 233

14.3.3  i2c_driver和i2c_client的关系 235

14.3.4  IIC总线层 236

14.3.5  IIC设备层和总线层的关系 237

14.3.6  写IIC设备驱动的步骤 238

14.4  IIC子系统的初始化 238

14.4.1  IIC子系统初始化函数i2c_init() 238

14.4.2  IIC子系统退出函数i2c_exit() 239

14.5  适配器驱动程序 240

14.5.1  S3C2440对应的适配器结构体 240

14.5.2  IIC适配器加载函数i2c_add_adapter() 242

14.5.3  IDR机制 242

14.5.4  适配器卸载函数i2c_del_adapter() 244

14.5.5  IIC总线通信方法s3c24xx_i2c_algorithm结构体 244

14.5.6  适配器的传输函数s3c24xx_i2c_doxfer() 246

14.5.7  适配器的中断处理函数s3c24xx_i2c_irq() 249

14.5.8  字节传输函数i2c_s3c_irq_nextbyte() 251

14.5.9  适配器传输停止函数s3c24xx_i2c_stop() 253

14.5.10  中断处理函数的一些辅助函数 254

14.6  IIC设备层驱动程序 255

14.6.1  加载和卸载IIC设备驱动模块 255

14.6.2  探测函数s3c24xx_i2c_probe() 256

14.6.3  移除函数s3c24xx_i2c_remove() 258

14.6.4  控制器初始化函数s3c24xx_i2c_init() 259

14.6.5  设置控制器数据发送频率函数s3c24xx_i2c_clockrate() 259

14.7  小结 261

14.8  习题 262

第15章  LCD设备驱动程序 263

15.1  FrameBuffer概述 263

15.1.1  FrameBuffer与应用程序的交互 264

15.1.2  FrameBuffer的显示原理 264

15.1.3  LCD显示原理 265

15.2  FrameBuffer结构分析 265

15.2.1  FrameBuffer架构 265

15.2.2  FrameBuffer驱动程序的实现 266

15.2.3  FrameBuffer驱动程序的组成 267

15.3  LCD驱动程序分析 272

15.3.1  LCD模块的加载和卸载函数 273

15.3.2  LCD驱动程序的平台数据 274

15.3.3  LCD模块的探测函数 275

15.3.4  移除函数 279

15.4  小结 280

15.5  习题 280

第16章  触摸屏设备驱动程序 282

16.1  触摸屏设备的工作原理 282

16.1.1  触摸屏设备简介 282

16.1.2  触摸屏设备类型 282

16.1.3  电阻式触摸屏 283

16.2  触摸屏设备的硬件结构 283

16.2.1  S3C2440触摸屏接口简介 283

16.2.2  S3C2440触摸屏接口的工作模式 284

16.2.3  S3C2440触摸屏设备寄存器 284

16.3  触摸屏设备驱动程序分析 288

16.3.1  触摸屏设备驱动程序构成 288

16.3.2  S3C2440触摸屏设备驱动程序的注册和卸载 289

16.3.3  S3C2440触摸屏驱动模块探测函数 289

16.3.4  触摸屏设备驱动程序中断处理函数 292

16.3.5  S3C2440触摸屏设备驱动模块的remove()函数 293

16.4  测试触摸屏设备驱动程序 294

16.5  小结 295

16.6  习题 295

第17章  输入子系统设计 297

17.1  input子系统入门 297

17.1.1  简单的实例 297

17.1.2  注册函数input_register_device() 299

17.1.3  向子系统报告事件 303

17.2  Handler处理器注册分析 308

17.2.1  输入子系统的构成 308

17.2.2  input_handler结构体 308

17.2.3  注册input_handler 309

17.2.4  input_handle结构体 310

17.2.5  注册input_handle 311

17.3  input子系统 312

17.4  evdev输入事件驱动程序分析 313

17.4.1  evdev的初始化 313

17.4.2  打开evdev设备 315

17.5  小结 318

17.6  习题 318

第18章  块设备驱动程序 319

18.1  块设备概述 319

18.1.1  块设备简介 319

18.1.2  块设备的结构 320

18.2  块设备驱动程序架构 322

18.2.1  块设备的加载过程 322

18.2.2  块设备的卸载过程 323

18.3  通用块层 323

18.3.1  通用块层简介 323

18.3.2  blk_alloc_disk()函数对应的gendisk结构体 324

18.3.3  块设备的注册和注销 326

18.3.4  请求队列 327

18.3.5  设置gendisk属性中的block_device_operations结构体 327

18.4  I/O调度器 328

18.4.1  数据从内存到磁盘的过程 329

18.4.2  块I/O请求 329

18.4.3  请求结构 331

18.4.4  请求队列 333

18.4.5  请求队列、请求结构和bio的关系 334

18.4.6  四种调度算法 335

18.5  编写块设备驱动程序 337

18.5.1  宏定义和全局变量 337

18.5.2  加载函数 339

18.5.3  卸载函数 341

18.5.4  自定义请求处理函数 341

18.5.5  驱动测试 342

18.6  小结 345

18.7  习题 345

第19章  USB设备驱动程序 346

19.1  USB概述 346

19.1.1  USB的发展版本 346

19.1.2  USB的特点 347

19.1.3  USB总线拓扑结构 348

19.1.4  USB驱动总体架构 348

19.2  USB设备驱动模型 352

19.2.1  USB设备驱动初探 352

19.2.2  USB设备驱动模型实现原理 355

19.2.3  USB设备驱动结构usb_driver 357

19.3  USB设备驱动程序 362

19.3.1  USB设备驱动程序加载和卸载函数 362

19.3.2  探测函数probe()的参数usb_interface 363

19.3.3  USB协议中的设备 363

19.3.4  端点的传输方式 369

19.3.5  设置 370

19.3.6  探测函数storage_probe() 372

19.4  获得USB设备信息 375

19.4.1  设备关联函数associate_dev() 375

19.4.2  获得设备信息函数get_device_info() 377

19.4.3  获得传输协议函数get_transport() 378

19.4.4  获得协议信息函数get_protocol() 379

19.4.5  获得管道信息函数get_pipes() 379

19.5  资源初始化 382

19.5.1  storage_probe()函数的调用过程 382

19.5.2  资源获取函数usb_stor_acquire_resources() 382

19.5.3  USB请求块 383

19.6  控制子线程 387

19.6.1  控制线程 387

19.6.2  扫描延迟工作函数usb_stor_scan_dwork() 389

19.6.3  获得LUN函数usb_stor_Bulk_max_lun() 389

19.7  小结 396

19.8  习题 396