ATF(Arm Trusted Firmware)/TF-A Chapter 02 BL1-ROMCode - Continued(1)

第二章目录:

Chapter 02.TF-A(Arm Trusted Firmware, ATF ) BL1-ROMCode

Chapter 02.TF-A(Arm Trusted Firmware, ATF ) BL1-ROMCode - Continued(1) (本文)

Chapter 02.TF-A(Arm Trusted Firmware, ATF ) BL1-ROMCode - Continued(2)

下一章:

Chapter 03.TF-A(Arm Trusted Firmware, ATF ) Chain of Trust (CoT)


先看porting guide的描述:

大意是在 MMU 和d-cache disabled的情况下执行(前面分析过i-cache已经开了),并且仅由主CPU调用。功能:

     启用SP805[S1] 的安全实例作为可信monitor程序。

     初始化UART(PL011[S2]控制台),在BL1中使用printf。

     允许向与包括主CPU的cluster相对应的CCI从接口发出snoop和DVM(分布式虚拟内存)请求。

该函数在\plat\arm\common\arm_bl1_setup.c 2行(weak实现)和\plat\arm\board\fvp\fvp_bl1_setup.c中都有实现,最终fvp_bl1_setup.c会覆盖arm_bl1_setup.c中的弱实现。


 [S1] SP805 TBD

[S2]ARM的一个UART IP

\plat\arm\board\fvp\fvp_bl1_setup.c->\plat\arm\common\arm_bl1_setup.c->:

默认ARM_DISABLE_TRUSTED_WDOG=0,执行sp805_start

初始化串口,设置trust ram信息。

 

返回到bl1_entrypoint执行44行的bl1_plat_arch_setup(\plat\arm\common\arm_bl1_setup.c)

调用arm_bl1_plat_arch_setup

在porting guide中,描述:

使能MMU。

先看mmap_region

一个元素MAP_BL1_TOTAL,展开后:

                   .base_pa = 0x04000 0000 + 0x1000

                   .base_va = 0x04000 0000 + 0x1000

                   .size = 0x0004 0000 -0x1000

                   .attr = MT_MEMORY | MT_RW | MT_ SECURE

                   .granularity = 1<<30,       

 

PAGE_SIZE在xlat_tables_aarch64.h中定义,为4KB

 

第二个元素

Include/common/bl_common.h

展开后:

                   .base_pa = 0x0000 0000

                   .base_va = 0x0000 0000

                   .size = 0x0000 4000          //16K

                   .attr = MT_CODE| MT_ SECURE

                   .granularity = 1<<30,       

                   .base_pa = 0x0000 4000

                   .base_va = 0x0000 4000

                   .size = 0x0000 4c38 //16K

                   .attr = MT_CODE| MT_ SECURE

                   .granularity = 1<<30,       

注意BL_RO_DATA_BASE实际上用import_sym宏定义的,即定义一个变量的同时给它赋值,这个值来自于ld链接脚本

继续arm_bl1_plat_arch_setup,126行

在\plat\common\plat_common.c中定义的

Plat_arm_get_map在\plat\arm\common\arm_common.c中定义,在bl1会返回结构体:

其结构了bl-regions相同,都使用MAP_REGION_FLAT定义一个mmap,内容为plat使用的地址范围和属性

Arm称这个设置方式为静态区域和配置,一旦使能MMU,就不能修改器地址的属性和范围,虽然静态和动态区域的定义不是基于MMU的状态,但两者仍然通过代码联系起来。只能在调用init_xlat_tables()之前添加静态区域,并且在MMU仍处于关闭状态时必须调用init_xlat_tables()。因此,一旦启用MMU,就无法添加静态区域。可以在打开或关闭MMU的情况下添加动态区域。调用流程如下所示:

  1. MMU关闭。
  2. 添加一些静态区域,添加一些动态区域。
  3. 基于mmap区域列表初始化转换表(使用init_xlat_tables *()API)。
  4. 此时,不再可能添加静态区域。仍然可以添加或删除动态区域。
  5. 启用MMU。
  6. 可以继续添加或删除动态区域。

由于静态区域是在boot时早期添加的,并且都在平台初始化代码的控制之下,因此mmap_add *()不会失败,不会返回任何错误代码。

MMU和xlat库后面专门章节分析.

 

继续arm_bl1_plat_arch_setup,从setup_page_tables返回后执行enable_mmu_el3(0) 使能MMU。从之前的region看都为platmap,主要目的是通过MMU保护地址访问。

继续arm_bl1_plat_arch_setup,arm_setup_romlib,USE_ROMLIB =0 时是空函数。

至此arm_bl1_plat_arch_setup执行完

2.5 Bl1_main.c

Bl1/aarch64/bl1_entrypoint.S->bl1_entrypoint,第51行,进入c代码main

Main主要工作:

  1. Ensure that MMU/Caches and coherency are turned on
  2. Perform remaining generic architectural setup from EL3
  3. Initialize authentication module if required
  4. Perform platform setup in BL1.
  5. Get the image id of next image to load and run.

 

在porting guide中:

  1. 该函数是在MMU和cache使能的情况下执行的。 它负责执行在启用MMU和数据高速缓存后可能发生的任何其余特定于平台的设置。
  2. 如果需要支持多个引导源,则初始化plat_try_next_boot_source()使用的引导顺序。
  3. 在Arm标准平台中,此函数初始化用于加载下一个引导加载程序映像的存储抽象层。

在145行,

重点看149行,在plat/arm/common/arm_dyn_cfg.c,122行,首先load TB_FW_CONFIG    

先说明下Trust boot加载bl的逻辑设计:

  1. Boot Loader阶段的动态配置
  2. 在cold boot期间初始化和执行前三个阶段
  3. EL3运行时软件的规范(AArch64的BL31和AArch32的BL32)替代可信引导固件使用的入口点要求代替提供的BL1和BL2

Cold boot期间的动态配置

如果platform需要,每一个boot loader阶段都可以动态配置。 Boot Loader阶段可以选择指定固件配置文件firmware configuration和/或硬件配置文件hardware configuration:

  1. HW_CONFIG - 硬件配置文件。 可以由所有Boot Loader阶段以及Normal World Rich OS共享。
  2. TB_FW_CONFIG - 可信引导固件配置文件。 在BL1和BL2之间共享。
  3. SOC_FW_CONFIG - SoC固件配置文件。 由BL31使用。
  4. TOS_FW_CONFIG - 可信操作系统固件配置文件。 由Trusted OS(BL32)使用。
  5. NT_FW_CONFIG - 非可信固件配置文件。 由不可信固件(BL33)使用。

Arm开发平台(包括了fvp和juno)使用Flattened Device Tree(FDT)格式作为动态配置文件。

每个Boot Loader阶段可以通过寄存器将最多4个参数传递到下一个阶段。 BL2通过arg0将下一个image的列表传递给EL3 runtime程序(AArch64的BL31和AArch32的BL32)。 所有其他参数都是平台定义的。 Arm开发平台使用以下约定:

  1. BL1通过arg1将meminfo_t结构的地址传递给BL2。此结构包含BL2可用的内存layout。
  2. 当存在动态配置文件时,第一个有效参数是下一阶段的Boot Loader 的固件配置,第二个有效参数是硬件配置,例如,
    1. 如果BL1加载TB_FW_CONFIG,则配置信息的地址通过arg0传递给BL2。
    2. 如果BL1加载HW_CONFIG,则其地址通过arg2传递给BL2。注意,arg1已经用于meminfo_t。
    3. 如果BL2加载SOC_FW_CONFIG,则其地址通过arg1中传递给BL31。注意,arg0用于传递可执行映像列表。
    4. 类似地,如果BL1或BL2加载HW_CONFIG,则其地址通过arg2传递给BL31。
    5. 对于其他BL3x映像,如果BL2加载了固件配置文件,则其地址通过arg0中传递,如果加载了HW_CONFIG,则其地址将在arg1中传递。

 

在看arm_load_tb_fw_config,首先说明几个比较重要的结构体:

其中

image_info_t

和param_header_t

主要是设置镜像类型为PARAM_IMAGE_BINARY,设置image的physical load address为

ARM_SHARED_RAM_BASE+ARM_SHARED_RAM_SIZE+sizeof(meminfo_t) =

0x04000000 +0x00001000 + 0x10 =0x04001010 。

image_max_size = 4K-0x10

设置好image info后,开始load fw config

 

 

arm_load_tb_fw_config->load_auth_image->load_auth_image_internal->load_image->io_xxx

主要的逻辑实现在load_auth_image_internal(common/bl_common.c, 230行)

load_auth_image_internal 工作主要分为两部分:认证image和load image

我们先不考虑认证image的情况,只分析load image。直接看252行和280行:

 

第一个参数image_id = TB_FW_CONFIG_ID

第二个参数image_data = arm_tb_fw_info.image_info

Load image实现在154行:

主要是通过plat_get_image_source 获取这个image的dev_handle (open,read,write一些ops)

将image load到image_data->image_base并更新image_data->image_size (之前并未给image_size赋值,只是给image_max_size赋值)

 

280行:

是在lib/aarch64/cache_helpers.S,44行定义的汇编函数,直接调用了一个汇编宏:

看下porting guide中的介绍:

至此load_auth_image执行完。继续执行。

继续arm_load_tb_fw_config:

看porting guide:

bl1_plat_get_image_desc(plat/common/palt_bl1_common.c,51行)返回一个static的BL2_IMAGE_DESC(35行):

同样是获取image_desc_t结构体,主要设置image_info类型为PARAM_EP,.image_info.image_base = BL2_BASE(BL2_AT_EL3=0的情况,否则ARM_TRUSTED_SRAM_BASE+128K+0x2000)

ARM_BL_RAM-BASE  0X04000 0000

ARM_BL_RAM_SIZE  0X0004 0000

PLAT_ARM_MAX_BL1_RW_SIZE     0xB000

PLAT_ARM_MAX_ROMLIB_RW_SIZE      0( USE_ROMLIB =0 ,否则0x1000)

BL2_BASE = 40035000(在lds中RAM的base)-PLAT_ARM_MAX_BL2_SIZE(0x11000或者TRUSTED_BOARD_BOOT=1时0x1D000)的位置

设置ep_info,类型为PARAM_EP,属性为 SECURE | EXECUTABLE,.ep_info.pc = BL2_BASE

这样就可以通过image_desc获取bl2的入口地址并配置mmu

153行,config_base就是arm_tb_fw_info.image_info.image_base,即通过TB_FW_CONFIG设置的配置信息,根据前面Cold boot期间的动态配置的描述,配置信息的地址要保存到arg0

 

在不考虑TRUSTED_BOARD_BOOT=1 && defined(DYN_DISABLE_AUTH)情况下,arm_load_tb_fw_config执行完。

继续arm_bl1_platform_setup,设置generic timer,具体实现TBD。

 

至此,bl1_platform_setup执行完,返回到bl1_main:

bl1_plat_get_next_image_id获取下一个即将跳转的image的id,并检查是否为bl2,如果是,则load bl2,否则将执行FWU流程(firmware update)

注意bl1_plat_get_next_image_id这个函数在bl1_main.c第22行,定义weak实现

在plat/arm/commonm/arm_bl1_setup.c

plat_arm_bl1_fwu_needed->arm_io_is_toc_valid

在fip中获取fwu的handle,否则在bl1_plat_get_next_image_id返回的就是BL2_IMAGE_ID

 


 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值