本篇文章以mknod创建字符设备文件进行讲解
字符设备驱动的Demo例子可参考该篇文章
Linux 编写简单驱动并测试
1. mknod 命令
mknod /dev/hello c 520 0
该命令主要通过制定要创建的设备文件名称/dev/hello,以及设备类型c字符设备,最后的520 0 表示为主设备号和次设备号。
当我们使用该命令创建好了/dev/hello设备文件,当我们在用户态对该文件进行open()、write()、read()时,就会调用到/dev/hello设备文件对应的设备驱动的file_operations对应的.open、.write、.read回调函数。
那么这一切是怎么做到的呢?这就跟我们的mknod命令的实现有关。
2. mknod 原理
当我们输入mknod命令时,实际上会创建设备文件/dev/hello和所对应的inode,以及将主设备号和次设备号形成的设备号保存在inode的i_rdev中。
3. mknod 源码分析
已经知道mknode主要是为设备文件创建inode的原理后,我们来看一下代码是如何实现的。
3.1 mknod
SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev)
{
return do_mknodat(AT_FDCWD, getname(filename), mode, dev);
}
这个是mknod命令的系统调用,我们键入的命令mknod /dev/hello c 520 0,将会为这个函数进行赋值,赋值的内容如下:
filename = "/dev/hello";
mode = mode | S_IFCHR;
dev = MKDEV(520, 0);
3.2 do_mknodat
static int do_mknodat(int dfd, struct filename *name, umode_t mode,
unsigned int dev)
{
struct user_namespace *mnt_userns;
struct dentry *dentry;
struct path path;
int error;
unsigned int lookup_flags = 0;
error = may_mknod(mode);
if (error)
goto out1;
retry:
dentry = filename_create(dfd, name, &path, lookup_flags);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out1;
if (!IS_POSIXACL(path.dentry->d_inode))
mode &= ~current_umask();
error = security_path_mknod(&path, dentry, mode, dev);
if (error)
goto out2;
mnt_userns = mnt_user_ns(path.mnt);
switch (mode & S_IFMT) {
case 0: case S_IFREG:
error = vfs_create(mnt_userns

本文详细解析了Linux中使用mknod创建字符设备文件的过程,涉及mknod命令的工作原理、源码中do_mknodat和相关函数的执行流程,以及shmem_mknod等关键技术。
最低0.47元/天 解锁文章
1151

被折叠的 条评论
为什么被折叠?



