一,前言
之前解决ping问题的过程中,需要看uboot的代码,感觉看起来很轻松,我一直觉得代码写的小学生都能看懂的,这才是高手写的代码。面向对象设计的好,封装做的也好。虽然和qemu的Qobject设计雷同,但是我又手痒想画图了。
二,学习
1,uclass_find(id)
根据uclass id来找uclass。在gd->uclass_root中循环扫描,uc->uc_drv->id与id值进行比较
list_for_each_entry(uc, gd->uclass_root, sibling_node) {
if (uc->uc_drv->id == key)
return uc;
}
2,lists_uclass_lookup(id)
根据id来找uclass_driver,里面开头居然用了段地址。u_boot_list_2_为前缀,1为后缀,代表段开始。进行依次扫描,判断if (entry->id == id)就找到了。
#define ll_entry_start(_type, _list) \
({ \
static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN) \
__attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_1"); \
(_type *)&start; \
})
还有一个end的宏,里面也用了段地址结尾。u_boot_list_2_为前缀,3为后缀,代表段结束
#define ll_entry_end(_type, _list) \
({ \
static char end[0] __aligned(4) __attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_3"); \
(_type *)&end; \
})
ll_entry_declare用来定义的,猜测都是知道,2为后缀,代表段中的内容。
3,lists_driver_lookup_name与lists_uclass_lookup雷同,都是利用段地址范围来扫描的。
4,uclass_find_device(UCLASS_AHCI, 0, &dev);通过uclass的dev_head开始扫描找到dev。
uclass_foreach_dev(dev, uc) {
if (!index--) {
*devp = dev;
return 0;
}
5,看到很多uclass_find_device_byxxx,对应到udevice中有很多属性,name,seq,ofnode等等,这类api就是先通过uclass找到udevice然后和udevice中的属性对比。因为一般一个uclass可以有多个udevice。
三,小结
我喜欢通过画图来学习结构体对象,这样更有面向对象的设计感。
标签:__,Apple,--,boot,list,uclass,dev,id,uc From: https://blog.51cto.com/AppleCai/7893978