一、前言
应用程序运行在用户空间,而 Linux 驱动运行于内核空间。当我们在用户空间想要实现对内核的操作,比如使用 open 函数打开/dev/led 这个驱动,由于用户空间不能直接对内核进行操作,因此必须使用一个叫做 “系统调用” 的方法来实现从用户空间“陷入”到内核空间,这样才能实现对底层驱动的操作。
索引节点对象代表一个具体文件,由struct inode结构体表示,定义在linux/fs.h中。
二、具体过程
用户空间使用open()系统调用函数打开一个字符设备时( int fd = open("dev/demo", O_RDWR) )大致有以下过程:
- VFS层接收open()系统调用,在虚拟文件系统VFS中的查找与字符设备对应 struct inode节点;
- 遍历字符设备列表(chardevs数组),根据inod节点中的 cdev_t设备号找到cdev对象;
- 创建struct file对象,作为这个打开的文件的描述符。;
- 初始化struct file对象,将 struct file对象中的 file_operations成员(指针)指向字符设备驱动 struct cdev对象中的 file_operations成员(file->fops = cdev->fops);
- 回调file->fops->open函数。
- 任务完成,VFS层会给应用返回一个文件描述符(fd)。这个fd是和struct file结构体对应的。
- 应用程序使用 fd 调用 read()/write() 等读写函数,VFS层再回调 file->fops->read()/write() 函数,调用字符设备驱动读写。
三、参考内容
1.Linux 字符设备驱动结构(三)—— file、inode结构体及chardevs数组等相关知识解析_发如雪Jay的博客-CSDN博客
2.Linux字符设备中的两个重要结构体(file、inode)_clam_zxf的博客-CSDN博客
3.linux字符设备驱动之open()函数_d_backing_inode_麻辣小新的博客-CSDN博客