第1课.Linux驱动的概述
1.应用程序,库,内核,驱动程序的关系
(1).应用程序使用库提供的接口函数(open,read,write,ioctl等)函数可以打开设备文件
(2).库根据open函数传入的参数执行“swi”指令,这条指令会引起CPU异常,进入内核。
(3).内核的异常处理函数根据这些参数找到相应的驱动程序,返回一个文件句柄,进而返回给应用程序
(4).应用程序得到文件句柄后,使用库提供的write或ioctl函数发出指令控制
(5).库根据write或ioctl函数传入的参数执行"swi"指令,这条指令会引起CPU异常,进入内核。
(6).内核的异常处理函数根据这些参数调用驱动程序的相关函数
2.Linux驱动程序分类
Linux的外设可以分为3类:字符与设备(character device),块设备(block device)和网络接口(network interface)
字符设备
字符设备是能够像字节流(比如文件)一样被访问的设备,就是说对它的读写是以字节为单位的。
应用程序可以通过设备文件(比如:/dev/ttySAC0)来访问字符设备
块设备
块设备上的数据以块的形式进行存放,比如NAND FLASH上的数据就是以页为单位存放的
字符设备和块设备的访问方式没有差别
块设备和字符设备的区别
(1).操作硬件的接口实现方式不一样
块设备驱动程序先将用户发来的数据组织成块,在写入设备;或从设备中读出若干块数据,在从中挑选出用户需要的
(2).数据块上的数据可以有一定的格式
通常在块设备中按照一定的格式存放数据,不同的文件系统类型就是用来定义这些格式的。内核中,文件系统的层次位与块设备驱动程序的上面,这意味着块设备驱动程序除了向用户层提供与字符设备一样的接口外,还要向内核其他部件提供一些接口,这些接口用户是看不到的。这些接口是的可以在块设备上存放文件系统,挂载(mount)块设备
网络接口
网络接口同时具有字符设备,块设备的部分特点。
它的输入/输出是有结构的,成块的(报文,包,帧);如果说它是块设备,它的"块"又不是固定大小的,大到数百甚至数千字节,小到几字节。unix式的操作系统访问网络接口的方法是给它们分配一个唯一的名字(比如eth0),但这个名字在文件系统中(比如/dev目录下)不存在对应的节点项。库、内核提供了一套和数据包传输相关的函数,而不是open,read,write等
3.Linux驱动的开发流程
1).查看原理图、数据手册,了解设备的操作方法
2).在内核中找到相近的驱动程序,以它为模板进行开发,有时候需要从零开始
3).实现驱动程序的初始化:比如向内核注册这个驱动程序,这样应用程序传入文件名是,内核才能找到相应的驱动程序
4).设计所要实现的操作:比如open,close,read,write等函数
5).实现中断服务函数(中断并不是每一个设备驱动所必须的)
6).编译该驱动程序到内核中,或者用insmod命令加载
7).测试驱动程序
4.驱动程序的加载和卸载
在2.6的内核中,模块的扩展名为.ko,可以使用insmod命令加载,使用rmmod命令卸载,使用lsmod命令查看内核中已经加载了哪些模块。
insmod:加载模块时,模块的初始化函数被调用。它用来向内核注册驱动程序;
rmmod: 卸载模块时,模块的清楚函数被调用。
某个配置项设为m,就表示它将会被编译成一个模块。
某个配置项设为y,就表示它将会被编进内核。
5.一些常用命令
mknod file c major cnt #手动创建字符设备
rmmod file #卸载驱动
insmod file #安装驱动
mount -t nfs -o nolock 192.168.5.22:/home/book/stw /mnt #手动挂载nfs
cat /proc/devices #查看安装的设备和其设备号