1. 设备编号
"主设备号标识设备对应的驱动程序" 而 "次设备号用于正确确定设备文件所指的设备"(LDD3 p48)
也就是说:主设备号对应驱动程序;次设备号对应使用同个驱动程序的设备;一般一个驱动程序可以被多个设备共享
一个主设备号和一个次设备号 合在一起 可以唯一确定一个设备文件,Linux内核使用一个叫做dev_t的类型来保存主设备号和次设备号,我们称dev_t类型的数据为设备编号。
要通过设备编号获取主次设备号,可以用以下宏:
MAJOR(dev_t dev);
MINOR(dev_t dev);
要通过主次设备号组成设备编号,可以用以下宏:
MKDEV(int major, int minor);
"在建立一个字符设备之前,我们的驱动程序首先要做的事情就是获得一个或者多个设备编号"(LDD3 P49)
至于分配和释放设备编号,感谢LDD3的作者已经为我们提供了很好的范例:
- if(scull_major)
- {
- dev = MKDEV(scull_major, scull_minor);
- result = register_chrdev_region(dev, scull_nr_devs, "scull");
- } else {
- result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
- scull_major = MAJOR(dev);
- }
-
- if(result < 0)
- {
- printk(KERN_WARNING "scull cannot register character device /n");
- return result;
- }
if(scull_major) { dev = MKDEV(scull_major, scull_minor); result = register_chrdev_region(dev, scull_nr_devs, "scull"); } else { result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull"); scull_major = MAJOR(dev); } if(result < 0) { printk(KERN_WARNING "scull cannot register character device /n"); return result; }
2. 重要的数据结构
file_operations结构的作用是将驱动程序的操作连接到我们注册号的设备编号上:
- struct file_operations scull_fops = {
- .owner = THIS_MODULE,
- .llseek = scull_llseek,
- .read = scull_read,
- .write = scull_write,
- .ioctl = scull_ioctl,
- .open = scull_open,
- .release = scull_release,
- };
struct file_operations scull_fops = { .owner = THIS_MODULE, .llseek = scull_llseek, .read = scull_read, .write = scull_write, .ioctl = scull_ioctl, .open = scull_open, .release = scull_release, };
file结构是在打开一个设备时创建的,所有在该设备上操作的方法都共享这个结构描述符,直到最后关闭这个设备文件。
inode结构唯一标识一个设备,一个设备可能会有多个file结构的描述符,但是有且只有一个inode,其成员i_cdev表示字符设备。
3. scull的设备布局
scull使用链表存储量子集,一个量子集有多个量子,每个量子有一定的大小。
转自:http://blog.csdn.net/victorsummer/article/details/6092199