Linux内核设备驱动之字符设备驱动笔记整理

2019-01-16 20:44:33王振洲

见char_load和char_unload脚本。

(3)字符设备的基本数据结构

和字符设备驱动关系最紧密的3个基本的数据结构是:file, file_oepeations和inode

a.file_operations数据结构

结构中包含了若干函数指针。这些函数就是实际和硬件打交道的函数。

用户空间调用的open,write等函数最终会调用这里面的指针所指向的函数。每个打开的文件和一组函数关联。

见<linux/fs.h>和驱动书的p54

2.6内核结构的初始化:

struct file_operations my_fops = { .owner = THIS_MODULE, .llseek = my_llseek, .read = my_read, .write = my_write, .ioctl = my_ioctl, .open = my_open, .release = my_release, }

2.4内核结构的初始化:

struct file_operations my_fops = { owner: THIS_MODULE, llseek: my_llseek, ... }

b.file结构<linux/fs.h>

file是一个内核结构体,实际上和用户open文件后返回的文件描述符fd对应。

file结构代表一个打开的文件,系统中每个打开的文件在内核空间都有一个对应的file结构。

它由内核在open时创建,并传递给在该文件上进行操作的所有函数,直到最后的close函数,在文件的所有实例都被关闭后,内核会释放这个结构。

用户空间进程fork一个新进程后,新老进程会共享打开的文件描述符fd,这个操作不会在内核空间创建新的file结构,只会增加已创建file结构的计数。

见<linux/fs.h>

mode_t f_mode;  通过FMODE_READ和FMODE_WRITE标示文件是否可读或可写。

loff_t f_pos;  当前的读写位置,loff_t为64位

unsigned int f_flags;  文件标志,如O_RDONLY, O_NONBLOCK, O_SYNC。标志都定义在<linux/fcntl.h>

struct file_operations *f_op;  与文件相关的操作。内核在执行open时对这个指针赋值。可以在驱动的open方法中根据次设备号赋予不同的f_op

void *private;  通常将表示硬件设备的结构体赋给private.

struct dentry *f_dentry;  文件对应的目录项(dentry)结构。可通过filp->f_dentry->d_inode访问索引节点。

file中其他的内容和驱动关系不大。

c.inode结构

内核用inode结构表示一个实际的文件,可以是一个普通的文件,也可以是一个设备文件。

每个文件只有一个inode结构,而和文件描述符对应的file结构可以有多个(多次进行open调用)。这些file都指向同一个inode。

inode定义在<linux/fs.h>

dev_t i_rdev;  对于表示设备文件的inode结构,i_rdev里包含了真正的设备编号

struct cdev *i_cdev  cdev是表示字符设备的内核的内部结构。当inode表示一个字符设备时,i_cdev指向内核中的struct cdev.

其他结构和设备驱动关系不大。

用如下宏从inode获取设备号: