kobject_uevent,uevent_helper,/sys/kernel/uevent_helper,/proc/sys/kernel/hotplug
阿新 • • 發佈:2019-01-04
class_device_create
class_device_register
class_device_add
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
kobject_uevent_env
action_string = action_to_string(action);
uevent_ops->filter
subsystem = uevent_ops->name(kset, kobj);
envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
devpath = kobject_get_path(kobj, GFP_KERNEL);
envp[i++] = "HOME=/";...
#if defined(CONFIG_NET)
/* send netlink message */
if (uevent_helper[0]) {
char *argv [3];
argv [0] = uevent_helper;
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0);
}
關於uevent_helper(在Source Insight中搜索)
1.對/sys/kernel/uevent_helper 檔案的讀寫就是對uevent_helper的讀寫
linux/kernel/ksysfs.c
static ssize_t uevent_helper_show(struct kset *kset, char *page)
{
return sprintf(page, "%s\n", uevent_helper);
}
static ssize_t uevent_helper_store(struct kset *kset, const char *page, size_t count)
{
if (count+1 > UEVENT_HELPER_PATH_LEN)
return -ENOENT;
memcpy(uevent_helper, page, count);
uevent_helper[count] = '\0';
if (count && uevent_helper[count-1] == '\n')
uevent_helper[count-1] = '\0';
return count;
}
KERNEL_ATTR_RW(uevent_helper);//宣告一個subsys_attribute變數 uevent_helper_attr
//它對應sysfs 中的一個檔案,檔名是uevent_helper
//它的讀寫函式分別是uevent_helper_show,uevent_helper_store
#define KERNEL_ATTR_RW(_name) \
static struct subsys_attribute _name##_attr = __ATTR(_name, 0644, _name##_show, _name##_store)
#define __ATTR(_name,_mode,_show,_store) { \
.attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
}
int error = subsystem_register(&kernel_subsys);//註冊子系統
//kernel_subsys的建立使用decl_subsys巨集
decl_subsys(kernel, NULL, NULL);//建立了/sys/kernel目錄
error = sysfs_create_group(&kernel_subsys.kobj,&kernel_attr_group);//在子系統中建立一組檔案
static struct attribute_group kernel_attr_group = {
.attrs = kernel_attrs,
};
static struct attribute * kernel_attrs[] = {
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
&uevent_seqnum_attr.attr,
&uevent_helper_attr.attr,//uevent_helper檔案
#endif
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
#endif
NULL
};
2.對/proc/sys/kernel/hotplug 檔案的讀寫就是對uevent_helper的讀寫
/linux/kernel/sysctl.c
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
{
.ctl_name = KERN_HOTPLUG,
.procname = "hotplug",//建立/proc/sys/kernel/hotplug檔案
.data = &uevent_helper,//對檔案讀寫的資料物件,讀寫/proc/sys/kernel/hotplug就是對uevent_helper的讀寫
.maxlen = UEVENT_HELPER_PATH_LEN,
.mode = 0644,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
},
所以,在使用mdev時,在/etc/init.d/rc.S 寫入 echo "/sbin/mdev" > /proc/sys/kernel/hotplug
和 寫入 echo "/sbin/mdev" > /sys/kernel/uevent_helper作用應該是相同的