Uboot重定位
一、重定位的意义
uboot的重定位有两次,第一次是在编译成镜像后,在makefile中调用进行处理的,其调用tools/riscv_prelink.c的代码进行重定位处理(主要就是对重定位表中的R_RISCV_RELATIVE和R_RISCV_64/32类型的重定位项进行处理,将其中的各项重定位到链接地址)
makefile中的处理代码如下:
ifeq ($(CONFIG_RISCV),y)
@tools/prelink-riscv $@
endif
第二次的重定位发生在board_init_f阶段后,这次重定位的意义在于将uboot自己搬到高端内存(高地址),而给kernel腾出空间,一般kernel都会加载到低端位置比如0x80200000。这次重定位的内容与第一次应该是相似的,只不过当前需要修改地址搬移后的地址。实际的重定位操作如下所示。
R_RISCV_RELATIVE:相对重定位类型,在修改时只需要将.rela.dyn表项中对应entry的address加上代码offset得出地址值A,addend加上代码的偏移得出地址值B,然后将B写入A所指示的内存中
R_RISCV_64 :绝对重定位类型,在修改时需要将symbol index取出,然后去.dynsyn查找对应的st_value字段,这个字段里装着该符号的地址C(函数或者变量的地址),然后将该地址C加上addend和offset后存入.rela.dyn表项中对应entry的address加上代码offset得出的地址。
二、介绍一些重定位相关的表项结构(节)
.rel.dyn 包含了需要重定位的变