第4章-U-boot驱动模型之一基本内容

1. 基本概念

1.1 全局数据global_data

某些情况下,u-boot在某些只读存储器上运行,如ROM,NorFlash等;在其重定位到RAM之前,无法写入数据或者通过全局变量传递数据,而global_data(也称GD)则可以解决这个问题

简单来说,u-boot把GD放在RAM区,使用它来存储全局数据, 以解决上述场景中无法使用全局变量的问题

GD数据结构

// include/asm-generic/global_data.h
typedef struct global_data {
    bd_t *bd;  // 保存开发板的相关参数
    unsigned long env_addr;     // 环境变量地址
    unsigned long ram_top;      // RAM空间的顶端地址
    unsigned long relocaddr;    // u-boot重定位后的地址
    phys_size_t ram_size;       // 物理ram的size
    unsigned long irq_sp;       // 中断的栈地址
    unsigned long start_addr_sp;    // stack地址
    unsigned long reloc_off;    // uboot的relocation的偏移
    struct global_data *new_gd; // 重定位后的GD结构体
    const void *fdt_blob;       // dtb地址
    void *new_fdt;              // 重定位后dtb地址
    unsigned long fdt_size;     // dtb的长度
    struct udevice *cur_serial_dev; // 当前使用串口设备
    ......
} gd_t;

初始化GD

// crt0.S
// 设置C运行时环境
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) // 设置栈顶SP指针,只是预设,并不是最终的栈顶地址
bic sp, sp, #7 // 8byte对齐
mov r0, sp  // SP放入r0
bl  board_init_f_alloc_reserve // 参数为r0,返回后,r0中存放的是GD的地址
mov sp, r0  // r0放入sp中
mov r9, r0  // r0放入r9中,即r0和r9存放的都是GD的地址
bl  board_init_f_init_reserve  // 对GD初始化,r0为参数

// 给GD分配空间,传入的是r0,即栈顶地址
ulong board_init_f_alloc_reserve(ulong top)
{
    // 自顶向下分配CONFIG_SYS_MALLOC_F_LEN大小内存, 用于在relocation前用于给malloc函数提供内存池(给堆用的)
    top -= CONFIG_SYS_MALLOC_F_LEN;

    // 继续向下分配sizeof(struct global_data)大小的内存给GD使用,向下16byte对齐
    top = rounddown(top-sizeof(struct global_data), 16);

    // 返回GD地址
    return top;
}

// 初始化GD分配的空间, 即清空global_data区域
// 传入的参数为GD的基地址
void board_init_f_init_reserve(ulong base)
{
    // 清零
    memset(gd_ptr, '\0', sizeof(*gd));

    // 获取了early malloc的内存池的地址(给堆使用)
    base += roundup(sizeof(struct global_data), 16);

    // 写入到gd->malloc_base中
    gd->malloc_base = base;

    // 获取early malloc的内存池的末尾地址
    base += CONFIG_SYS_MALLOC_F_LEN;
}

使用GD
根据上面可得GD的基地址存放在r9中,需要GD的时候,直接从r9寄存器中取的其地址即可

// arch/arm/include/asm/global_data.h
#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r9")

// common/board_r.c
DECLARE_GLOBAL_DATA_PTR

static int initr_reloc(void)
{
    // 直接使用gd变量即可
    gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
}

1.2 驱动模型引入

在U-boot中引入驱动模型(driver model),为驱动的定义和范文接口提供统一的方法,提高驱动间的兼容性以及访问的标准性,u-boot中的驱动模型(DM)和kernel中的设备驱动模型类似,但是也有所区别

通过宏定义CONFIG_DM使能驱动模型,对应的实际驱动设备则需要通过使能CONFIG_DM_SERIAL来使能;后面以serial驱动为例

1.2.1 uclass/udevice/drivers三者之间的关联

uclass可以理解为具有相同属性的device对外操作的接口, 它与上层接口直接通讯,其驱动为uclass_driver,给上层提供接口
udevice对具体设备的抽象,对应的驱动是driver; driver负责和硬件通讯,为uclass提供实际的操作集
udevice如何和uclass绑定:udevice对应的driver_iduclass对应的uclass_driver_id是否匹配
hardware对应的driver绑定对应的udevice,udevice绑定uclassuclass有其对应的uclass_driver

uclass和udevice是动态生成的

  1. udevice在解析fdt中的设备的时候自动生成,然后udevice找到对应的driver
  2. driver中保存了uclass_id, 根据它找到uclass_driver_id
  3. uclass链表中查找对应的uclass是否已经生成,若没有生成,则动态生成
  4. 重点是解析设备树,生成udevice, 并找到对应的driver

u-boot驱动模型

1.2.2 全局数据GD中和DM相关部分

typedef struct global_data {
   // dts中的根节点,第一个创建的udevice
   struct udevice  *dm_root;

   // relocation之前的根设备
   struct udevice  *dm_root_f;

  // uclass的链表, 挂的是有udevice的uclass
   struct list_head uclass_root;  
} gd_t;
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

踏马潜行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值