分类: LINUX
2014-03-03 11:34:43
原文地址:内核驱动模块如何在dev文件下自动创建设备文件 作者:g_programming
每次测试自己写的驱动模块都要自己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开始可用
/**
* device_create - creates a device and registers it with sysfs
* @class: pointer to the struct class that this device should be registered to
* @parent: pointer to the parent struct device of this new device, if any
* @devt: the dev_t for the char device to be added
* @fmt: string for the device's name
*
* This function can be used by char device classes. A struct device
* will be created in sysfs, registered to the specified class.
*
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct device is passed in, the newly created
* struct device will be a child of that device in sysfs.
* The pointer to the struct device will be returned from the call.
* Any further sysfs files that might be required can be created using this
* pointer.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
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, ...)
试例程序
会在/dev/下生成test_usb 设备文件,并且在/sys也有相应文件
#include
#include
#include
#include
#include
#include
#include
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)
{
/* Remove sysfs files */
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);