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

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

    经过上述源码阅读,下面将上述关系用图的形式更直观的表现出来:

            

      

            

  • 相关阅读:
    Java基础(五):数组和Java方法
    Java基础(四):Java Number & Math 类、Character 类、String 类、StringBuffer & StringBuilder 类
    Java基础(三):修饰符、运算符、循环结构和分支结构
    Java基础(二):基本数据类型和变量类型
    Java基础(一):简介
    变量声明置顶规则、函数声明及函数表达式和函数的arguments属性初始化
    JS操作JSON常用方法
    站点的良好体验在网络优化中极为重要
    JVM基础(二) 实现自己的ClassLoader
    [DLX精确覆盖] hdu 3663 Power Stations
  • 原文地址:https://www.cnblogs.com/gs1008612/p/8253213.html
Copyright © 2020-2023  润新知