完整编译 u-boot-next-dev:
./make.sh rk3568 2>&1 >log.txt
生成两个主要的文件是:
RKLoader:rk356x_spl_loader_v1.08.111.bin
Uoot FIT Image:uboot.img
两个都是有特定格式的混合文件。
RKLoader 的生成,是下面的指令:
E:\Dev\EE\Rockchip\u-boot-next-dev\make.sh:
function pack_loader_image()
{...
scripts/loader.sh rkbin\RKBOOT\RK3568MINIALL.ini
....}
E:\Dev\EE\Rockchip\u-boot-next-dev\scripts\loader.sh:
...
./tools/boot_merger ${INI}
...
E:\Dev\EE\Rockchip\rkbin\RKBOOT\RK3568MINIALL.ini:
综上,最小版 RKLoader 的生成, 至少依赖如下三个文件:
rkbin/bin/rk35/rk3568_ddr_1560MHz_v1.08.bin
rkbin/bin/rk35/rk356x_usbplug_v1.08.bin
rkbin/bin/rk35/rk356x_spl_v1.11.bin
这三个文件是 github 上的 rkbin 项目里面的, 不开源。
但是 Rockchip_Developer_Guide_UBoot_Nextdev_CN.pdf 文档中说:
RK平台根据前级Loader代码是否开源,目前有两套启动方式:
// 前级loader闭源
BOOTROM => ddr bin => Miniloader => TRUST => U-BOOT => KERNEL
// 前级loader开源
BOOTROM => TPL => SPL => TRUST => U-BOOT => KERNEL
TPL 相当于 ddr bin,SPL 相当于 miniloader。TPL+SPL 的组合实现了跟 RK 闭源 ddr.bin+miniloader 一致的功能,可相互替换。
TPL是比U-Boot更早阶段的Loader,TPL运行在SRAM中,
其作用是代替ddr bin负责完成DRAM的初始化工作。
TPL是代码开源的版本,ddr bin是代码闭源的版本。
既然说可以替换,那:
完整编译是这样:
make rk3568_defconfig
./make.sh rk3568 2>&1 >log.txt
pack loader okay! Input: /mnt/e/Dev/EE/Rockchip/rkbin/RKBOOT/RK3568MINIALL.ini
完整编译过一次后,可以使用 tpl + spl 重新生成 loader.bin :
./make.sh --tpl --spl 2>&1 >>log.txt
pack loader(TPL+SPL) okay! Input: /mnt/e/Dev/EE/Rockchip/rkbin/RKBOOT/RK3568MINIALL.ini
综上可得:
闭源RKLoader = ddr bin + usbplug + Miniloader
开源RKLoader = uboot TPL + usbplug + uboot SPL
uboot TPL 应该是做了跟 ddr_bin 一样的事(初始化ext_ddr_mem)是否还有其它功能未知。
编译好然后开始测试=>
替换TPL+SPL实测:失败!!只打印出下面一这行,就卡住不动了。
U-Boot TPL 2017.09 (Jan 21 2022 - 19:00:12)
然后 XSearch.exe 对 u-boot-next-dev 目录一通搜索 2017.09
再一通搜索 U_BOOT_VERSION
再一通搜索 U_BOOT_DATE
确认是这个文件的输出。
E:\Dev\EE\Rockchip\u-boot-next-dev\arch\arm\mach-rockchip\tpl.c
printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
U_BOOT_TIME ")\n");
简单说, tpl 只能跑到这个文件!官方的tpl也有问题?还是哪里有要设置的?
2022.02.12 补充:
rk3568 DDR初始化代码没有开源!
只能使用 rk3568_ddr_1560MHz_v1.08.bi
想查找问题在哪, 但是每次改完代码,重新编译的时间太久。
于是想把 tpl 相关的源文件扣出来,单独做一个叫 rkubootTPL 的项目单独编译。
于是乎开始分析 tpl 相关的源文件有哪些:
./make.sh
===========================================================
SRCTREE=`pwd`
SCRIPT_SPL="${SRCTREE}/scripts/spl.sh"
function process_args()
{
...
--tpl|tpl) # use tpl file
ARG_TPL_BIN="tpl/u-boot-tpl.bin"
...
}
function pack_idblock()
{
if [ ! -z "${ARG_TPL_BIN}" ]; then
TPL_BIN=${ARG_TPL_BIN}
fi
}
function pack_spl_loader_image()
{
rm *_loader_*.bin -f
cd ${RKBIN}
if [ ! -z "${ARG_SPL_BIN}" -a ! -z "${ARG_TPL_BIN}" ]; then
${SCRIPT_SPL} --ini ${INI_LOADER} --tpl ${SRCTREE}/${ARG_TPL_BIN} --spl ${SRCTREE}/${ARG_SPL_BIN}
elif [ ! -z "${ARG_TPL_BIN}" ]; then
${SCRIPT_SPL} --ini ${INI_LOADER} --tpl ${SRCTREE}/${ARG_TPL_BIN} #!!!!!!<----------------
else
${SCRIPT_SPL} --ini ${INI_LOADER} --spl ${SRCTREE}/${ARG_SPL_BIN}
fi
cd -
if [ -f ${RKBIN}/*_loader_*.bin ]; then
mv ${RKBIN}/*_loader_*.bin ./
fi
}
./scripts/spl.sh --ini /mnt/e/Dev/EE/Rockchip/rkbin/RKBOOT/RK3568MINIALL.ini --tpl ${SRCTREE}/tpl/u-boot-tpl.bin
./scripts/spl.sh ==> 其实应该叫 makeRKLoader_With_Tpl.sh
===========================================================
INI="/mnt/e/Dev/EE/Rockchip/rkbin/RKBOOT/RK3568MINIALL.ini"
TPL_BIN="/mnt/e/Dev/EE/Rockchip/u-boot-next-dev/tpl/u-boot-tpl.bin"
rm tmp -rf && mkdir tmp -p
TMP_INI="tmp/MINIALL.ini"
cp ${INI} ${TMP_INI}
cp ${TPL_BIN} tmp/tpl.bin
sed -i "s/FlashData=.*$/FlashData=.\/tmp\/tpl.bin/" ${TMP_INI}
sed -i "0,/Path1=.*/s/Path1=.*$/Path1=.\/tmp\/tpl.bin/" ${TMP_INI}
rm *_loader_*.bin -f
./tools/boot_merger ${TMP_INI}
其中 u-boot-tpl.bin 来自:cp tpl/u-boot-tpl-nodtb.bin tpl/u-boot-tpl.bin
#在 E:\Dev\EE\Rockchip\u-boot-next-dev\tpl\.u-boot-tpl.bin.cmd
u-boot-tpl-nodtb.bin来自:aarch64-linux-gnu-objcopy -j .text \
-j .secure_text\
-j .secure_data\
-j .rodata\
-j .data\
-j .u_boot_list\
-j .rela.dyn\
-j .got\
-j .got.plt\
-j .dtb.init.rodata\
-O binary\
tpl/u-boot-tpl\
tpl/u-boot-tpl-nodtb.bin
#在 E:\Dev\EE\Rockchip\u-boot-next-dev\tpl\.u-boot-tpl-nodtb.bin.cmd
也就是从 tpl/u-boot-tpl 文件导出来的,只是去除了一些无关的数据段
tpl/u-boot-tpl 来自:E:\Dev\EE\Rockchip\u-boot-next-dev\tpl\.u-boot-tpl.cmd
cmd_tpl/u-boot-tpl := (cd tpl &&
/mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-ld.bfd
-T u-boot-spl.lds --gc-sections -Bstatic --gc-sections
--no-dynamic-linker
-Ttext 0xfdcc1000
arch/arm/cpu/armv8/start.o
--start-group
arch/arm/mach-rockchip/built-in.o
arch/arm/cpu/armv8/built-in.o
arch/arm/cpu/built-in.o
arch/arm/lib/built-in.o
board/rockchip/evb_rk3568/built-in.o
common/init/built-in.o
disk/built-in.o
drivers/built-in.o
dts/built-in.o
fs/built-in.o
--end-group
-L /mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/6.3.1
-lgcc
-Map u-boot-tpl.map
-o u-boot-tpl
&& /mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-objdump -t u-boot-tpl > u-boot-tpl.sym
)
上面就是 tpl 编译流程,但范围还是太大,
还是得结合源码阅读 + u-boot-tpl.map + u-boot-tpl.sym分析的方式来扣出 tpl 相关的源文件。
待续。
2022.02.12 补充:
rk3568 DDR初始化代码没有开源!
只能使用 rk3568_ddr_1560MHz_v1.08.bin
其它内容:
E:\Dev\EE\Rockchip\u-boot-next-dev\.config
CONFIG_TPL_LDSCRIPT="arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
CONFIG_TPL_TEXT_BASE=0xfdcc1000
CONFIG_TPL_MAX_SIZE=61440
CONFIG_TPL_ROCKCHIP_BACK_TO_BROM=y
CONFIG_TPL_SYS_MALLOC_F_LEN=0x80000
CONFIG_SUPPORT_TPL=y
CONFIG_TPL=y
CONFIG_TPL_TINY_FRAMEWORK=y
CONFIG_TPL_SERIAL_SUPPORT=y
CONFIG_TPL_RAM=y
CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE=0
CONFIG_TPL_DM_SERIAL=y
... 过滤文件中所有带 TPL 的行
0xfdcc1000, 是上电时SYSTEM_SRAM的空间(总共64kb, 0xfdcc0000 - 0xfdccffff)
aarch64-linux-gnu-objdump -h ./tpl/elfBinFile #查看数据段
aarch64-linux-gnu-objdump -S ./tpl/elfBinFile #反汇编
TPL和SPL都使用arch/arm/cpu/armv8/start.S做为入口,只是两者编译时下的参数不一样。
E:\Dev\EE\Rockchip\u-boot-next-dev\tpl\arch\arm\cpu\armv8\.start.o.cmd
/mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -Wp,-MD,tpl/arch/arm/cpu/armv8/.start.o.d -nostdinc -isystem /mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/6.3.1/include -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -D__KERNEL__ -D__UBOOT__ -DCONFIG_SPL_BUILD -DCONFIG_TPL_BUILD -D__ASSEMBLY__ -g -D__ARM__ -mstrict-align -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -fno-common -ffixed-x18 -pipe -march=armv8-a+nosimd -D__LINUX_ARM_ARCH__=8 -I./arch/arm/mach-rockchip/include -c -o tpl/arch/arm/cpu/armv8/start.o arch/arm/cpu/armv8/start.S
E:\Dev\EE\Rockchip\u-boot-next-dev\spl\arch\arm\cpu\armv8\.start.o.cmd
/mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc -Wp,-MD,spl/arch/arm/cpu/armv8/.start.o.d -nostdinc -isystem /mnt/e/Dev/EE/Rockchip/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/6.3.1/include -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -D__KERNEL__ -D__UBOOT__ -DCONFIG_SPL_BUILD -D__ASSEMBLY__ -g -D__ARM__ -mstrict-align -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -fno-common -ffixed-x18 -pipe -march=armv8-a+nosimd -D__LINUX_ARM_ARCH__=8 -I./arch/arm/mach-rockchip/include -c -o spl/arch/arm/cpu/armv8/start.o arch/arm/cpu/armv8/start.S对比可以看到, SPL 编译时比 TPL 编译是少定义一个宏: -DCONFIG_TPL_BUILD
1.9 TPL/SPL/U-Boot-proper
U-Boot 通过使用不同的编译条件可以用同一套代码获取三种不同功能的Loader:TPL/SPL/U-Bootproper。
TPL:运行在 sram 中,负责完成 ddr 初始化;
SPL:运行在 ddr 中,负责完成系统的 lowlevel 初始化、后级固件加载(trust.img 和 uboot.img);
U-Boot proper:运行在ddr中,即我们通常所说的"U-Boot",它负责引导kernel;
U-Boot proper:翻译过来是“真正的U-Boot”的意思。
简单说是代码利用,定义不同的宏,可以编译出不同的代码(TPL/SPL/UBoot proper)
完整编译过一次 u-boot-next-dev 后,目录里面会 tpl 和 spl 两个文件夹。
tpl 文件夹里面有什么 .o 结尾的文件,说明 tpl 使用了对应的 .c .s 结尾的源文件。
.cmd 是对应的编译指令。
查看 E:\Dev\EE\Rockchip\u-boot-next-dev\tpl\u-boot-tpl.sym, 可得如下文件列表:
0000000000000000 l df *ABS* 0000000000000000 arch/arm/cpu/armv8/start.o
0000000000000000 l df *ABS* 0000000000000000 param.c
0000000000000000 l df *ABS* 0000000000000000 sdram.c
0000000000000000 l df *ABS* 0000000000000000 rk3568.c
0000000000000000 l df *ABS* 0000000000000000 clk_rk3568.c
0000000000000000 l df *ABS* 0000000000000000 bootrom.c
00000000fdcc1458 l O .data 0000000000000068 brom_ctx
0000000000000000 l df *ABS* 0000000000000000 tpl.c
0000000000000000 l df *ABS* 0000000000000000 rk_atags.c
0000000000000000 l df *ABS* 0000000000000000 cpu.c
0000000000000000 l df *ABS* 0000000000000000 generic_timer.c
0000000000000000 l df *ABS* 0000000000000000 cache_v8.c
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/cpu/armv8/exceptions.o
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/cpu/armv8/cache.o
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/cpu/armv8/tlb.o
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/cpu/armv8/transition.o
0000000000000000 l df *ABS* 0000000000000000 fwcall.c
0000000000000000 l df *ABS* 0000000000000000 cpu-dt.c
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/cpu/armv8/smccc-call.o
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/lib/crt0_64.o
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/lib/setjmp_aarch64.o
0000000000000000 l df *ABS* 0000000000000000 spl.c
0000000000000000 l df *ABS* 0000000000000000 zimage.c
0000000000000000 l df *ABS* 0000000000000000 bootm-fdt.c
0000000000000000 l df *ABS* 0000000000000000 sections.c
0000000000000000 l df *ABS* 0000000000000000 stack.c
0000000000000000 l df *ABS* 0000000000000000 tpl/arch/arm/lib/gic_64.o
0000000000000000 l df *ABS* 0000000000000000 interrupts_64.c
0000000000000000 l df *ABS* 0000000000000000 stacktrace_64.c
0000000000000000 l df *ABS* 0000000000000000 cache.c
0000000000000000 l df *ABS* 0000000000000000 psci-dt.c
0000000000000000 l df *ABS* 0000000000000000 board_init.c
0000000000000000 l df *ABS* 0000000000000000 sdram_common.c
0000000000000000 l df *ABS* 0000000000000000 sdram_rk3568.c
0000000000000000 l df *ABS* 0000000000000000 serial-uclass.c
0000000000000000 l df *ABS* 0000000000000000 ns16550.c
0000000000000000 l df *ABS* 0000000000000000 part.c
SoC Boot Stage(sram 阶段):
===================================================================
stage1:
代码:Soc rom with system_sram
作用:search TPL -> copy TPL into system_sram -> jumpto TPL
stage2:
代码:TPL with system_sram => SPL with ddr_mem
作用:init ext_ddr_ram -> copy SPL_in_sytem_ram into ext_ddr_ram
-> jumpto SPL_in_ext_ddr_ram
=> SPL 加载 u-boot FIT Image,解包,jumpto bl31stage3:
代码:u-boot-proper、bl31、bl32、op-tee、OSKernel
作用:开始区分安全和非安全环境,并初始化之,
让安全环境运行 op-tee,
让非安全环境运行 u-boot-proper, 继续后面的启动流程(比如加载 OSKernel 等)
这部分可能理解得有错。
参考:
EL0、EL1、EL2、EL3:RK3399——裸机大全 | hceng blog
百度 arm trustzone
注意:
u-boot-next-dev 编译要求系统里面必须必须得有 python2(可以从python3链接过来用)
如果没有 python2 ,编译出错信息只会一闪而过,make 流程不会停,
并且最后还是会生成 uboot.img,但运行不了。。。