一,前言
今天我主要先分析下bb black的relocate。至于为什么要分析这块内容,因为我个人理解,内存分布也是重要内容,最关键的是这些内容我3年前分析过TQ2440的,但是没分析过bb black的,所以补上。
二,实践
先在board_f.c中添加#define _DEBUG 1
就支持debug函数打印信息了。
U-Boot 2023.10 (Oct 27 2023 - 19:36:30 +0800)Apple Cai's am335 Board
U-Boot code: 80800000 -> 808807B8 BSS: -> 8088BEE8
CPU : AM335X-GP rev 2.1
Model: TI AM335x EVM
DRAM: get_ram_size return value is 20000000
Monitor len: 0008BEE8
Ram size: 20000000
Ram top: A0000000
Reserving 559k for U-Boot at: 9ff64000
Reserving 32896k for malloc() at: 9df44000
Reserving 92 Bytes for Board Info at: 9df43fa0
Reserving 256 Bytes for Global Data at: 9df43ea0
Reserving 80768 Bytes for FDT at: 9df30320
Reserving for stacks at: 9df30310
RAM Configuration:
Bank #0: 80000000 Bank #1: 0 Bank #2: 0 Bank #3: 0
DRAM: 512 MiB
New Stack Pointer is: 9df30300
Relocation Offset is: 1f764000
Relocating to 9ff64000, new gd at 9df43ea0, sp at 9df30300
Device 'clock@0' Driver 'ti_omap4_cm',drv->bind addr is 0x9ff8622d
Device 'clock@400' Driver 'ti_omap4_cm',drv->bind addr is 0x9ff8622d
直接从Ram top函数开始分析,我做了一个表格,记录了计算过程如下。
三,遇到的问题
- 我猜测是定义了CFG_SYS_SDRAM_BASE,通过打开每个头文件,找到了关键字
u-boot-2023.10/include/configs/am335_ap.h
u-boot-2023.10/include/configs/ti_am335x_common.h
u-boot-2023.10/include/configs/ti_armv7_omap.h
u-boot-2023.10/include/configs/ti_armv7_common.h
最后在ti_armv7_common.h中找到CFG_SYS_SDRAM_BASE的配置值为0x80000000。
- CONFIG_SYS_MALLOC_LEN和CONFIG_ENV_SIZE的值找了我老半天,它在.config中,但是defconfig中没有,于是想到了是否Kconfig中的默认值,果然在Konfig中看到了默认值。
config SYS_MALLOC_LEN
hex "Define memory for Dynamic allocation"
default 0x2000000 if ARCH_ROCKCHIP || ARCH_OMAP2PLUS || ARCH_MESON
config ENV_SIZE
hex "Environment Size"
default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
- reserve_fdt调用完成时gd->start_addr_sp = 0x9DF30320,接着reserve_stacks调用完成后gd->start_addr_sp = 0x9DF30310,然后就打印了,为什么还有16字节是什么时候做的减法?New Stack Pointer is: 9df30300 答:继续添加debug来打印。reserve_stacks调用完成后确实是0x9DF30310,后来发现arch_reserve_stacks里面不是空,因为_weak关键字就有可能其他c文件也有此函数,于是查map文件原来此函数是在arch/arm/lib/stack.c里面有继续再减去16。
- CFG_MAX_RAM_BANK_SIZE是(1024<<20)也就是1G,am335x芯片手册也写了1G,但是u-boot-2023.10/common/memsize.c中get_ram_size的返回值为什么是512M?导致后面setup_dest_addr打印出来Ram size: 20000000
int dram_init(void)
{
/* dram_init must store complete ramsize in gd->ram_size */
gd->ram_size = get_ram_size(
(void *)CFG_SYS_SDRAM_BASE,
CFG_MAX_RAM_BANK_SIZE);
return 0;
}
答:继续添加debug来打印信息看原因。果然返回的不是size不是传入的1G maxsize,此函数将数据写入地址0,1,2,4,8,然后依次读取对比,数据一致则内存大小倍增,不一致说明内存位置不可用,就返回size了,这属于uboot检测内存大小的机制。后来反应过来芯片手册写了支持1G,但是bb black外部的sdram芯片只有512M,所以就算配置为1G,显示可用的也只能是512M,是我糊涂了,哈哈~
- 看到汇编重定向后,直接用
ldr lr, =board_init_r
且注释写了自动重定向。若说是调试器只要我在此语句前,用新的地址加载elf即可,然后搜索symbol就可以到重定向后的地址,但是若不是调试器,代码运行的过程中自己是怎么知道这个symbol的地址变了?
答:之前我理解应该就是用地址无关的跳转指令,但是再具体些就不清楚了。百度后又了解了些关键内容。b是绝对地址跳转,bl是地址无关跳转。uboot要支持重定向,汇编指令就需要支持地址无关跳转和重定向符号表,uboot编译就要添加了LDFLAGS_u-boot += -pie,然后就会有rel.dyn字段用来管理加载地址和编译地址及符号表。这块具体细节还不太清楚,之后准备专门学习下。
四,小结
以前我学习uboot的时候没有DM,启动流程主要看网上,然后快速看了代码,也没有多思考数据来源及为什么这样设计,所以只是大概的了解,能做出些小作品为目的。本轮希望能更深入的学习,深度思考后才发现我还有很多不清楚的细节。挺好的,看来我这次第二轮刻意学习是起到做用的,又get到新的方法论及知识点了。
标签:uboot,Apple,--,地址,gd,ti,Reserving,ARCH,size From: https://blog.51cto.com/AppleCai/8071109