Linux内核init_mknod和ksys_mknod的区别
时间: 2023-05-29 08:01:27 浏览: 85
在 Linux 内核中,`init_mknod` 和 `ksys_mknod` 都是创建设备节点的内核函数。
区别在于:
1. `init_mknod` 是在用户空间调用 `mknod` 函数时被调用,主要负责解析用户传入的参数,调用 `ksys_mknod` 进行实际的设备节点创建操作。
2. `ksys_mknod` 则是用来实际创建设备节点的内核函数。
因此,`init_mknod` 属于用户空间与内核空间的交互函数,而 `ksys_mknod` 则是纯粹的内核函数。
相关问题
linux内核中有哪些函数可以在内核态创建块设备的函数?介绍一下vfs_mknod的使用?
Linux内核中可以使用以下函数来创建块设备:
1. register_blkdev:用于分配一个未使用的主设备号,并将其与相应的设备驱动程序关联。
2. blk_alloc_queue:用于为块设备分配一个请求队列。
3. blk_init_queue:用于初始化请求队列。
4. blk_queue_logical_block_size:用于设置逻辑块大小。
5. blk_queue_physical_block_size:用于设置物理块大小。
6. blk_queue_max_hw_sectors:用于设置每个请求的最大扇区数。
7. blk_queue_max_segments:用于设置请求中允许的最大段数。
8. blk_queue_max_segment_size:用于设置请求中允许的最大段大小。
9. blk_queue_bounce_limit:用于设置数据传输限制。
关于vfs_mknod函数的使用,它是用于在Linux内核中创建一个特殊文件的函数,例如块设备或字符设备文件。vfs_mknod函数的原型如下:
```
int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev);
```
该函数的参数解释如下:
- dir:指向父目录的inode结构体指针。
- dentry:指向新创建特殊文件的dentry结构体指针。
- mode:新创建特殊文件的权限模式。
- dev:新创建特殊文件的设备号。
使用vfs_mknod函数可以在内核态中创建块设备或字符设备文件,例如:
```
dev_t dev = MKDEV(250, 0); // 创建设备号
vfs_mknod(dir, dentry, S_IFBLK | 0660, dev); // 创建块设备
```
注意:使用vfs_mknod函数创建特殊文件需要具有root权限。
按照你说的做了,编译时驱动时报了sys_mknod函数找不到的错误,这是什么原因?
在Linux内核中,sys_mknod函数并不是一个公共的函数,它只在内核空间中使用。因此,在驱动中使用sys_mknod函数会报错找不到函数的错误。
如果想在驱动中创建设备节点,可以使用内核提供的函数device_create和class_create,它们是公共的函数,可以在驱动中使用。
下面是一个简单的示例代码,用于在驱动中使用device_create和class_create创建设备节点:
```
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/device.h>
static int my_device_init(void)
{
int result;
dev_t devno;
struct class *my_class;
struct device *my_device;
// 分配设备号
result = alloc_chrdev_region(&devno, 0, 1, "my_device");
if (result < 0) {
printk(KERN_ERR "my_device: failed to allocate device number\n");
return result;
}
// 创建设备类
my_class = class_create(THIS_MODULE, "my_device_class");
if (IS_ERR(my_class)) {
unregister_chrdev_region(devno, 1);
printk(KERN_ERR "my_device: failed to create device class\n");
return PTR_ERR(my_class);
}
// 创建设备节点
my_device = device_create(my_class, NULL, devno, NULL, "my_device");
if (IS_ERR(my_device)) {
class_destroy(my_class);
unregister_chrdev_region(devno, 1);
printk(KERN_ERR "my_device: failed to create device node\n");
return PTR_ERR(my_device);
}
printk(KERN_INFO "my_device: device node created\n");
return 0;
}
static void my_device_exit(void)
{
// 销毁设备节点
device_destroy(class_find_device(THIS_MODULE, NULL, MKDEV(240, 0)), MKDEV(240, 0));
// 销毁设备类
class_destroy(class_find(THIS_MODULE, "my_device_class"));
// 释放设备号
unregister_chrdev_region(MKDEV(240, 0), 1);
printk(KERN_INFO "my_device: device node destroyed\n");
}
module_init(my_device_init);
module_exit(my_device_exit);
```
在上面的代码中,驱动使用了alloc_chrdev_region函数分配设备号,并使用class_create函数创建设备类。然后使用device_create函数创建设备节点,最后在驱动退出时使用device_destroy和class_destroy函数销毁设备节点和设备类。