【思考三:为什么要创建类呢?】
概念:
在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上Linux内核为我们提供了一组函数,可以用来在模块加载的时候自动在/dev目录下创建相应设备节点,并在卸载模块时删除该节点,当然前提条件是用户空间移植了udev。
内核中定义了struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点。
已经知道的:
1:register_chrdev来注册字符设备驱动,用这种方法的好处是简单,只需要一个函数就可以注册字符设备驱动了,缺点是无法设置次设备号;
2:register_chrdev_region/allco_chrdev_region、cdev_XXX这些函数来配合注册设备驱动,单纯使用这些函数存在一个问题就是无法自动在/dev目录下面创建
驱动设备文件,我们在嵌入式设备中一般使用busybox中的mdev来实现驱动设备文件的自动创建,但是驱动设备文件的创建需要一个uevent文件;
3:uevent文件是有kobject_uevent函数来实现的;所以我们为了设备文件的自动生成,首先使用class_create函数来创建一个设备类,在用device_create函数
把子目录创建了,这时候就会有一个uevent文件,然后mdev会自动的根据uevent创建/dev/目录下面的设备文件;
4:所以我们在module_init的时候要把sys目录下的类创建了,以及把device也创建了;
下面是详细分析:
class_create函数:
|
class_create
|
__class_create
|
__class_register
|
kset_register
|
kobject_uevent /* kobject_uevent_env - send an uevent with environmental data*/
思考四:创建设备节点的具体过程?】
/**
* 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
* @drvdata: the data to be added to the device for callbacks
* @fmt: string for the device's name
*/
leds_dev[0] = device_create(leds_class, NULL, MKDEV(major, 0), NULL, "leds"); //在类下,创建设备节点"leds"
|
device_create_vargs(leds_class, NULL, MKDEV(major, 0), NULL, "leds", vargs);
|
device_create_groups_vargs(leds_class, NULL, MKDEV(major, 0), NULL, NULL, "leds", args);
|
device_initialize(dev); //对设备的初始化,就是把这个结构体,插入到链表中;
device_add(dev);
|
device_create_file(dev, &dev_attr_uevent);
device_add_class_symlinks(dev);
device_add_attrs(dev);
bus_add_device(dev);
dpm_sysfs_add(dev);
device_pm_add(dev);
kobject_uevent(&dev->kobj, KOBJ_ADD); // 发送uevent信息,创建设备节点
bus_probe_device(dev);
类似的还有DRIVER_ATTR,BUS_ATTR,CLASS_ATTR。这几个东东的区别就是,DEVICE_ATTR对应的文件在/sys/devices/目录中对应的device下面。
而其他几个分别在driver,bus,class中对应的目录下。
在创建类和创建设备的时候,最终都调用了kobject_uevent,通过内核的uevent机制自动创建文件,但具体uevent是怎样工作的呢?现在还不懂,以后在深究吧。