linux内核中是如何通过device_add()注册一个/dev/下的设备节点的?函数调用流程是怎样的?
在Linux内核中,通过device_add()
函数注册一个设备节点的过程涉及多个步骤和函数调用。以下是一个简化的流程,描述了主要的函数调用和操作:
调用device_add()
:
device_add()
函数来注册一个设备。int device_add(struct device *dev);
初始化设备结构体:
device_add()
会对传入的struct device
结构体进行一系列初始化操作,包括设置设备的状态、初始化设备的kobject等。调用device_initialize()
:
device_add()
内部会调用device_initialize()
来初始化设备的kobject和其他相关字段。调用bus_add_device()
:
device_add()
会调用bus_add_device()
将设备添加到总线(bus)上。add
回调函数。调用device_create_file()
:
device_add()
会调用device_create_file()
为设备创建属性文件(sysfs文件),这些文件通常位于/sys/devices/
目录下。调用kobject_uevent()
:
device_add()
会调用kobject_uevent()
发送uevent通知用户空间,告知有新设备添加。udev
等用户空间守护进程来创建相应的设备节点。调用devtmpfs
相关函数:
devtmpfs
,内核会自动在/dev/
目录下创建设备节点。device_add()
会调用devtmpfs_create_node()
来创建设备节点。设备节点创建:
devtmpfs_create_node()
会根据设备的主次设备号(major/minor number)在/dev/
目录下创建相应的设备节点文件。以下是一个简化的调用流程图:
device_add()
|
+--> device_initialize()
|
+--> bus_add_device()
| |
| +--> bus->add(dev)
|
+--> device_create_file()
|
+--> kobject_uevent()
|
+--> devtmpfs_create_node()
以下是一个简化的代码示例,展示了如何使用device_add()
注册一个设备:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/fs.h>
static struct class *example_class;
static struct device *example_device;
static dev_t devt;
static int __init example_init(void)
{
int ret;
// 分配设备号
ret = alloc_chrdev_region(&devt, 0, 1, "example");
if (ret < 0) {
pr_err("Failed to allocate chrdev region\n");
return ret;
}
// 创建设备类
example_class = class_create(THIS_MODULE, "example_class");
if (IS_ERR(example_class)) {
unregister_chrdev_region(devt, 1);
return PTR_ERR(example_class);
}
// 创建设备
example_device = device_create(example_class, NULL, devt, NULL, "example_device");
if (IS_ERR(example_device)) {
class_destroy(example_class);
unregister_chrdev_region(devt, 1);
return PTR_ERR(example_device);
}
pr_info("Example device created successfully\n");
return 0;
}
static void __exit example_exit(void)
{
device_destroy(example_class, devt);
class_destroy(example_class);
unregister_chrdev_region(devt, 1);
pr_info("Example device removed\n");
}
module_init(example_init);
module_exit(example_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Example Author");
MODULE_DESCRIPTION("Example Device");
在这个示例中,device_create()
函数内部会调用device_add()
来注册设备,并最终在/dev/
目录下创建一个名为`example