uboot驱动模型(DM)分析(二)

上篇分析了两个关键宏U_BOOT_DRIVER及U_BOOT_DEVICES的作用,有了上篇的基础,本文将分析:

1.上篇中的uboot_list段中的信息如何被用起来?

2.uclass,uclass_driver,udevice,driver之间的关系?

 

从board_r.c中的initr_dm函数开始分析:

1 static const struct driver_info root_info = {
2     .name        = "root_driver",
3 };

 1 /* This is the root driver - all drivers are children of this */
 2 U_BOOT_DRIVER(root_driver) = {
 3     .name    = "root_driver",
 4     .id    = UCLASS_ROOT,
 5     .priv_auto_alloc_size = sizeof(struct root_priv),
 6 };
 7 
 8 /* This is the root uclass */
 9 UCLASS_DRIVER(root) = {
10     .name    = "root",
11     .id    = UCLASS_ROOT,
12 };

 

initr_dm

  ret = dm_init_and_scan(false);

    dm_init

      INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);  //#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root) 创建头结点gd->uclass_root

      ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);

        drv = lists_driver_lookup_name(info->name);  //lists_driver_lookup_name("root_driver")  

             struct driver *drv =ll_entry_start(struct driver, driver);  //通过上篇分析,此处得到的是uboot_list_2_driver_1的地址

              const int n_ents = ll_entry_count(struct driver, driver);  //uboot_list_2_driver_3-uboot_list_2_driver_1即得到长度

              for (entry = drv; entry != drv + n_ents; entry++) {    //遍历,通过name字段匹配,匹配成功得到driver结构体地址

                if (!strcmp(name, entry->name))
                   return entry;
              }

           device_bind_common(parent, drv, info->name, (void *)info->platdata, 0, ofnode_null(), platdata_size, devp);

            ret = uclass_get(drv->id, &uc);            

              struct uclass *uc;

              uc = uclass_find(id);              

              if (!uc)

                return uclass_add(id, ucp); //通过上面得到的drv中的id字段(UCLASS_ROOT)进行匹配,匹配成功得到对应的uclass_driver结构体地址

              uc->uc_drv = uc_drv;  //uclass root的uclass_driver指向uclass_driver root   

              INIT_LIST_HEAD(&uc->sibling_node);
              INIT_LIST_HEAD(&uc->dev_head);
              list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);

            .......

            //关键代码如下

            INIT_LIST_HEAD(&dev->sibling_node);
            INIT_LIST_HEAD(&dev->child_head);
            INIT_LIST_HEAD(&dev->uclass_node);

            dev->name = name;

            dev->node = node;

            dev->parent = parent;

            dev->driver = drv;

            dev->uclass = uc;

            ......

            ret = uclass_bind_device(dev);

              uc = dev->uclass;

              list_add_tail(&dev->uclass_node, &uc->dev_head);

---------------------------------------------------------------------------------------------------------------------------------------------

经过上述源码阅读,下面将上述关系用图的形式更直观的表现出来:

 

        

  

        

 

posted @ 2018-01-09 19:55  gs1008612  阅读(3345)  评论(0编辑  收藏  举报