我可以从我的内核模块调用 mknod 吗?
Can I call mknod from my kernel module?
如标题所述,我正在编写一个内核模块,我希望模块创建的字符设备能够自动显示。我可以在 module_init
和 module_exit
中使用 mknod
和 rm
来创建和删除设备吗?
编辑:不确定是否允许这样做,但作为问题的扩展,我在哪里可以找到更多这样的信息?我的大部分 google 搜索都会导致对非常旧的信息(内核 2.6 及更早版本)感到非常困惑,学习如何编写内核模块的最佳地点是什么?
不,您不能使用内核中的 mknod 和 rm cli space。这些是 bash 命令。但是存在其他选项可以从内核 space 创建和删除模块的设备节点文件。在模块初始化函数中,您可以在为您的设备注册后使用 class_create() 和 device_create() 函数。 cdev_init() 调用后,您可以使用这两个函数创建节点文件。类似地,您可以在 module_exit 函数中使用 device_destroy() 和 class_destroy() 函数来删除节点文件。
这是在字符设备初始化函数中创建 /dev/kmem 的示例代码:
int majorNum;
dev_t devNo; // Major and Minor device numbers combined into 32 bits
struct class *pClass; // class_create will set this
static int __init devkoInit(void) {
struct device *pDev;
// Register character device
majorNum = register_chrdev(0, "devko", &fileOps);
if (majorNum < 0) {
printk(KERN_ALERT "Could not register device: %d\n", majorNum);
return majorNum;
}
devNo = MKDEV(majorNum, 0); // Create a dev_t, 32 bit version of numbers
// Create /sys/class/kmem in preparation of creating /dev/kmem
pClass = class_create(THIS_MODULE, "kmem");
if (IS_ERR(pClass)) {
printk(KERN_WARNING "\ncan't create class");
unregister_chrdev_region(devNo, 1);
return -1;
}
// Create /dev/kmem for this char dev
if (IS_ERR(pDev = device_create(pClass, NULL, devNo, NULL, "kmem"))) {
printk(KERN_WARNING "devko.ko can't create device /dev/kmem\n");
class_destroy(pClass);
unregister_chrdev_region(devNo, 1);
return -1;
}
return 0;
} // end of devkoInit
static void __exit devkoExit(void) {
// Clean up after ourselves
device_destroy(pClass, devNo); // Remove the /dev/kmem
class_destroy(pClass); // Remove class /sys/class/kmem
unregister_chrdev(majorNum, DEVICE_NAME); // Unregister the device
} // end of devkoExit
如标题所述,我正在编写一个内核模块,我希望模块创建的字符设备能够自动显示。我可以在 module_init
和 module_exit
中使用 mknod
和 rm
来创建和删除设备吗?
编辑:不确定是否允许这样做,但作为问题的扩展,我在哪里可以找到更多这样的信息?我的大部分 google 搜索都会导致对非常旧的信息(内核 2.6 及更早版本)感到非常困惑,学习如何编写内核模块的最佳地点是什么?
不,您不能使用内核中的 mknod 和 rm cli space。这些是 bash 命令。但是存在其他选项可以从内核 space 创建和删除模块的设备节点文件。在模块初始化函数中,您可以在为您的设备注册后使用 class_create() 和 device_create() 函数。 cdev_init() 调用后,您可以使用这两个函数创建节点文件。类似地,您可以在 module_exit 函数中使用 device_destroy() 和 class_destroy() 函数来删除节点文件。
这是在字符设备初始化函数中创建 /dev/kmem 的示例代码:
int majorNum;
dev_t devNo; // Major and Minor device numbers combined into 32 bits
struct class *pClass; // class_create will set this
static int __init devkoInit(void) {
struct device *pDev;
// Register character device
majorNum = register_chrdev(0, "devko", &fileOps);
if (majorNum < 0) {
printk(KERN_ALERT "Could not register device: %d\n", majorNum);
return majorNum;
}
devNo = MKDEV(majorNum, 0); // Create a dev_t, 32 bit version of numbers
// Create /sys/class/kmem in preparation of creating /dev/kmem
pClass = class_create(THIS_MODULE, "kmem");
if (IS_ERR(pClass)) {
printk(KERN_WARNING "\ncan't create class");
unregister_chrdev_region(devNo, 1);
return -1;
}
// Create /dev/kmem for this char dev
if (IS_ERR(pDev = device_create(pClass, NULL, devNo, NULL, "kmem"))) {
printk(KERN_WARNING "devko.ko can't create device /dev/kmem\n");
class_destroy(pClass);
unregister_chrdev_region(devNo, 1);
return -1;
}
return 0;
} // end of devkoInit
static void __exit devkoExit(void) {
// Clean up after ourselves
device_destroy(pClass, devNo); // Remove the /dev/kmem
class_destroy(pClass); // Remove class /sys/class/kmem
unregister_chrdev(majorNum, DEVICE_NAME); // Unregister the device
} // end of devkoExit