[Firefly-RK3399] Bootloader各个引导阶段直至加载Kernel的过程
Posted Neutionwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Firefly-RK3399] Bootloader各个引导阶段直至加载Kernel的过程相关的知识,希望对你有一定的参考价值。
1、BOOTROM阶段
BOOTROM的代码是Rockchip原厂芯片出厂时已烧录的代码,目的是从各个存储媒介中加载miniloader(tpl + spl),以下摘自RK3399芯片手册:
从图中可以看出BOOTROM会依次从Nor Flash、Nand Flash、eMMC、SD/MMC中校验ID BLOCK,由此便知道BOOTROM的存储媒介启动顺序为Nor Flash > Nand Flash > eMMC > SD/MMC。
2、SPL阶段
SPL阶段是U-Boot的前一级,SPL的目的也是加载U-Boot到内存,至于在加载哪一个存储媒介的U-Boot到内存,这个取决于dts的u-boot,spl-boot-order
结点,以下来自uboot/arch/arm/dts/rk3399-firefly.dts
:
chosen {
stdout-path = &uart2;
u-boot,spl-boot-order = &sdmmc, &sdhci;
};
我们看到既有sdmmc
,也有sdhci
,其实在dts中,sdmmc
就代表SD/MMC、sdhci
就代表eMMC,这里sdmmc
放得比sdhci
靠前,自然优先级就是SD/MMC > eMMC,也就是如果eMMC与SD/MMC存储媒介中都有U-Boot,则会优先加载SD/MMC中的U-Boot,这就是为什么我们一插进SD卡后,会直接加载SD卡的镜像。
注意:eMMC与SD/MMC存储媒介均有镜像,那么这个SPL本身是从eMMC中加载到内存的。
3、U-Boot阶段
U-Boot的根本目的是加载内核,同时给内核传参。RK3399加载内核是通过依次执行三条命令实现,以下来自uboot/include/configs/rockchip-common.h
:
#define RKIMG_BOOTCOMMAND \\
"boot_android ${devtype} ${devnum};" \\
"bootrkp;" \\
"run distro_bootcmd;"
我们看到RK3399首先执行boot_android
命令,这个命令是启动Android的Kernel使用的,当然这里的Android必须是GPT分区,以往Firefly-RK3399的Android 7.1是RK分区,这个命令不支持这种方式;第二条命令是bootrkp
,这个是启动Linux的Kernel使用的,最后一条是run distro_bootcmd
,我们来看一下distro_bootcmd
环境变量的定义,来自uboot/include/config_distro_bootcmd.h
:
"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \\
"for target in ${boot_targets}; do " \\
"run bootcmd_${target}; " \\
"done\\0"
我们可以看到它就相当于依次执行bootcmd_${target}
环境变量的内容,到目前为止,博主未使用过这个命令加载内核,只知道它是主线U-Boot加载Kernel的方式。
注意:U-Boot一旦加载Kernel成功便不会再返回,因此上述三条命令有且只有一条命令加载Kernel成功,否则U-Boot就会加载Kernel失败,然后进入U-Boot shell。
以上是关于[Firefly-RK3399] Bootloader各个引导阶段直至加载Kernel的过程的主要内容,如果未能解决你的问题,请参考以下文章
[Firefly-RK3399] U-Boot shell中增加saveenv命令
[Firefly-RK3399] U-Boot配置使用键盘与2.4G无线遥控