zoukankan      html  css  js  c++  java
  • 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);

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

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

     转自https://www.cnblogs.com/gs1008612/p/8253213.html

  • 相关阅读:
    poj 2560Freckles (krusual)
    ACRush 楼天成回忆录
    大腕版ACMICPC比赛
    POJ刷题
    DataGrid中添加DropdownList时的数据绑定
    【转帖】SQL Server各种日期计算方法(收藏)
    安全配置Win2000服务器
    C#写的一个代码生成器
    .Net 常用加密算法类
    实习之最
  • 原文地址:https://www.cnblogs.com/idyllcheung/p/12085349.html
Copyright © 2011-2022 走看看