三九宝宝网宝宝教育计划总结

如何编写一个简单的linux内核模块和设备驱动程序

02月13日 编辑 39baobao.com

[怎样在PC上使用PS3游戏手柄并正确安装驱动程序]安装过程和普通的电脑上手柄驱动没什么区别,类似于接入外设自动搜索驱动并安装下载,你只要将PS3连接USB数据线接入电脑,等待正确安装驱动程序就可以搜索到PS3手柄了。 如果不能...+阅读

Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖kernel中的函数,有些常用的操作要自己来编写,而且调试也不方便。以下的一些文字主要来源于khg,johnsonm的Write linux device driver,Brennan's Guide to Inline Assembly,The Linux a-z,还有清华bbs上的有关device driver的一些资料。

一、Linux device driver 的概念 系统调用是操作系统内核和应用程序之间的接口,设备62616964757a686964616fe78988e69d8331333339653737驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能:

1、对设备初始化和释放。

2、把数据从内核传送到硬件和从硬件读取数据。

3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据。

4、检测和处理设备出现的错误。 在Linux操作系统下有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待。 已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序。 最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。 读/写时,它首先察看缓冲区的内容,如果缓冲区的数据未被处理,则先处理其中的内容。 如何编写Linux操作系统下的设备驱动程序

二、实例剖析 我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理。把下面的C代码输入机器,你就会获得一个真正的设备驱动程序。#define __NO_VERSION__ #include #include char kernel_version [] = UTS_RELEASE; 这一段定义了一些版本信息,虽然用处不是很大,但也必不可少。Johnsonm说所有的驱动程序的开头都要包含,一般来讲最好使用。 由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构: struct file_operations { int (*seek) (struct inode * ,struct file *, off_t ,int); int (*read) (struct inode * ,struct file *, char ,int); int (*write) (struct inode * ,struct file *, off_t ,int); int (*readdir) (struct inode * ,struct file *, struct dirent * ,int); int (*select) (struct inode * ,struct file *, int ,select_table *); int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long); int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *); int (*open) (struct inode * ,struct file *); int (*release) (struct inode * ,struct file *); int (*fsync) (struct inode * ,struct file *); int (*fasync) (struct inode * ,struct file *,int); int (*check_media_change) (struct inode * ,struct file *); int (*revalidate) (dev_t dev); } 这个结构的每一个成员的名字都对应着一个系统调用。用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。 下面就开始写子程序。 #include #include #include #include#include #includeunsigned int test_major = 0; static int read_test(struct inode *node,struct file *file,char *buf,int count){ int left; if (verify_area(VERIFY_WRITE,buf,count) == -EFAULT ) return -EFAULT; for(left = count ; left >0 ; left--) { __put_user(1,buf,1); buf++; } return count; } 这个函数是为read调用准备的。当调用read时,...

以下为关联文档:

总结编译linux内核的步骤是什么实,通常其它操作系统的内核编译是比较繁琐的。然而,由于Debian强大的dpkg软件包管理系统,使得内核的升级、编译也变得容易很多。如果下面的步骤都注意并执行了,编译内核不是很复...

linux内核的经典书籍有那些学习内核不是件容易事,前面有很多前续课程要读。 1.C语言,推荐 The programmgin c language被称为圣经的书,不过没有中文版,不过C语言不太难,而且读内核也不需要你对C有多深了解...

linux里oracle11g内核参数怎么配置展开1全部 修改 /etc/sysctl.conf 文件之后,执行命令 # sysctl -p 立刻生效 1、kernel.shmmax 用于定义单个共享内存段的最大值 shmmax 设置应该足够大,能在一个共享内存段下...

浏览器的内核WebKit是什么公司开发的?这个内核好不好苹果公司在设计WebKit之时加入了太多Mac OS X平台的独有事物,这给向其它系统的移植造成了很大障碍。不过,由于WebKit出色的开源特性,这些障碍正在被不断克服。 WebKit是Mac OS...

推荐阅读
图文推荐