内核驱动模块如何在/dev文件下自动创建设备

时间:2021-11-28 19:02:26
每次测试自己写的驱动模块都要自己mknod设备文件,总觉得是一种不好的行为
而且要自己指定主设备号和次设备号,就是没有书上说sysfs、udev什么程序员不需关心设备号之类的优点了
内核TMD经常变,一个2.6.25上还好好的驱动,跑到2.6.29上就不能编译通过了,妈的,
可以理解为什么Linux驱动工程师会高薪了,好,我忍了

这里的方法只能保证倒2.6.31,再往后就未知了,所以死读书是不行的
要融会贯通,深入理解,有问题直接到内核代码里找答案
在2.6.17以前,在/dev目录下生成设备文件很容易,
devfs_mk_bdev
devfs_mk_cdev
devfs_mk_symlink
devfs_mk_dir
edvfs_remove
这几个是纯devfs的api,2.6.17以前可用,但是后来devfs被抛弃,采用sysfs+udev的形式
同时期sysfs文件系统可以用的api:
class_device_create_file 在2.6.26以后也不行了
现在,好使的是device_create ,从2.6.18开始可用
 

struct device *device_create(struct class *class, struct device *parent,
dev_t devt, const char *fmt, ...)
从2.6.26起又多了一个参数drvdata: the data to be added to the device for callbacks
不会用就给个NULL吧
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
 
 
试例程序有些步骤应该在open或者bind时才调用的,为了方便直接在init里做了
会在/dev/下生成test_usb 设备文件,并且在/sys也有相应文件
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/utsname.h>
#include <linux/fs.h>
MODULE_DESCRIPTION("My kernel module");
MODULE_AUTHOR("deep_pro");
MODULE_LICENSE("GPL");
static struct class *usb_class;
static struct device *dev;
static const char shortname [] = "test_usb";
static dev_t test_usb_devno;

static int test_sysfs_init_module(void)
{
int    ret;
printk( KERN_DEBUG "Module test_sysfs init\n" );
usb_class = class_create(THIS_MODULE, shortname);
if (IS_ERR(usb_class))
{
printk( KERN_DEBUG "class_create error\n" );
return -1;
}
ret=alloc_chrdev_region(&test_usb_devno, 0, 1, shortname);
if (ret)
{
printk( KERN_DEBUG "alloc_chrdev_region error\n" );
class_destroy(usb_class);
return ret;
}
dev=device_create(usb_class, NULL, test_usb_devno, shortname);
//2.6.26以上
// dev=device_create(usb_class, NULL, test_usb_devno, NULL,shortname);
return 0;
}
static void test_sysfs_exit_module(void)
{

device_destroy(usb_class, test_usb_devno);
unregister_chrdev_region(test_usb_devno, 1);
class_destroy(usb_class);
printk( KERN_DEBUG "Module test_sysfs exit\n" );
}
module_init(test_sysfs_init_module);
module_exit(test_sysfs_exit_module);