linux驱动开发详解——宋宝华 笔记

linux驱动开发详解————宋宝华 笔记
1.udev负责捕获内核发送的uevent事件,进行规则匹配生成删除设备文件,比devfs区别是将设备的增加删除交给应用程序,而不是给内核
2.字符设备驱动cdev_add()函数和cdev_del()函数分别向系统添加和删除一个cdev,完成字符设备的注册和注销,在字符设备驱动模块加载函数中应该实现设备号的申请和cdev的注册,而在卸载函数中应实现设备号的释放和cdev的注销。
3.file_operations结构体中的成员函数是字符设备驱动与内核虚拟文件系统的接口,由于用户空间不能直接访问内核空间的内存,因此借助了函数copy_from_user()完成用户空间缓冲区到内核空间的复制,以及
copy_to_user()完成内核空间到用户空间缓冲区的复制
4.访问共享资源的代码区域称为临界区(Critical Sections),临界区需要被以某种互斥机制加以保护。中断屏蔽、原子操作、自旋锁、
信号量、互斥体等是Linux设备驱动中可采用的互斥途径。
5.在自旋锁锁定期间不能调用可能引起进程调度的函数。如果进程获得自旋锁之后再阻塞,如调用copy_from_user()、
copy_to_user()、kmalloc()和msleep()等函数,则可能导致内核的崩溃。
6.互斥体是进程级的,用于多个进程之间对资源的互斥,虽然也是在内核中,但是该内核执行路径是以进程的身
份,代表进程来争夺资源的。如果竞争失败,会发生进程上下文切换,当前进程进入睡眠状态,CPU将运行其
他进程。鉴于进程上下文切换的开销也很大,因此,只有当进程占用资源时间较长时,用互斥体才是较好的选
择。当所要保护的临界区访问时间比较短时,用自旋锁是非常方便的,因为它可节省上下文切换的时间。但是CPU
得不到自旋锁会在那里空转直到其他执行单元解锁为止,所以要求锁不能在临界区里长时间停留,否则会降低
系统的效率。
7.  由此,可以总结出自旋锁和互斥体选用的3项原则。
    1)当锁不能被获取到时,使用互斥体的开销是进程上下文切换时间,使用自旋锁的开销是等待获取自旋锁(由
    临界区执行时间决定)。若临界区比较小,宜使用自旋锁,若临界区很大,应使用互斥体。
    2)互斥体所保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界
    区。因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图获取本自旋锁,死锁就会发
    生。
    3)互斥体存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断情况下使用,则在互斥体和自
    旋锁之间只能选择自旋锁。当然,如果一定要使用互斥体,则只能通过mutex_trylock()方式进行,不能获取就
    立即返回以避免阻塞
8 并发和竞态广泛存在,中断屏蔽、原子操作、自旋锁和互斥体都是解决并发问题的机制。中断屏蔽很少单独被
使用,原子操作只能针对整数进行,因此自旋锁和互斥体应用最为广泛。
自旋锁会导致死循环,锁定期间不允许阻塞,因此要求锁定的临界区小。互斥体允许临界区阻塞,可以适用于
临界区大的情况。
10.Linux设备中的并发控制有中断屏蔽、原子操作、自旋锁、读写锁、RCU锁、互斥量;
11.通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问,select()和poll()系统调用的本质一样,前者在BSD UNIX中引入,后者在System V中引入.
当多路复用的文件数量庞大、I/O流量频繁的时候,一般不太适合使用select()和poll(),此种情况下,select()和poll()的
性能表现较差,我们宜使用epoll。epoll的最大好处是不会随着fd的数目增长而降低效率,select()则会随着fd的数量增大性能下
降明显。
12.Linux中的异步I/O:使用信号可以实现设备驱动与用户程序之间的异步通知,总体而言,设备驱动和用户空间要分别完成3项对应的
工作,用户空间设置文件的拥有者、FASYNC标志及捕获信号,内核空间响应对文件的拥有者、FASYNC标志的
设置并在资源可获得时释放信号。
13.在Linux 2.6以后的设备驱动模型中,需关心总线、设备和驱动这3个实体,总线将设备和驱动绑定。在系统每注
册一个设备的时候,会寻找与之匹配的驱动;相反的,在系统每注册一个驱动的时候,会寻找与之匹配的设
备,而匹配由总线完成
14.现在我们将前面章节的globalfifo驱动挂接到platform总线上,这要完成两个工作。
1)将globalfifo移植为platform驱动。注册完globalfifo对应的platform_driver后,我们会发现/sys/bus/platform/drivers目录下多出了一个名字叫globalfifo的子目录。
static struct platform_driver globalfifo_driver = {
 .driver = {
 .name = "globalfifo",
 .owner = THIS_MODULE,
 },
 .probe = globalfifo_probe,
 .remove = globalfifo_remove,
};
2)在板文件中添加globalfifo这个platform设备。会在/sys/devices/platform目录下看到一个名字叫globalfifo的子目录,/sys/devices/platform/globalfifo中会有一个driver文件,它是指向/sys/bus/platform/drivers/globalfifo的符号链接,
static struct platform_device globalfifo_device = {
 .name = "globalfifo",
 .id = -1,
};

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux设备驱动详解【第二版】,作者宋宝华,此版PDF是经过本人整理的文字版PDF,带目录、高清无水印版。 内容简介 《Linux设备驱动开发详解(第《Linux设备驱动开发详解(第2版)》内容全面,实例丰富,操作性强,语言通俗易懂,适合广大Linux开发人员、嵌入式工程师参考使用。 图书目录 第1篇 Linux设备驱动入门 第1章 Linux设备驱动概述及开发环境构建 2 第2章 驱动设计的硬件基础 21 第3章 Linux内核及内核编程 53 第2篇 Linux设备驱动核心理论 第4章 Linux内核模块 82 第5章 Linux文件系统与设备文件系统 92 第6章 字符设备驱动 118 第7章 Linux设备驱动中的并发控制 139 第8章 Linux设备驱动中的阻塞与非阻塞I/O 161 第9章 Linux设备驱动中的异步通知与异步I/O 176 第10章 中断与时钟 193 第11章 内存与I/O访问 213 第12章 工程中的Linux设备驱动 242 第3篇 Linux设备驱动实例 第13章 Linux设备驱动 272 第14章 Linux终端设备驱动 304 第15章 Linux的I2C核心、总线与设备驱动 333 第16章 Linux网络设备驱动 363 第17章 Linux音频设备驱动 388 第18章 LCD设备驱动 440 第19章 Flash设备驱动 479 第20章 USB主机与设备驱动 507 第21章 PCI设备驱动 547 第4篇 Linux设备驱动调试、移植 第22章 Linux设备驱动的调试 564 第23章 Linux设备驱动的移植 602
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值