启动最早的ROM,它可以类比Boot Guard的ACM,
老狼:什么是Boot Guard?电脑启动中的信任链条解析269 赞同 · 44 评论文章编辑
不过它是在CPU的ROM里而不是和BIOS在一起,是一切的信任根。它的代码在这里:
代码很简单(略去不重要内容):
func bl1_entrypoint
....
bl bl1_early_platform_setup
bl bl1_plat_arch_setup
....
bl bl1_main
....
b el3_exit
endfunc bl1_entrypoint
bl1_main()开始就是c程序了,那c运行依靠的堆和栈空间在哪里呢?在CPU内部的SRAM里。SRAM一启动就已经可以访问了,bl1_plat_arch_setup()简单地在其中划分出来一块作为Trusted SRAM给c程序用,而不用像x86在cache里面扣一块出来,简单了很多。
BL1主要目的是建立Trusted SRAM、exception vector、初始化串口console等等。然后找到并验证BL2(验签CSF头),然后跳过去。
BL2:Trusted Boot Firmware
同样运行在EL3上的BL2和BL1一个显著的不同是它在Flash上,作为外置的一个Firmware,它的可信建立在BL1对它的验证上。它也有完整的源代码:
它也会初始化一些关键安全硬件和软件框架。更主要的是,也是我希望大家下载NXP 2160A的分支的重要原因,BL2会初始化很多硬件,而这些硬件初始化在x86中是BIOS完成的(无论是在PEI中还是包在FSP/AGESA中),而在ARM的ATF体系中,很多种CPU是在BL2中完成的。2160A在Plat目录下提供了很多开源的硬件初始化代码,供ATF BL2框架代码调用。比较重要的是bl2_main()
void bl2_main(void)
{
...
bl2_arch_setup();
...
/* initialize boot source */
bl2_plat_preload_setup();
/* Load the subsequent bootloader images. */
next_bl_ep_info = bl2_load_images();
...
bl2_run_next_image(next_bl_ep_info);
}
最重要的两步都在这个函数中完成:初始化硬件和找到BL31。
bl2_plat_preload_setup()中会初始化一堆硬件,包括读取RCW初始化Serdes等,对内存初始化感兴趣的人(比如我)也可以在里面找到初始化DDR4的代码:dram_init(),它在Plat\nxp\drivers\ddr\nxp-ddr下。比较遗憾的是DDR4 PHY的代码是个Binary,不含源码,这里对DDR4的初始化仅仅聚焦设置timing寄存器和功能寄存器,而没有内存的Training过程。
Anyway,x86带内初始化硬件的很多代码ARM ATF体系都包括在BL2中,而不在UEFI代码中,这是和x86 UEFI代码的一个显著区别。部分原因这些代码都要求是Secure的。更加糟糕的是,很多ARM平台,BL1和BL2,甚至后面的BL31都是以二进制的形式提供,让定制显得很困难。BL2能否提供足够的信息和定制化选择给固件厂商和提供足够信息给UEFI代码,考验BL2的具体设计实现。NXP在两个方面都做的不错,不但提供RCW等配置接口,还开源了大部分代码,十分方便。
<