linux内核 devtmpfs介绍
概要
提示:这里可以添加技术概要
linux内核中 devtmpfs实现介绍
内核版本:5.10
Devtmpfs在Linux中是一个特殊的设备文件系统,主要用来linux内核中加速启动过程和管理设备节点。高版本的linux基本都是使用devtmpfs来管理设备节点。
devtmpfs(device temporary file system)是在 Linux 内核 2.6.33 版本中引入的。 devtmpfs 的引入是为了简化设备节点的创建过程,并且减少对用户空间程序(如 udev)的依赖,使得设备节点能够在系统启动早期就可用。
整体架构流程
代码流程如下:
devtmpfs是和tmpfs类似,是存在内存中的,不会存储到硬盘,主要功能是:创建和删除设备节点(mknod)
技术细节
1,初始化:
devtmpfs_init
vfs_kern_mount(&internal_fs_type, 0, “devtmpfs”, opts);
register_filesystem(&dev_fs_type); // 注册文件系统
kthread_run(devtmpfsd, &err, “kdevtmpfs”); //创建kthread处理setup和loop。
Devtmpfs初始化时候先vfs_kern_mount产生一个挂载点描述结构vfsmount mnt结构,然后注册dev_fs_type文件系统,最后再创建devtmpfsd的kthread。
2,devtmpfsd线程代码:
Devtmpfsd
devtmpfs_setup
devtmpfs_work_loop();
Devtmpfsd会先调用devtmpfs_setup函数挂载devtmpfs到 “/” 目录,然后进入work_loop,等待请求去创建和删除设备文件。
创建/删除设备文件接口:
devtmpfs_create_node
devtmpfs_delete_node
在内核启动init进程(systemd)后,由systemd将devtmpfs挂载到 /dev 目录。
线程实现细节:
有一个全局的 requests 结构来接收发送的请求,这个结构是个 链表,新的请求将插入头部,request指向当前设置的req,然后唤醒等待的处理线程,等待处理完成。
线程处理会加自旋锁然后 一次性将链表中所有请求 处理完成。提交请求和处理请求均有加锁操作spin_lock。
static struct req {struct req *next;struct completion done;int err;const char *name;umode_t mode; /* 0 => delete */kuid_t uid;kgid_t gid;struct device *dev;
} *requests; //链表 从头部加数据 线程处理一次性将链表中所有请求处理完成static int devtmpfs_submit_req(struct req *req, const char *tmp)
{init_completion(&req->done);spin_lock(&req_lock);req->next = requests;requests = req;spin_unlock(&req_lock);wake_up_process(thread);wait_for_completion(&req->done); //等待请求完成kfree(tmp);return req->err;
}static void __noreturn devtmpfs_work_loop(void)
{while (1) {spin_lock(&req_lock);while (requests) {struct req *req = requests;requests = NULL;spin_unlock(&req_lock);while (req) {struct req *next = req->next;req->err = handle(req->name, req->mode,req->uid, req->gid, req->dev);complete(&req->done);// 完成请求req = next;}spin_lock(&req_lock);}__set_current_state(TASK_INTERRUPTIBLE);spin_unlock(&req_lock);schedule();}
}
并不是所有的device都会创建设备节点
只有分配设备号的设备会创建,net设备不会创建
设备节点(dev目录下的设备文件)本质是由vfs_mknod创建
字符设备c和块设备b文件,fifo和socket文件也是vfs_mknod实现。
小结
以上介绍了devtmpfs基本概念和实现细节,有需要可以参考devtmpfs的单线程req实现内核线程相关操作。