编辑推荐
《Linux驱动程序开发实例》深入讲解了Linux设备驱动程序开发,内容包括Linux驱动程序基础、内核移植、I2C驱动程序、LCD驱动程序、网络驱动程序、USB驱动程序、输入子系统驱动程序、块设备驱动程序等。《Linux驱动程序开发实例》提供了丰富的实例代码和详细的注释,并附赠代码光盘一张。
基于ARM体系结构
全面剖析Linux驱动程序开发的精髓
涵盖多种硬件接口驱动程序
附赠内核代码与实例源代码
内容简介
《Linux驱动程序开发实例》专门介绍Linux设备驱动程序开发,涵盖了Linux驱动程序基础、内核移植、I2C驱动程序、LCD驱动程序、网络驱动程序、USB驱动程序、输入子系统驱动程序、块设备驱动程序等内容。《Linux驱动程序开发实例》以实例为主线,是为Linux设备驱动程序开发人员量身打造的精品学习图书和实战指南。《Linux驱动程序开发实例》提供了丰富的实例代码和详细的注释,并附赠完整代码光盘一张。
《Linux驱动程序开发实例》主要面向各层次的嵌入式Linux开发工程师,也可以作为各类嵌入式系统培训机构的培训教材和高校计算机课程的教辅书籍。
内页插图
目录
出版说明
前言
第1章 Linux设备驱动程序模型1
1.1 设备驱动程序基础1
1.1.1 驱动程序的概念1
1.1.2 驱动程序的加载方式2
1.1.3 编写可加载模块3
1.1.4 带参数的可加载模块5
1.1.5 设备驱动程序的分类6
1.2 字符设备驱动程序原理7
1.2.1 file_operations结构7
1.2.2 使用register_chrdev注册字符设备9
1.2.3 使用cdev_add注册字符设备11
1.2.4 字符设备的读写13
1.2.5 ioctl接口14
1.2.6 seek接口16
1.2.7 poll接口18
1.2.8 异步通知22
1.3 proc文件系统24
1.3.1 proc文件系统概述24
1.3.2 seq_file机制25
1.3.3 使用proc文件系统27
1.4 块设备驱动程序32
1.4.1 Linux块设备驱动程序原理32
1.4.2 简单的块设备驱动程序实例35
1.5 网络设备驱动程序39
1.5.1 网络设备的特殊性39
1.5.2 sk_buff结构40
1.5.3 Linux网络设备驱动程序架构42
1.5.4 虚拟网络设备驱动程序实例46
1.6 Linux 2.6设备管理机制50
1.6.1 kobject和kset50
1.6.2 sysfs文件系统51
1.6.3 设备模型层次52
1.6.4 platform的概念54
第2章 Linux内核同步机制58
2.1 锁机制58
2.1.1 自旋锁58
2.1.2 读写锁60
2.1.3 RCU61
2.2 互斥64
2.2.1 原子操作64
2.2.2 信号量65
2.2.3 读写信号量67
2.3 等待队列68
2.3.1 等待队列原理68
2.3.2 阻塞式I/O实例68
2.3.3 完成事件70
2.4 关闭中断71
第3章 内存管理与链表72
3.1 物理地址和虚拟地址72
3.2 内存分配与释放72
3.3 IO端口到虚拟地址的映射73
3.3.1 静态映射73
3.3.2 动态映射75
3.4 内核空间到用户空间的映射76
3.4.1 内核空间到用户空间的地址映射原理76
3.4.2 mmap地址映射实例78
3.5 内核链表80
3.5.1 Linux内核中的链表80
3.5.2 内核链表实例81
第4章 延迟处理83
4.1 内核线程83
4.2 软中断机制85
4.2.1 软中断原理85
4.2.2 tasklet87
4.3 工作队列89
4.3.1 工作队列原理89
4.3.2 工作队列实例91
4.4 内核时间92
4.4.1 Linux中的时间概念92
4.4.2 Linux中的延迟93
4.4.3 内核定时器93
第5章 简单设备驱动程序96
5.1 寄存器访问96
5.1.1 S3C6410地址映射96
5.1.2 S3C6410看门狗驱动程序实例98
5.1.3 S3C6410蜂鸣器驱动程序实例102
5.2 电平控制107
5.2.1 S3C6410 LED驱动程序实例107
5.2.2 扫描型S3C6410按键驱动程序实例109
5.3 时序产生112
5.3.1 时序图原理112
5.3.2 AT24C02芯片原理112
5.3.3 AT24C02驱动程序开发实例115
5.4 硬中断处理123
5.4.1 硬中断处理原理123
5.4.2 中断型S3C6410按键驱动程序实例127
5.5 Linux I/O端口控制132
5.5.1 Linux I/O端口读写132
5.5.2 在应用层访问Linux I/O端口133
5.5.3 /dev/port设备134
第6章 深入Linux内核135
6.1 嵌入式Linux系统构成135
6.2 Linux内核导读136
6.2.1 Linux内核组成136
6.2.2 Linux的代码结构137
6.2.3 内核Makefile138
6.2.4 S3C6410硬件初始化139
6.3 Linux文件系统141
6.3.1 虚拟文件系统141
6.3.2 根文件系统143
6.3.3 文件系统加载143
6.3.4 ext3文件系统145
6.4 Flash文件系统145
6.4.1 MTD设备145
6.4.2 MTD字符设备148
6.4.3 MTD块设备150
6.4.4 cramfs文件系统153
6.4.5 JFFS2文件系统153
6.4.6 YAFFS文件系统155
6.4.7 文件系统总结156
6.5 Linux内核移植156
6.5.1 体系配置156
6.5.2 添加yaffs2157
6.5.3 Nand flash驱动程序移植157
6.5.4 配置启动参数159
6.5.5 移植RTC驱动程序160
6.6 根文件系统制作162
6.6.1 Busybox162
6.6.2 shell基础165
6.6.3 根文件系统构建实例166
6.7 udev模型167
6.7.1 udev模型原理167
6.7.2 mdev的使用167
第7章 I2C总线驱动程序169
7.1 Linux的I2C驱动程序架构169
7.1.1 I2C适配器169
7.1.2 I2C算法170
7.1.3 I2C驱动程序结构170
7.1.4 I2C从设备171
7.1.5 i2c-dev设备层171
7.2 Linux I2C驱动程序开发174
7.2.1 S3C2410X的I2C控制器174
7.2.2 S3C2410X的I2C驱动程序分析175
7.3 S3C2410的I2C访问实例182
7.4 I2C客户端驱动程序185
第8章 TTY与串口驱动程序190
8.1 TTY概念190
8.2 Linux TTY驱动程序体系190
8.2.1 TTY驱动程序调用关系190
8.2.2 TTY驱动程序原理191
8.3 线路规程194
8.4 串口驱动程序与TTY196
8.4.1 串口设备驱动程序原理196
8.4.2 S3C6410的串口驱动程序实例199
8.5 TTY应用层202
第9章 网络设备驱动程序205
9.1 DM9000网卡驱动程序开发205
9.1.1 DM9000原理205
9.1.2 DM9000X驱动程序分析207
9.1.3 DM9000网口驱动程序移植215
9.2 NFS根文件系统搭建219
9.2.1 主机配置219
9.2.2 NFS根文件系统搭建实例220
9.3 netlink Socket224
9.3.1 netlink机制224
9.3.2 netlink应用层编程228
9.3.3 netlink驱动程序实例229
第10章 framebuffer驱动程序232
10.1 Linux framebuffer驱动程序原理232
10.1.1 framebuffer核心数据结构232
10.1.2 framebuffer操作接口234
10.1.3 framebuffer驱动程序的文件接口236
10.1.4 framebuffer驱动程序框架236
10.2 S3C6410 显示控制器238
10.3 S3C6410 LCD驱动程序实例243
10.4 framebuffer应用层250
10.5 Qt4界面系统移植251
第11章 输入子系统驱动程序253
11.1 Linux输入子系统概述253
11.1.1 input_dev结构253
11.1.2 输入事件255
11.2 input_handler256
11.2.1 Input Handler层256
11.2.2 常用的Input Handler259
11.3 输入设备应用层261
11.4 键盘输入设备驱动程序实例262
11.5 event接口267
11.6 触摸屏驱动程序实例270
11.6.1 S3C6410触摸屏控制器270
11.6.2 S3C6410触摸屏驱动程序设计273
11.7 触摸屏校准282
11.7.1 触摸屏校准原理282
11.7.2 利用TSLIB库校准触摸屏282
第12章 USB驱动程序284
12.1 USB体系概述284
12.1.1 USB系统组成284
12.1.2 USB主机284
12.1.3 USB设备逻辑层次285
12.2 Linux USB驱动程序体系287
12.2.1 USB总体结构287
12.2.2 USB设备驱动程序287
12.2.3 主机控制器驱动程序288
12.2.4 USB请求块urb289
12.2.5 USB请求块的填充291
12.3 S3C6410 USB主机控制器驱动程序292
12.3.1 USB主机控制器驱动程序分析292
12.3.2 S3C6410 USB驱动程序加载294
12.4 USB键盘设备驱动程序分析296
12.5 USB Gadget驱动程序301
12.5.1 Linux USB Gadget驱动程序301
12.5.2 Linux USB Gadget驱动程序实例302
第13章 音频设备驱动程序303
13.1 ALSA音频体系303
13.2 ALSA驱动层API304
13.2.1 声卡和设备管理304
13.2.2 PCM API304
13.2.3 控制与混音API305
13.2.4 AC97 API306
13.2.5 SOC层驱动307
13.3 ALSA驱动程序实例308
13.3.1 S3C6410的AC97控制单元308
13.3.2 S3C6410声卡电路原理309
13.3.3 S3C6410的数字音频接口310
13.3.4 wm9713的数字音频接口313
13.4 ALSA音频编程接口316
13.4.1 ALSA PCM接口实例316
13.4.2 ALSA MIDI接口实例320
13.4.3 ALSA mixer接口实例321
13.4.4 ALSA timer接口实例322
第14章 video4linux2视频驱动程序327
14.1 video4linux2驱动程序架构327
14.1.1 video4linux2驱动程序的注册327
14.1.2 v4l2_fops接口331
14.1.3 常用的结构332
14.1.4 video4linux2的ioctl函数333
14.2 S3C6410摄像头驱动程序分析333
14.2.1 电路原理333
14.2.2 驱动程序分析334
14.3 video4linux2应用层实例339
第15章 SD卡驱动程序346
15.1 Linux SD卡驱动程序体系346
15.1.1 SD卡电路原理346
15.1.2 MMC卡驱动程序架构347
15.1.3 MMC卡驱动程序相关结构347
15.1.4 MMC卡块设备驱动程序350
15.1.5 SD卡主机控制器接口驱动程序356
15.2 S3C6410 SD卡控制器驱动程序分析360
15.2.1 电路原理360
15.2.2 S3C6410 SDHCI驱动程序原理360
15.2.3 SD卡的加载实例364
参考文献366
精彩书摘
在Linux操作系统中,设备驱动程序对各种设备提供了一致的访问接口,用户程序可以像对普通文件一样对设备文件进行打开和读写操作。Linux包含如下3类设备驱动程序:
(1)字符设备
Linux下的字符设备是指发送和接收数据以字符的形式进行的设备。字符设备接口支持面向字符的I/O操作,不经过系统的快速缓存,所以它们负责管理自己的缓冲区结构。字符设备接口只支持顺序存取的有限长度的I/O操作,典型的字符设备包括串行接口、LED灯、键盘等设备。
(2)块设备
块设备是以块的方式进行I/0操作的设备。块设备利用一块系统内存作缓冲区,如果用户进程对设备的请求能满足用户的要求,就返回请求的数据,否则调用请求函数来进行实际的I/O操作。块设备主要是针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待响应。块设备支持随机存取功能,几乎可以支持任意位置和任意长度的I/O请求。典型的块设备包括硬盘、CF卡、SD卡等存储设备。
(3)网络设备
Linux操作系统中的网络设备是一类特殊的设备。Linux的网络子系统主要基于BSDUNIX的socket机制,在网络子系统和驱动程序之间定义有专门的数据结构(skbuff)进行数据的传递。Linux操作系统支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多种网络协议的支持。
Linux系统为每个设备分配了一个主设备号与次设备号,主设备号唯一地标识了设备类型,次设备号标识具体设备的实例。由同一个设备驱动程序控制的所有设备具有相同的主设备号,从设备号则被用来区分具有相同主设备号的不同设备。
前言/序言
深入浅出,玩转Linux内核:掌握驱动程序开发的必备利器 这是一本为有志于深入Linux系统底层、掌握硬件控制精髓的开发者量身打造的实战指南。本书并非仅停留在理论的堆砌,而是以大量详实、可运行的驱动程序开发实例为载体,带您一步步解锁Linux内核的奥秘,从基础概念到高级特性,无不涵盖。我们将一起探索Linux驱动程序开发的方方面面,让您能够独立开发、调试,乃至优化各种硬件设备的驱动程序,成为一名合格的Linux驱动工程师。 为何选择Linux驱动开发? 在当今高度互联的物联网、嵌入式系统以及服务器领域,Linux的统治地位毋庸置疑。而驱动程序,作为连接硬件与操作系统的桥梁,其重要性不言而喻。掌握Linux驱动开发,意味着您拥有了直接与硬件交互的能力,能够为各种嵌入式设备、外围设备、高性能计算硬件等开发定制化的驱动,实现硬件功能的充分挖掘和性能优化。这不仅是技术深度的体现,更是解决实际工程问题的关键所在。 本书将带您领略怎样的精彩旅程? 本书内容详实,结构清晰,从入门到精通,层层递进,力求为读者提供一个全面且深入的学习体验。 第一篇:驱动开发基石——构建坚实基础 Linux内核概览与开发环境搭建: 我们将从宏观角度审视Linux内核的整体架构,理解其模块化设计以及内核空间与用户空间的概念。在此基础上,详细指导您如何搭建一套完整的Linux内核开发环境,包括交叉编译工具链的配置、内核源码的获取与编译,以及虚拟机环境的部署,确保您能够顺利地进行后续的驱动开发实践。 Linux内核模块编程基础: 内核模块是Linux驱动程序最常见的载体。本章将深入讲解内核模块的生命周期管理(加载、卸载)、符号导出与导入机制、以及模块参数的设置。您将学习如何编写简单的“Hello, World!”内核模块,并理解其工作原理。 Linux内核对象与数据结构: 了解内核常用的数据结构,如链表(list_head)、队列(kfifo)、原子操作(atomic_t)以及自旋锁(spinlock_t)、信号量(semaphore)等同步原语,是编写健壮驱动程序的基础。我们将通过实例演示这些数据结构的实际应用,帮助您编写高效且线程安全的代码。 内存管理与页分配: 驱动程序经常需要动态地分配和管理内存。本章将详细介绍Linux内核的内存管理机制,包括物理内存分配(kmalloc, vmalloc)、伙伴系统(buddy system)、 slab 分配器等,并阐述如何安全有效地使用这些内存分配函数。 中断处理机制: 中断是硬件与CPU通信的重要方式。我们将深入讲解中断的产生、中断控制器的工作原理、中断处理函数的编写与注册,以及中断共享等高级话题。通过实际的按键中断、定时器中断实例,您将完全掌握中断处理的精髓。 定时器与延迟: 在驱动开发中,精确的定时和延时控制至关重要。本章将介绍内核提供的各种定时器(timer_list)和延迟函数(udelay, mdelay, ssleap_delay),并给出相应的应用实例,例如周期性任务的调度和硬件操作的时序控制。 第二篇:核心驱动技术——掌握关键技能 字符设备驱动开发: 字符设备是Linux中最基础的设备类型。我们将从零开始,一步步构建一个完整的字符设备驱动,包括设备号的分配、cdev结构体的注册、file_operations结构体的实现(open, read, write, ioctl等操作),并演示如何在用户空间通过系统调用访问该设备。 块设备驱动开发: 块设备(如硬盘、U盘)的驱动开发相对复杂,涉及到磁盘调度、I/O请求的处理等。本章将介绍块设备驱动的基本框架,包括request_queue的创建、blk_init_queue的注册,以及处理read/write请求的通用块层(generic block layer)的工作机制。 网络设备驱动开发: 在连接无处不在的今天,网络设备驱动的开发显得尤为重要。我们将深入理解网络接口(net_device)的结构体,学习如何实现数据包的发送(ndo_start_xmit)和接收(NAPI),以及网卡设备的初始化和配置。 I2C、SPI、I2S等总线驱动: 许多嵌入式设备通过I2C、SPI、I2S等总线进行通信。本章将重点讲解这些总线协议的工作原理,并提供相应的驱动开发实例,例如控制传感器、显示器等外围设备。 USB设备驱动开发: USB作为一种通用的外部设备接口,其驱动开发具有广泛的应用前景。我们将深入分析USB协议栈,学习USB设备枚举、接口描述、端点(endpoint)的配置,以及URB(USB Request Block)的创建和管理,并开发一个简单的USB设备驱动。 PCI/PCIe设备驱动开发: 对于高性能硬件,PCI/PCIe接口扮演着关键角色。本章将介绍PCI/PCIe设备的配置空间访问、内存映射I/O(MMIO)、中断处理,以及DMA(Direct Memory Access)技术的应用,帮助您开发高效的PCI/PCIe设备驱动。 第三篇:高级驱动技巧与实践——提升工程能力 Linux设备模型(Device Model): 设备模型是Linux内核组织和管理设备的一种强大机制。我们将深入理解kobject、kset、device、driver等核心概念,学习如何利用设备模型统一管理设备资源,实现驱动与设备的解耦。 设备树(Device Tree): 在现代嵌入式Linux系统中,设备树扮演着越来越重要的角色。本章将详细讲解设备树的语法、节点的表示方法,以及如何编写和解析设备树来描述硬件平台。您将学习如何将设备树与驱动程序相结合,实现硬件无关性。 驱动程序的调试与性能优化: 调试是驱动开发过程中不可或缺的一环。我们将介绍内核调试工具(如printk、dynamic debug、ftrace、kdb/kgdb),以及如何利用这些工具定位和解决驱动程序中的bug。同时,还将探讨常见的驱动性能瓶颈,并提供相应的优化策略。 Power Management(电源管理): 在功耗敏感的设备中,电源管理至关重要。本章将介绍Linux内核的电源管理框架,包括runtime PM、system suspend/resume等,并指导您如何为驱动程序实现电源管理功能。 用户空间与内核空间的交互(ioctl,procfs,sysfs): 驱动程序需要与用户空间应用程序进行交互。本章将深入讲解ioctl系统调用、procfs文件系统的创建与使用、sysfs文件系统的动态创建与属性管理,让您能够设计灵活高效的接口。 嵌入式Linux开发实战: 结合具体的嵌入式硬件平台(如ARM架构开发板),我们将通过多个完整的驱动开发项目,将前面所学的知识融会贯通。从简单的GPIO控制到复杂的传感器驱动,再到网络通信模块,让您在实践中巩固技能,提升解决实际问题的能力。 谁适合阅读本书? C语言熟练的嵌入式开发者: 如果您熟悉C语言,并且对嵌入式系统有浓厚兴趣,希望深入了解Linux内核的工作原理。 Linux系统管理员或工程师: 希望进一步提升Linux系统底层的理解深度,能够独立开发或维护硬件驱动。 计算机科学、电子工程等相关专业的学生: 对操作系统原理、计算机体系结构有深入学习需求,希望通过实践掌握Linux驱动开发。 物联网(IoT)开发者: 需要为各种传感器、执行器、通信模块开发定制化的Linux驱动。 对Linux内核刨根问底的技术爱好者: 想要揭开Linux内核神秘面纱,掌握与硬件交互的终极能力。 本书的独特价值 本书最大的亮点在于其丰富的实战案例。我们精选了大量在实际开发中常见且有代表性的驱动程序实例,并提供了完整的源代码,保证读者能够直接上手编译、运行和调试。这些案例涵盖了多种硬件接口和通信协议,能够满足不同领域开发者的需求。 此外,本书注重理论与实践的结合,在讲解每一个技术点时,都辅以相应的代码示例,帮助读者将抽象的概念转化为具体的实现。我们力求用最清晰易懂的语言,将复杂的内核机制娓娓道来。 开启您的Linux驱动开发之旅 掌握Linux驱动开发,就是掌握了与硬件直接对话的能力。本书将为您铺就一条通往Linux内核深处的道路,让您能够自信地面对各种硬件挑战,开发出高性能、高可靠性的驱动程序。立即开始,与我们一同踏上这场激动人心的Linux驱动开发之旅吧!