龙空技术网

U-Boot之代码重定向

linux与soc 360

前言:

而今同学们对“定向术语ddr”大约比较关注,咱们都需要了解一些“定向术语ddr”的相关内容。那么小编同时在网络上收集了一些对于“定向术语ddr””的相关知识,希望看官们能喜欢,大家快快来了解一下吧!

U-Boot是否要重定向,取决于其运行地址和链接地址是否相同。

链接、运行、加载地址

通常来说,当U-Boot运行于DDR时,无需重定向就可以运行起来。当U-Boot在NORFLASH、MMC、SPI FLASH等作为启动设备的存储介质中时,SoC内部的RAM空间通常无法满足U-Boot的需求,此时,需要U-Boot自身通过重定向功能实现程序的搬移。

下面三个比较关键的地址概念,分别是链接地址、运行地址、加载地址,在重定向的过程中起着非常重要的作用。

链接地址是U-Boot重定向后的执行地址,若重定向后在DDR上运行,那么链接地址是DDR内存中的地址。二次重定向一般为了给kernel留出运行空间,习惯将U-Boot重定向到高端内存区。链接地址通过在include/configs/xxx.h中设置CONFIG_SYS_TEXT_BASE来实现。

运行地址是U-Boot当前执行时的地址PC。假设U-Boot不需要重定向,那么运行地址一般也就时基于加载地址进行相应的偏移。若U-Boot需要重定向,那么重定向前的运行地址和加载地址无关,对于可以直接运行程序的存储介质,如NORFLASH,前期代码时直接映射到内部RAM或直接在NORFLASH上执行的位置无关代码。

加载地址同样需要考虑是否需要重定向,若需要重定向,那么加载地址一般是存储地址,若不需要重定向,那么加载地址、链接地址、运行地址意义基本一样。这个在单片机程序中最能体现的出来。

位置无关代码

U-Boot借鉴了共享库中广泛使用的位置无关技术。所谓的位置无关是指代码的执行所在的地址可以和链接地址不同,也就是不受链接地址的限制,可以将代码加载到任意的地方通过相对寻址的方式得到下一条指令的位置,从而继续执行。

通过反汇编u-boot我们发现,位置无关代码使用的是adr、ldr、b、bl等指令,基于当前PC值累加上计算出的地址偏移,得到要跳转符号的地址信息。

LDR汇编指令

LDR指令分为真指令和伪指令。如何区分真伪的方法就是看LDR最后一个参数前是否由“=”号。若由“=”号,则属于LDR伪指令。U-Boot重定向时使用到加载gd指针位置的代码属于LDR伪指令。伪指令的含义是将符号CONFIG_SYS_INIT_SP_ADDR的值赋给sp寄存器。

假设下面的语句变成ldr sp, CONFIG_SYS_INIT_SP_ADDR,那么含义就变了,它的含义是将CONFIG_SYS_INIT_SP_ADDR地址处的数据赋值给sp。

ADR汇编指令

ADR是基于当前PC值获取到相对地址,例如crt0.S中下面的adr指令,这条指令的含义是取得当前代码执行的pc值赋给lr,当程序执行完分支任务后用以返回。

relocate实现

U-Boot重定向是在完成cpu_init_cp15之后做的,此时对cpu核心进行基本的初始化,然后在可用的ram空间申请一片区域,用于存放global_data结构体,此结构体的作用是存放board_init_f函数所需的堆栈信息。

U-Boot重定向之后运行地址会发生变化,通常重定向之后代码运行于外部DDR空间,代码运行速度、资源空间大小都会得到极大的提高。在board_init_f函数中完成DDR初始化以及其他重定向使用到的模块。

重定向关键的数据结构是global_data,该结构体如下图所示:

GD空间分配函数:board_init_f_alloc_reserve(ulong top)

top参数在调用处r0,sp中,ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)。GD空间的分配要保证不会破坏掉C代码运行的堆栈空间,所以,通常在可用的SRAM空间顶端一段空间,这个顶端地址空间sp, CONFIG_SYS_INIT_SP_ADDR并将分配空间的低地址返回作为GD的堆栈指针SP。

CONFIG_SYS_INIT_SP_ADDR地址一定要是可读写的一片内存或SRAM区域。这个宏是在include/configs/xxx.h中定义,如下:

GD初始化函数:board_init_f_init_reserve(ulong base)

基于申请的GD空间,确定global_data的基地址,如果定义了CONFIG_SYS_MALLOC_F,那么实例化malloc_base,并将gd_base增加对应的偏移量CONFIG_SYS_MALLOC_F_LEN。接下来调用的board_init_f,每个SoC厂商或板级用户可根据自己的实际情况进行相应的代码开发,也可以使用官方提供的代码。

U-Boot重定向的过程,打开DEBUG宏开关,通过启动信息验证上面的分析:

标签: #定向术语ddr