LDM上层建筑之Bus---局部窥探
时间:2016-02-22 13:05 来源:linux.it.net.cn 作者:IT
首先看下sys/devices怎么来的?
在初始的启动汇编中会跳到start_kernel---->rest_init---->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND)---->do_basic_setup(void)---->driver_init(void)---->buses_init();
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
if (!bus_kset)
return -ENOMEM;
return 0;
}
/sys/bus 就建立了,bus_uevent_ops做什么目前还不了解,先不管了
看下platform这个虚拟的bus怎么建立的。
同样是在driver_init(void)---->platform_bus_init(void) //driver_init 函数的注释是driver_init - initialize driver model.
int __init platform_bus_init(void)
{
int error;
error = device_register(&platform_bus); //
/************
struct device platform_bus = {
.bus_id = "platform",
};
这个地方生成了/sys/devices/platform 目录 和devices篇有关联
************/
if (error)
return error;
error = bus_register(&platform_bus_type);
if (error)
device_unregister(&platform_bus);
return error;
}
主要看error = bus_register(&platform_bus_type);
/**
* bus_register - register a bus with the system.
* @bus: bus.
*
* Once we have that, we registered the bus with the kobject
* infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the bus.
*/
int bus_register(struct bus_type *bus)
{
int retval;
struct bus_type_private *priv;
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->bus = bus;
bus->p = priv; //这两句将bus结构体的成员struct bus_type_private *p定义了
BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);
retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);
//bus->name 是“platform” ,将priv->subsys.kobj 的name定为“platform”;
if (retval)
goto out;
priv->subsys.kobj.kset = bus_kset; //将priv->subsys.kobj.kset定为bus_kset buses_init();中的bus_kset
priv->subsys.kobj.ktype = &bus_ktype;
priv->drivers_autoprobe = 1; //正因为将其赋值1,所以设备中的bus_attach_device函数中的device_attach(dev)会跑
retval = kset_register(&priv->subsys); //在sys/bus/下生成了platform目录
if (retval)
goto out;
retval = bus_create_file(bus, &bus_attr_uevent);
/*******************
找了半天没找到bus_attr_uevent那儿定义的,用SI搜到搜不到,google才发现是这样的:
Bus.c中:static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
而#define BUS_ATTR(_name, _mode, _show, _store) /
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
所以这里在platform下面创建了一个名为uevent的文件
******************/
if (retval)
goto bus_uevent_fail;
priv->devices_kset = kset_create_and_add("devices", NULL,
&priv->subsys.kobj); //在platform下新建的devicse目录
if (!priv->devices_kset) {
retval = -ENOMEM;
goto bus_devices_fail;
}
priv->drivers_kset = kset_create_and_add("drivers", NULL,
&priv->subsys.kobj); //在platform下新建的drivers目录
if (!priv->drivers_kset) {
retval = -ENOMEM;
goto bus_drivers_fail;
}
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); //初始化bus包含的devices链表和drivers链表
klist_init(&priv->klist_drivers, NULL, NULL);
retval = add_probe_files(bus);
//调用bus_create_file函数创建drivers_probe和drivers_autoprobe两个文件
if (retval)
goto bus_probe_files_fail;
retval = bus_add_attrs(bus);
//Add default attributes for this bus.
if (retval)
goto bus_attrs_fail;
pr_debug("bus: '%s': registered/n", bus->name);
return 0;
bus_attrs_fail:
remove_probe_files(bus);
bus_probe_files_fail:
kset_unregister(bus->p->drivers_kset);
bus_drivers_fail:
kset_unregister(bus->p->devices_kset);
bus_devices_fail:
bus_remove_file(bus, &bus_attr_uevent);
bus_uevent_fail:
kset_unregister(&bus->p->subsys);
kfree(bus->p);
out:
return retval;
}
bus先分析到这儿
(责任编辑:IT)
首先看下sys/devices怎么来的? 在初始的启动汇编中会跳到start_kernel---->rest_init---->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND)---->do_basic_setup(void)---->driver_init(void)---->buses_init();
int __init buses_init(void)
/sys/bus 就建立了,bus_uevent_ops做什么目前还不了解,先不管了
看下platform这个虚拟的bus怎么建立的。
同样是在driver_init(void)---->platform_bus_init(void) //driver_init 函数的注释是driver_init - initialize driver model.
int __init platform_bus_init(void) error = device_register(&platform_bus); // /************
struct device platform_bus = { 这个地方生成了/sys/devices/platform 目录 和devices篇有关联
************/ 主要看error = bus_register(&platform_bus_type);
priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);
priv->bus = bus; BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier); retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name); //bus->name 是“platform” ,将priv->subsys.kobj 的name定为“platform”;
priv->subsys.kobj.kset = bus_kset; //将priv->subsys.kobj.kset定为bus_kset buses_init();中的bus_kset
retval = kset_register(&priv->subsys); //在sys/bus/下生成了platform目录 retval = bus_create_file(bus, &bus_attr_uevent); /******************* 找了半天没找到bus_attr_uevent那儿定义的,用SI搜到搜不到,google才发现是这样的: Bus.c中:static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
而#define BUS_ATTR(_name, _mode, _show, _store) /
所以这里在platform下面创建了一个名为uevent的文件
******************/
priv->devices_kset = kset_create_and_add("devices", NULL,
priv->drivers_kset = kset_create_and_add("drivers", NULL,
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put); //初始化bus包含的devices链表和drivers链表 retval = add_probe_files(bus);
//调用bus_create_file函数创建drivers_probe和drivers_autoprobe两个文件 retval = bus_add_attrs(bus);
//Add default attributes for this bus.
pr_debug("bus: '%s': registered/n", bus->name);
bus_attrs_fail:
bus先分析到这儿 (责任编辑:IT) |