typedef struct global_data {
...
#ifdef CONFIG_DM
struct udevice *dm_root; /* Root instance for Driver Model */
struct udevice *dm_root_f; /* Pre-relocation root instance */
struct list_head uclass_root; /* Head of core tree */
#endif
...
}
dm_root:DM模型的根设备
dm_root_f:重定向前的根设备
uclass_root:uclass链表的头
struct uclass {
void *priv; //uclass的私有数据
struct uclass_driver *uc_drv; //uclass类的操作函数集合
struct list_head dev_head; //该uclass的所有设备
struct list_head sibling_node; //下一个uclass的节点
};
uclass:来管理该类型下的所有设备,并且有对应的uclass_driver驱动。
uclass是uboot自动生成的,并且不是所有uclass都会生成,
有对应uclass_driver并且有被udevice匹配到的uclass才会生成。
所有生成的uclass都会被挂载gd->uclass_root链表上。
struct uclass_driver {
const char *name; // 该uclass_driver的命令
enum uclass_id id; // 对应的uclass id
/* 以下函数指针主要是调用时机的区别 */
int (*post_bind)(struct udevice *dev); // 在udevice被绑定到该uclass之后调用
int (*pre_unbind)(struct udevice *dev); // 在udevice被解绑出该uclass之前调用
int (*pre_probe)(struct udevice *dev); // 在该uclass的一个udevice进行probe之前调用
int (*post_probe)(struct udevice *dev); // 在该uclass的一个udevice进行probe之后调用
int (*pre_remove)(struct udevice *dev);// 在该uclass的一个udevice进行remove之前调用
int (*child_post_bind)(struct udevice *dev); // 在该uclass的一个udevice的一个子设备被绑定到该udevice之后调用
int (*child_pre_probe)(struct udevice *dev); // 在该uclass的一个udevice的一个子设备进行probe之前调用
int (*init)(struct uclass *class); // 安装该uclass的时候调用
int (*destroy)(struct uclass *class); // 销毁该uclass的时候调用
int priv_auto_alloc_size; // 需要为对应的uclass分配多少私有数据
int per_device_auto_alloc_size; //
int per_device_platdata_auto_alloc_size; //
int per_child_auto_alloc_size; //
int per_child_platdata_auto_alloc_size; //
const void *ops; //操作集合
uint32_t flags; // 标识为
};
uclass_driver主要通过UCLASS_DRIVER来定义
其定义之后都被存放在了段._u_boot_list_2_uclass_2_pinctrl中
UCLASS_DRIVER(pinctrl) = {
.id = UCLASS_PINCTRL,
.post_bind = pinctrl_post_bind,
.flags = DM_UC_FLAG_SEQ_ALIAS,
.name = "pinctrl",
};
struct udevice {
const struct driver *driver; //device 对应的driver
const char *name; //device 的名称
void *platdata;
void *parent_platdata;
void *uclass_platdata;
ofnode node; //设备树节点
ulong driver_data;
struct udevice *parent; //父设备
void *priv; // 私有数据的指针
struct uclass *uclass; //驱动所属的uclass
void *uclass_priv;
void *parent_priv;
struct list_head uclass_node; //挂到uclass上
struct list_head child_head;
};
udevice是最基础的一个设备单元
将udevice连接到对应的uclass中,uclass主要用来管理着同一类的驱动
udevice 由U_BOOT_DEVICE定义,存在段
.u_boot_list_2_driver_info_1
struct driver {
char *name; //驱动名称
enum uclass_id id; //驱动所对应的uclass_id
const struct udevice_id *of_match; //匹配函数
int (*bind)(struct udevice *dev); //绑定函数
int (*probe)(struct udevice *dev); //注册函数
int (*remove)(struct udevice *dev);
};
driver对象,主要通过U_BOOT_DRIVER来定义
定义之后都被存放在了段.u_boot_list_2_driver_2_xxx中
driver的头 :.u_boot_list_2_driver_1
uclass:作为udevice的一个属性,主要用来管理某个驱动类的所有的设备。
uclass_driver:uclass的驱动程序,主要将uclass管理的设备和驱动实现绑定、注册,移除等操作。
udevice与driver的绑定:通过驱动的of_match和compatible属性来配对,绑定。
udevice与uclass的绑定:udevice内的driver下的uclass_id,
来与uclass对应的uclass_driver的uclass_id进行匹配。
uclass与uclass_driver的绑定:已知udevice内的driver下的uclass_id,创建uclass的同时,
通过uclass_id找到对应的uclass_driver对象,然后将uclass_driver绑定到uclass上!
在u_boot_list_2_driver_2_xxx段查找"**root_driver**",并创建其uclass和udevice,二者进行绑定
#define DM_ROOT_NON_CONST (((gd_t *)gd)->dm_root)
dm_init()
->drv = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);//root_info.name = "root_driver",
-> drv = lists_driver_lookup_name(info->name);
->return device_bind_common(parent, drv, info->name,
(void *)info->platdata, 0, ofnode_null(), platdata_size,
devp);//devp为DM_ROOT_NON_CONST
struct uclass *uc;
uclass_get(drv->id, &uc);
dev = calloc(1, sizeof(struct udevice));
dev->driver = drv;
dev->uclass = uc;
->uclass_bind_device(dev);
uc = dev->uclass;
->list_add_tail(&dev->uclass_node, &uc->dev_head);
*devp = dev;//gd->dm_root = udevice(.name = "root_driver")
->device_probe(DM_ROOT_NON_CONST);//对root_driver进行probe,为空
U_BOOT_DRIVER(root_driver) = {
.name = "root_driver",
.id = UCLASS_ROOT,
};
;/从平台设备扫描udevice(U_BOOT_DEVICE定义)和uclass ,头为.u_boot_list_2_driver_info_1
dm_scan_platdata(pre_reloc_only);
//为空
.u_boot_list_2_driver_info_1
0x00000000ff92d280 0x0 drivers/built-in.o
.u_boot_list_2_driver_info_3
;/从设备树扫描udevice
dm_extended_scan_fdt(gd->fdt_blob, pre_reloc_only);
//parent 为gd->dm_root
->dm_scan_fdt_node(struct udevice *parent, const void *blob,)
->lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
struct driver *driver = ll_entry_start(struct driver, driver);
//driver的头 :.u_boot_list_2_driver_1进入扫描U_BOOT_DRIVER定义的driver
for (entry = driver; entry != driver + n_ents; entry++) {
ret = driver_check_compatible(entry->of_match, &id,
compat);
//将设备树中的"compatible"属性与driver的of_match属性进行匹配
ret = device_bind_with_driver_data(parent, entry, name,
id->data, node, &dev); //绑定
->device_bind_common(parent, drv, name, NULL, driver_data, node, 0, devp);