uboot 2019 uclass、udevice
uboot 2019 uclass、udevice
uclass链表
drivers/core/uclass.c
uclass_get,根据uclass_id去get,如果没有find到,则调用uclass_add()将uclass添加到gd->uclass_root链表里,uclass是用UCLASS_DRIVER macro define的,他们被放置在section(".u_boot_list_2_"#uclass"_2_"#_name) section,放置在.u_boot_list_2_uclass_1和.u_boot_list_2_uclass_3之间(可以在u-boot.map里grep)
int uclass_get(enum uclass_id id, struct uclass **ucp) { struct uclass *uc; *ucp = NULL; uc = uclass_find(id); if (!uc) return uclass_add(id, ucp); *ucp = uc; return 0; }
static int uclass_add(enum uclass_id id, struct uclass **ucp) uc->uc_drv = uc_drv; INIT_LIST_HEAD(&uc->sibling_node); INIT_LIST_HEAD(&uc->dev_head); list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);
#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root)
20603: .u_boot_list_2_uclass_1 20605: .u_boot_list_2_uclass_2_backlight 20607: 0x000000002758f628 _u_boot_list_2_uclass_2_backlight ... .u_boot_list_2_uclass_3
udevice加入uclass的dev_head链表
lists_bind_fdt()
(lists_bind_fdt是被initr_dm()调用的,initr_dm在initr_dtbo()执行之后执行)
将U_BOOT_DRIVER define的struct里的udevice_id里的compatible和device tree里的compatible相比较,如果相等,则将U_BOOT_DRIVER define的driver和对应的uclass相绑定,将udevice加入uclass的dev_head链表中:
int uclass_bind_device(struct udevice *dev) { struct uclass *uc; int ret; uc = dev->uclass; list_add_tail(&dev->uclass_node, &uc->dev_head);