上篇分析了兩個關鍵巨集U_BOOT_DRIVER及U_BOOT_DEVICES的作用,有了上篇的基礎,本文將分析: 1.上篇中的uboot_list段中的信息如何被用起來? 2.uclass,uclass_driver,udevice,driver之間的關係? 從board_r.c中的initr_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);
---------------------------------------------------------------------------------------------------------------------------------------------
經過上述源碼閱讀,下麵將上述關係用圖的形式更直觀的表現出來: