Linux内核学习-字符设备驱动学习(一)
分类: Linux内核学习2011-06-19 15:46 480人阅读 评论(0) 收藏 举报Linux内核学习-字符驱动学习(一)
现在学习一下Linux的字符设备驱动,参考的样本应该就是ldd3这书大概第3章的内容吧。
下面的所说的字符设备都是基于2.6内核的,
一般的流程都是,呵呵,其实也不算是一般的流程了,只是手动加载字符设备驱动的一种方法吧,
1. 先使用register_chrdev_region或alloc_chrdev_region来注册一个字符设备的设备号,大家都知道Linux是通过设备号来找到相应的驱动程序的,所以你要注册字符设备的时候,需要一个设备号或系统为你指定一个设备号。这两函数的差别就是register_chrdev_region是注册指定设备号的字符设备,这个如果注册设备号已经存在则有可能会失败,而alloc_register_region是系统分配一个未使用的设备号然后再注册
2. 再使用cdev_add函数,把该设备号相应的文件操作file_operation文件操作入口表添加到内核的散列表里面,其中file_operation是需要你在驱动里面实现的。然后使用命令mknod,创建与该字符设备(设备号)对应的设备节点,当有用户程序打开这个设备并对其操作时候,系统会调用kobj_lookup() 函数,根据设备编号就可以找到 cdev 结构变量,从而取出其中的 ops (file_operation)字段,跳到相应的驱动入口去执行。
3. 当需要卸载驱动的时候(手动加载),需要做一些清理工作,cdev_del函数把散列表里面的数据清除,再调用unregister_chrdev_region.
下面简单介绍一下相关的函数:
|
上面有个count参数,文字意义上是数量的意思,而从函数名中的_region可以看出是注册某一范围的设备号的
把这两个结合起来就是说,注册使用从first[或dev]到(frist+count)[或dev+count],这个编号范围的设备使用该驱动。。。
内核用dev_t类型(<linux/types.h>)来保存设备编号,dev_t是一个32位的数,12位表示主设备号,20为表示次设备号。
在实际使用中,是通过<linux/kdev_t.h>中定义的宏来转换格式。
(dev_t)-->主设备号、次设备号 | MAJOR(dev_t dev) MINOR(dev_t dev) |
主设备号、次设备号-->(dev_t) | MKDEV(int major,int minor) |
如果只是在module_init函数里面做上面的这一步,加载内核模块的时候,会可以cat /proc/devices里面看到你注册的设备和主设备号。
大家应该都知道file_operation函数的,它在<linux/fs.h>文件里面有定义,是一个保存驱动操作函数入口的结构体,我们要做的工作基本都在这里,完成这一步之后,使用cdev_add函数,把设备号与相应的file_operation指针添加到系统cdev_map 散列表里面去,
初始化struct cdev
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
初始化cdev.owner
cdev.owner = THIS_MODULE;
cdev.ops = &fops;
cdev设置完成,通知内核struct cdev的信息(在执行这步之前必须确定你对struct cdev的以上设置已经完成!)
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
这里面的count的意义跟上面register_chrdev_region中的是一样的。
从系统中移除一个字符设备:void cdev_del(struct cdev *p)
完成这一步之后,你已经注册了字符设备,但是你还不能对它进行操作(打开,关闭读,写等),你需要使用mknod命令手动的去生成一个设备号对应的索引节点,这个需要管理员权限的,你的主设备号可以通过cat /proc/devices看到
mknod - make block or character special files
mknod [OPTION]... NAME TYPE [MAJOR MINOR]
option 有用的就是 -m 了
name 自定义
type 有 b 和 c 还有 p
主设备号
次设备号
sudo mknod /dev/char01 c 250 0
最后你可以在你的用户程序里面使用open("/dev/char01", O_RDONLY);去打开这个设备了,
由于创建/dev/*节点的时候,是只有管理员有权限的,所以你的测试程序也需要管理员权限执行。
下面是相应的源文件:
char01.c
Makefile:
测试文件,char01_test.c
参考文章:
http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=94290