Linux的驱动开发分析

时间:2022-10-19 10:45:32

Linux的驱动开发分析

摘 要:本文分析了linux下的驱动开发,对原理进行了分析,详细描述了IO结构,并对填充实例进行了详细分析。

关键词:嵌入式;系统开发;驱动

Linux由于具有内核强大且稳定,易于扩展和裁减,效率高,丰富的硬件支持等许多优点,在嵌人式系统中得到了广泛的应用。本文基于嵌人式操作系统下设备驱动程序的开发需要,阐述相关技术原理及设计要点,探求嵌人式Linux系统中设备驱动程序的构建方法。

1 嵌入式Linux系统驱动

嵌入式Linux系统中的设备驱动程序和Linux中的大多数驱动程序一样,也是采用层次型的体系结构。编写设备驱动程序,其主要工作就是编写子函数,并填充file_operations的各个域。Linux的设备驱动程序模块按照方式编译可以分为两类。

一类是静态链接的设备驱动程序模块,这类模块在编制完成后要与内核一起编译,其与内核是不可分割的整体,在系统引导时与内核一起加载并驻留内存。

另一类设备驱动程序采用可动态加载的模块。其驱动程序代码在使用之前动态地加载到内存中,在设备使用完毕后即从内存中移去其代码。

嵌入式Linux系统往往应用环境相对固定,系统都经过优化,尽可能地精简。嵌入式Linux系统不能够像桌面Linux那样灵活地使用insmod/rmmod加载卸载设备驱动程序。从嵌入式系统的整体性能考虑,采用静态链接模块能够使得整个系统的性能得到提高。许多广泛应用的嵌入式Linux系统都采用静态链接的设备驱动程序模块。

2 驱动程序原理

编写设备驱动程序的原理即基于I/O设备管理采用的分层模型,l/O设备管理软件位于内核中的最底层,设备驱动程序是操作系统内核和机器硬件之间的接El,设备驱动程序为应用程序屏蔽了硬件的细节。硬件设备只是一个设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作。

⑴工作原理。作为内核的一部分,设备驱动程序完成对设备初始化和释放、把数据从内核传送到硬件和从硬件读取数据、读取应用程序传送给设备文件的数据和回送应用程序请求的数据和检测处理设备出现的错误的功能。Linux设备主要分两类:字符设备和块设备,其主要区别是:在对字符设备发出读/写请求时,实际的硬件1/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作为高速缓存,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的l/O操作。

⑵I/O接口。逻辑l/O层通过内核定义的两个数据结构块设备转换表(blkdevs)和字符设备转换表(chrdevs)来实现与设备驱动程序的接口。每个设备驱动程序在设备转换表中占据一个表项。每个Linux设备文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备。用户进程利用系统调用在对设备文件进行read/write等各种操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取数据结构相应的函数指针,接着把控制权交给函数。

3 实例分析

编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域,以下为驱动程序test.c的主要内容。函数read_test()是为read调用准备的。当调用read时,read_test()被调用,它把用户的缓冲区全部写1。函数中的bur是read调用的一个参数,是用户进程空间的一个地址。但是在read_test()被调用时,系统进入核心态,所以不能使用bur这个地址,必须用put_user(),这是kernel提供的一个函数,用于向用户传送数据。

unsigned int test_major = 0;

static int read_test(struct inode* node, struct file *file, char *bur, int count)

{ int left;

if(verify_area(VERIFY_WRITE, bur, count) = = -EFAULT )

return EFAULT;

for(1eft = count; left > 0; left--)

{ __put_user(1, bur, 1);

bur ;}

return count;}

以下是驱动程序下半部分的其他几个函数。

static int write_tibet(struct inode inode, struct file *file, const char *bur, int count)

{return count;}

static int open_tibet(struct inode *inode, struct file *file)

{MOD-INC-USE-COUNT;

return 0;}

static void release_tibet(struct inode *inode, struct file *file)

{MOD-DEC-USE-COUNT;}

4 总结

论文对linux的驱动开发进行了分析,指出了其开发原理以及加载方式的分类,并且以实例进行了说明。

[参考文献]

[1]周明德.UNIX/Linux内核[M].北京:清华大学出版社,2004.

[2]倪继利.Linux内核分析及编程[M].北京:电子工业出版社,2005.1.

上一篇:试论土地登记制度的改革与问题 下一篇:高校学生质量评价初探