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);

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

經過上述源碼閱讀,下面將上述關系用圖的形式更直觀的表現出來:

 

        

  

        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM