linux内核bus总线原理分析---以usb的bus总线为例

linux所有的外部设备都是通过各种bus总线与cpu通信,常见的bus有pci,usb,i2c,isa,mca,sbus,platform,spi等,所有的外部设备终端都有一个bus控制器,cpu通过bus与各种控制器通信,而不同的控制器需要不同的驱动,总线就负责管理各种设备与驱动。
下面我们以usb总线为例分析下bus总线的与设备驱动的关系
一.linux启动时候首先注册一个usb总线设备
subsys_initcall(usb_init)-> // kernel/drivers/usb/core/usb.c
__init usb_init(void) ->
bus_register(struct bus_type *bus) -> kernel\drivers\base\bus.c

            struct subsys_private *priv;                         //分配一个struct subsys_private结构体
            priv->bus = bus;
            bus->p = priv;
            bus_create_file(bus, &bus_attr_uevent);           //sys/bus/usb/下创建uevent节点
            add_probe_files(bus);                                       //sys/bus/usb/下创建drivers_autoprobe   drivers_probe节点
            bus_add_groups(bus, bus->bus_groups);        //sys/bus/usb/下创建多个节点

这样一个usb设备总线设备就注册好了。usb总线设备本身也需要驱动,下面分析usb总线驱动加载流程
二.把总线驱动添加到总线上去

   subsys_initcall(usb_init)->         // kernel/drivers/usb/core/usb.c
            __init usb_init(void) ->       
                 usb_register_device_driver->    Y:\kernel\drivers\usb\core\driver.c  这里面传递了一个usb父驱动usb_generic_driver,所有usb设备插入都要用次驱动进行设备枚举,并设置了总线类型为new_udriver->drvwrap.driver.bus =                         &usb_bus_type;
        driver_register->   
                bus_add_driver(drv);         Y:\kernel\drivers\base\driver.c  //把驱动添加到总线上去
                                bus = bus_get(drv->bus);      //获取上面设置的总线

klist_init(&priv->klist_devices, NULL, NULL); 初始化并插入bus驱动链表
priv->driver = drv;
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
“%s”, drv->name);
三.普通usb设备-usb接口
1.usb最小通信单位是端点,一个接口有若干个端点,一个配置有若干个接口,平时写usb驱动就是接口驱动
usb_register_driver-> 注册一个usb接口驱动 kernel\drivers\usb\core\driver.c
driver_register
bus_add_driver(drv); kernel\drivers\base\driver.c //把驱动添加到总线上去
bus = bus_get(drv->bus); //获取上面设置的总线
klist_init(&priv->klist_devices, NULL, NULL); 初始化并插入bus驱动链表
这里分析了usb驱动添加到总线的过程
2.分析下usb设备添加到总线的过程
linux内核启动的时候注册了hub事件不停的查询usb设备的插入
hub_probe -> Y:\kernel\drivers\usb\core\hub.c
hub_event->
->port_event
hub_port_connect_change->
->hub_port_connect
->usb_new_device
->device_add Y:\kernel\drivers\base\core.c
bus_add_device //就在这里usb设备添加到usb总线上

通过上面的分析,我们知道usb设备的驱动与设备都是挂在总线上,每次插入一个新设备就会从总线上查找相应的符合的驱动,一旦找到相应的驱动,设备就处于可使用状态。通过上述分析,我们可以自己开发一个usb设备从而添加相应的设备驱动。以此类推,平台设备也是这个原理。

你可能感兴趣的:(linux,android,usb,内核,java)