来看内核中一个简单的字符设备驱动的例子,其主设备号为1,根据LANANA标准,该设备有10个不同的次设备号。每个都提供了一个不同的功能,这些都与内存访问操作有关。下面列出一些次设备号,以及相关的文件名和含义。
表1 用于主设备号1的各个从设备号
从设备号 | 文件 | 含义 |
1 | /dev/mem | 物理内存 |
2 | /dev/kmem | 内核虚拟地址空间 |
3 | /dev/null | 比特位桶 |
4 | /dev/port | 访问I/O端口 |
5 | /dev/zero | WULL字符源 |
8 | /dev/random | 非确定性随机数发生器 |
一些设备是我们熟悉的,特别是/dev/null。根据设备描述我们可以很清楚地知道尽管这些从设备都涉及到内存访问,但所实现功能有很大差别。然后来看下图1中主设备号为1的memory_fops中定义了哪些函数指针。代码如下:
driver/char/mem.c
static const struct file_operations memory_fops = { .open = memory_open, .llseek = noop_llseek, }; |
其中函数memory_open最为关键,其作用是根据次设备号找到次设备的驱动程序。
static int memory_open(struct inode *inode, struct file *filp) minor = iminor(inode); /* get the minor device number commented by guoqingbo */ dev = &devlist[minor];/* select the specific file_operations */ filp->f_op = dev->fops; /* Is /dev/mem or /dev/kmem ? */ if (dev->fops->open) //open the device return 0; |