所有drv_xxx均出自于《Linux设备驱动开发详解:基于最新的Linux 4.0内核.pdf》
对应关系: drv_hello "第4章 Linux内核模块简介-P93(右上方页码)" Notes: make 编译模块 sudo insmod drv_hello.ko 加载模块 sudo rmmod drv_hello 卸载模块 dmesg 查看系统日志 总结: "第1章 Linux设备驱动概述及开发环境搭建": 描述了无操作系统下的驱动框架,以及简述了Linux下驱动开发框架、搭建 驱动开发的环境
“第2章 驱动设计的硬件基础”:
简单讲解了驱动软件工程师必备的硬件基础只知识,描述了处理器、存储器的分类
以及各种处理器、存储器的原理与用途,并分析了常见的外围设备接口与总线的工作方式。
此外,本章还讲解了对驱动工程师进行实际项目开发有帮助的原理图、硬件时序分析方法,
芯片手册阅读方法以及万用表、示波器和逻辑分析仪的使用方法
“第3章 Linux内核及内核编程”
讲解了Linux内核和Linux内核编程的基础知识,为读者进行Linux驱动开发打下软件基础。
在Linux内核方面,主要介绍了Linux内核的发展史、组成、特点、源代码结构、内核编译方法及
内核引导过程。
由于Linux驱动编程本质属于内核编程,因此掌握内核编程的基础知识显得尤为重要。本章介绍了
在这方面在内核中新增程序、目录和编写Kconfig和Makefile的方法,并分析了Linux下C编程习惯以及
Linux所使用的GNU C针对标准C的扩展语法。
drv_hello_param
"第4章 Linux内核模块简介-P98(左上方页码)"
总结:
本章主要讲解Linux内核模块的概念和基本的编程方法。内核模块由加载/卸载函数、功能函数以及
一系列声明组成,它可以被传入参数,也可以导出符号供其他模块使用
由于Linux设备驱动以内核模块的形式存在,因此,掌握这一章的内容是编写任何设备驱动的必需。
drv_globalmem
“第6章 字符设备驱动-P149(右上方页码)”
Notes:
第5章 主要描述udev还有就是bus下的driver和device
mknod /dev/globalmem c 230 0 创建设备节点
echo "hello world" > /dev/globalmem 将“hello world”写入/dev/globalmem设备节点
cat /dev/globalmem 查看/dev/globalmems设备节点的内容
总结:
"第5章 Linux文件系统与设备文件"
Linux用户空间的文件编程有两种方法,即通过Linux API和通过C库函数访问文件。
用户空间看不到设备驱动,能看到的只有与设备对应的文件,因此文件编程也就是用户空间的设备编程。
Linux按照功能对文件系统的目录结构进行了良好的规划。/dev是设备文件的存放目录,devfs和udev分别是
Linux2.4和Linux2.6以后的内核生产设备节点的方法,前者运行于内核空间,后者运行于用户空间。
Linux2.6以后的内核通过一系列数据结构定义了设备模型,设备模型与sysfs文件系统中的目录和文件存在一种
对应关系。设备和驱动分离,并通过总线进行匹配。
udev可以利用内核通过netlink发出的uevent信息动态创建设备文件节点
"第6章 字符设备驱动"
字符设备是3大类设备(字符设备、块设备、和网络设备)中的一类,其驱动程序完成的主要工作是初始化、
添加和删除cdev结构体,申请和释放设备号,以及填充file_operations结构体中的操作函数,实现file_operations
结构体中的read()、write()、ioctl等函数是驱动设计的主体工作。
drv_globalmen_multidev
“第6章 字符设备驱动-P155(右上方页码)”
drv_globalmem_mutex、
“第7章 Linux设备驱动中的并发控制-P185(右上方页码)””
总结:
“第7章 Linux设备驱动中的并发控制”
Linux提供了多种解决静态问题的方式,这些方式合适不同的应用场景。
7.1节讲解了并发和竞态的概念及发生场合;
7.2节讲解了编译乱序、执行乱序的问题,以及内存屏障;
7.3节~7.8节分别讲解了中断屏蔽、原子操作、自旋锁、信号量和互斥体等并发控制机制;
7.9节讲解增加并发控制后globalmem的设备驱动;
并发和竞态广泛存在,中断屏蔽、原子操作、自旋锁和互斥体都是解决并发问题的机制。
中断屏蔽很少被单独使用,原子操作只能针对整数进行,因此自旋锁和互斥体应用最为广泛。
自旋锁会导致死循环,锁定期间不允许阻塞,因此要求锁定的临界区小。互斥体允许临界区阻塞,
可以适用于临界区大的情况
drv_globalfifo
“第8章 Linux设备驱动中的阻塞与非阻塞I/O-P194(左上方页码)”
总结:
8.1节讲述了阻塞与非阻塞I/O的区别,并讲解了实现阻塞I/O的等待队列机制,以及在globalfifo
设备驱动中增加对阻塞I/O支持的方法,并进行了用户空间的验证。
8.2节讲述了设备驱动轮询(Poll)操作的概念和编程方法,轮询可以帮助用户连接是否能对设备进行
无阻塞访问
8.
阻塞与非阻塞访问都是I/O操作的两种不同模式,前者在暂时不进行I/O操作时会让进程睡眠,后者
则不然。
在设备驱动中阻塞I/O一般基于等待队列或者等待队列的其他Linux内核API来实现,等待队列可用于
同步驱动中事件发生的先后顺序。使用非阻塞I/O的应用程序也可借助轮询函数来查询设备是否能够立即被访问,
用户空间调用select()、poll()或者epoll()接口,设备驱动提供poll()函数。设备驱动的poll()本身不会阻塞,
但是与poll()、select()、epoll()相关的系统调用则会阻塞地等待一个文件描述符集合可访问或超时。
drv_globalfifo_poll
“第8章 Linux设备驱动中的阻塞与非阻塞I/O-P202(左上方页码)”
drv_globalfifo_signal
“第9章 Linux设备驱动中的异步通知与异步I/O-P212(左上方页码)”
书中漏掉了一些东西导致没办法实现它的结果
.fasync = globalfifo_fasync,
总结:
“第9章 Linux设备驱动中的异步通知与异步I/O”
在设备驱动中使用异步通知可以使得在进行对设备的访问时,由驱动程序
主动通知应用程序进行访问。这样,使用非阻塞I/O的应用程序无须轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代。
除了异步通知以外,应用还可以在发起I/O请求以后,立即返回。之后,再
查询I/O完成情况,或者I/O完成后被调回。这个过程叫作异步I/O。
9.1节讲解了异步通知的编程方法
9.2节讲解了Linux异步通知的编程方法
9.3节给出了增加异步通知的globalfifo驱动及其再用户空间的验证
9.4节讲解了Linux基于C库的异步I/O和内核本身的异步I/O的用户空间
编程接口,以及驱动如何支持AIO
使用信号可以实现设备驱动于用户程序之间的异步通知,总体而言,设备驱动和用户空间要分别完成3项对应的工作,用户空间设置文件的
拥有者、FASYNC标志及捕获信号,内核空间空间响应文件的拥有者、FASYNC标志的设置并在资源可用的时候释放信号。
Linux2.6以后的内核包含对AIO的支持,它为用户空间提供了统一的异步I/O接口。另外,glibc也提供了一个不依赖于内核的用户空间AIO支持;
drv_globalfifo_aio
"第9章 Linux设备驱动中的异步通知与异步I/O-P215(右上方页码)"
aio适用于块设备、网卡设备,字符设置是一般不需要实现AIO的支持,主要优化吞吐量等优势;
drv_second_timer
“第10章 中断与时钟-P243(右上方页码)”
编译时会init_timer会报错
总结:
"第10章 中断与时钟"
本章主要讲解Linux设备驱动编程中的中断与定时器处理。由于中断服务程序的执行并不存在于进程上下文中,所以要求中断服务程序的时间
要尽量短。因此,Liunx在中断处理中引入了顶半部和底半部的机制。另外,内核对时钟的处理也采用中断方式,而内核软件定时器最终依赖于
时钟中断。
10.1节讲解中断与定时器的概念及处理流程;
10.2节讲解Linux中断处理程序的框架,以及顶半部、底半部之间的关系;
10.3节讲解Linux中断编程的方法,涉及申请和释放中断、使能和屏蔽中断以及中断底半部tasklet、工作队列、软中断机制和threaded_irq;
10.4节讲解多个设备共享同一中断号时的中断处理过程;
10.5节和10.6节分别讲解Linux设备驱动编程中定时器的编程以及内核延时的方法;
Linux的中断处理分为两个半部,顶半部处理紧急的硬件操作,底半部处理不紧急的耗时操作。tasklet和工作队列都是调度中断底半部的良好机制,
tasklet基于软中断实现。内核定时器也依靠软中断实现。
内核中的延时可以采用忙等待或睡眠等待,为了充分利用CPU资源,使系统有更好的吞吐性能,在对延迟时间的要求并不是很精确的情况下,睡眠等待
是值得推荐的,而ndelay()、udelay()忙等待机制在驱动中通常是为了配合硬件上的短时延要求。
“第11章 内存与I/O访问”
由于Linux系统提供了复杂的内存地址管理功能,所以内存的概念在Linux系统中相对复杂,有常规内存、高端内存、虚拟地址、逻辑地址、物理地址、
I/O内存、设备内存、预留内存等概念。本章将系统地讲解内存和I/O的访问编程,带读者作出内存和I/O的概念迷宫。
11.1节讲解内存和I/O的硬件机制,主要涉及内存空间、I/O空间和MMU。
11.2节讲解Linux的内存管理、内存区域的分布、常规内存与高端内存的区别。
11.3节讲解Linux内存存取的方法,主要涉及内存动态申请以及通过虚拟地址存取物理地址的方法。
11.4节讲解设备I/O端口和I/O内存的访问流程,这一节对于编写设备驱动的意义非常重大,设备驱动使用此节的方法访问物理设备。
11.5节讲解I/O内存静态映射。
11.6节讲解设备驱动中的DMA与Cache一致性问题以及DMA的编程方法。
已读到 271页(文档页数,并不是书的页码)