ARMV8 RK3399 u-boot TPL启动流程分析 --crt0.S

上一篇介绍到start.S 最后一个指令是跳转到_main, 接下来分析 __main 都做了什么

arch/arm/lib/crt0.S

__main 注释写的很详细,主要分为5步

  1. 准备board_init_f的运行环境

  2. 跳转到board_init_f

  3. 设置broad_init_f 申请的stack 和 GD

  4. 完整u-boot 执行relocate_code, 将u-boot 搬到board_init_f计算出的目的地址, tpl, spl 跳回crt0

  5. 设置board_init_r运行环境,完整u-boot 有些cpu 剩余工作由c_runtime_cpu_setup完成

  6. 跳转到board_init_r

详细分析如下:

  1. CONFIG_TPL_NEEDS_SEPARATE_STACK=1 CONFIG_TPL_STACK 0xff8effff

    复制代码
     bic	r0, r0, #7	/* 8-byte alignment for ABI compliance */
     mov	sp, r0
     bl	board_init_f_alloc_reserve
     mov	sp, r0
     /* set up gd here, outside any C code */
     mov	r9, r0
     bl	board_init_f_init_reserve
     bl	board_init_f_boot_flags
    
     bl	board_init_f
  2. board_init_f

代码位于arch/arm/mach-rockchip/tpl.c

CONFIG_SPL_FRAMEWORK=1

CONFIG_TINY_FRAMEWORK=n

CONFIG_DEBUG_UART=1

CONFIG_TPL_SERIAL=1

debug_uart_init => 到此可以用简单版的print, c标准printf 还不能用

rockchip_stimer_init => timer 相关,暂时用不到

2.1 spl_early_init

tpl/spl 中的大部分工作都是在这个函数中完成,代码位置 common\spl\spl.c, 主要完成

a. fdtdec_setup, 设置fdt,

b. dm_init_and_scan, 初始化所有挂在dm 架构上的驱动

tpl 中目前有如下几个,其中就包含了TPL 的主要功能,初始化DRAM, 即 .u_boot_list_2_driver_2_dmc_rk3399

.u_boot_list_2_driver_2_clk_fixed_rate

.u_boot_list_2_driver_2_clk_rk3399

.u_boot_list_2_driver_2_dmc_rk3399

.u_boot_list_2_driver_2_firmware

.u_boot_list_2_driver_2_generic_syscon

.u_boot_list_2_driver_2_psci

.u_boot_list_2_driver_2_rockchip_efuse

.u_boot_list_2_driver_2_rockchip_rk3399_pmuclk

.u_boot_list_2_driver_2_root_driver

.u_boot_list_2_driver_2_simple_bus_drv

.u_boot_list_2_driver_2_syscon_rk3399

2.2 返回BROM

back_to_bootrom 调用 longjmp(brom_ctx, BROM_BOOT_NEXTSTAGE);

x0 为 brom_ctx, x1 为BROM_BOOT_NEXTSTAGE=1

通过longjump 返回到上一篇中的setjmp 下一条指令,并且ret 被替换为longjmp 返回值,

ret=0, 可以boot next stage, 不过目前还不知具体原理,有了解的欢迎评论区讨论

/*

* To instruct the BROM to boot the next stage, we

* need to return 0 to it: i.e. we need to rewrite

* the return code once more.

*/

ret = 0;

复制代码
#if defined(CONFIG_TPL_ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_TPL_BOARD_INIT)
	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
#endif

ENTRY(longjmp)
	ldp  x19, x20, [x0,#0]
	ldp  x21, x22, [x0,#16]
	ldp  x23, x24, [x0,#32]
	ldp  x25, x26, [x0,#48]
	ldp  x27, x28, [x0,#64]
	ldp  x29, x30, [x0,#80]
	ldr  x2, [x0,#96]
	mov  sp, x2
	/* Move the return value in place, but return 1 if passed 0. */
	adds x0, xzr, x1
	csinc x0, x0, xzr, ne
	/* invalid icache for cortex a35 */
branch_if_a35_core x1, __asm_invalidate_icache_all
	ret
ENDPROC(longjmp)
相关推荐
_upupup16 小时前
Linux的调试工具——gdb/cgdb
linux·服务器
JeJe同学16 小时前
Docker镜像导入、容器启动
linux·运维·docker
Jason_zhao_MR16 小时前
Linux与实时控制如何兼得
linux·嵌入式硬件·机器人·工业控制
闲云野鹤在人间17 小时前
MySQL|从理论、安装、备份到主从复制、MHA高可用详解
linux·运维·数据库·mysql·云计算
一个风轻云淡18 小时前
GCC 和 GDB命令简单解读
java·linux·前端
H.莓飛18 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
资料库0118 小时前
Linux 8个常见运维故障排查
java·linux·运维
零基础12319 小时前
Ubuntu 常用命令汇总
linux·运维·开发语言
Android系统攻城狮20 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
xiaoqiMikko20 小时前
Linux 实战(一):CentOS 7、Rocky 9、Ubuntu 24.04 三台真机实测 —— 认清系统、换源、装包的版本坑
linux·centos