03 TF-A

TF-A

一、概述

在上一节中,我们已经简单介绍过了TF-A

TF-A是一个开源的、可信赖的固件层,旨在为ARM Cortex-A处理器系列提供安全启动、初始化和运行时支持。在启动流程中,TF-A最先启动,它负责系统引导和硬件初始化。在上一节启动流程中我们已经讲过,在安全启动(Secure boot)模式下,在嵌入式Linux启动链条(Boot chain)中,TF-A经常作为FSBL来对硬件进行鉴权(authentication)。

二、TF-A的使用

1. 源码下载

从以上描述可以知道,TF-A是开源的,所有人都可以下载使用,但事实上,作为普通开发者,我们不太可能凭借一己之力来使用TF-A,这样的开发难度太大了。所以,TF-A源码大多是供半导体厂商使用,他们会对其进行修改,将自己的芯片产品添加进去。我们在实际的项目开发时,只需要使用半导体厂商提供的TF-A源码即可,意法半导体为开发者提供的是一个开发包:STM32MP1 OpenSTLinux Developer Package

意法半导体官方提供三种开发开发包:
在这里插入图片描述

选项简介
STM32MP1DevSTM32MP1Dev代表了STM32MP1开发板,这个SDK可以帮助开发者快速入门并熟练掌握STM32MP1系列芯片的各项特性和应用方法,我们需要下载这个SDK
Yocto_SDKaarch64是一个针对ARM架构aarch64的SDK,适用于基于Yocto Project构建的STM32MP1 Linux发行版
Yocto_SDKx86可在x86架构的计算机上使用,用于基于Yocto Project构建的STM32MP1 Linux发行版
2. 源码打补丁

下载好STM32MP1Dev后解压缩,我们可以看到在\stm32mp1-openstlinux-6.1-yocto-mickledore-mp1-v23.06.21\sources\arm-ostl-linux-gnueabi目录下有名为tf-a-stm32mp-v2.8.6-stm32mp-r1-r0的文件夹,这就是ST官方提供的TF-A固件目录,在其中有几个文件:

文件简介
0001-v2.8-stm32mp-r1.patchST官方提供的TF-A补丁文件
Makefile.sdk编译TF-A时使用的Makefile文件
README.HOW_TO.txtST官方的README文档
series存放补丁名称的文件
tf-a-stm32mp-v2.8.6-stm32mp-r1-r0.tar.xzTF-A源码压缩包

在开头我们已经说过,各大半导体厂商需要修改TF-A源码,将自己的芯片产品添加进去,才能正常编译和使用TF-A。打补丁的过程在正点原子的驱动开发手册中已经说的很详细了,在此不再赘述。

3. 编译TF-A

在虚拟机Ubuntu18.04中,打开终端,输入以下指令

进入刚才的tf-a-stm32-2.2.r1目录:

cd tf-a-stm32mp-2.2.r1/

使用上一层目录中的Makefile.sdk编译此目录中的内容:

make -f …/Makefile.sdk all

编译完成后,会在上一层目录生成一个build目录,其中包含三个子目录:opteeserialboottrusted,那么Makefile.sdk中到底有什么内容,它们分别起什么作用呢?让我们具体看一看。

三、TF-A的Makefile.sdk

1. #remove default variables

Makefile.sdk的开头,使用#remove default variables来说明了需要清除掉的变量内容,没有太多意义

#//此部分通常用来注释掉默认变量或清除之前的定义内容。
#remove default variable
LDFLAGS=
CFLAGS=
CPPFLAGS=
CC=
CPP=
AS=
AR=
LD=
NM=
2. 编译路径和EXTRA_OEMAKE

在此之后,在Makefile中指定了编译路径:

#// PWD 是目前所在目录路径,将其赋值给LOCAL_PATH,作用是指定编译路径
LOCAL_PATH=$(PWD)

下面一部分,我们主要聚焦于EXTRA_OEMAKE这个变量。在TF-Amakefile中,EXTRA_OEMAKE是一个环境变量,用于指定编译参数和目标环境配置。例如,在不同平台上可能需要针对 CPU 类型、内存大小等因素进行额外的编译配置。在这种情况下,我们可以通过设置EXTRA_OEMAKE这个变量来传递相应参数,并执行make命令时就能获得针对性的编译结果。具体的EXTRA_OEMAKE内容取决于目标平台的需求和项目要求。

此外,EXTRA_OEMAKE变量也可以用于设定一些自定义编译选项,比如打开或关闭某个功能模块等等。总之,在TF-A编译过程中,我们可以根据实际需求为EXTRA_OEMAKE设置合适的值,以便于得到更符合期望的编译结果。

#// 这一部分给EXTRA_OEMAKE赋予了更加具体的设定,比如CROSS_COMPILE指定了具体的交叉编译器, \
这里使用的是正点原子教程中指定的arm-none-linux-gnueabihf,arm代表是arm官方发布的, \
none表示没有特殊的备注,linux表示适用于linux系统,gnueabihf规定了具体的编译方式, \
这里的hf表示hard float。当然,我们也可以使用linaro发行的交叉编译器。DEBUG置1,表示debug模式开启, \
PLAT指定了具体的平台,ARCH指定了具体的架构,ARM_ARCH_MAJOR指定了aarch的版本号。

#// 之后的STM32MP_SDMMC、STM32MP_EMMC、STM32MP_SPI_NOR、STM32MP_RAW_NAND和 \
STM32MP_SPI_NAND几条命令,针对的是 STM32MP1 处理器中集成的各种接口所对应的功能模块, \
将其都置为1,那么编译器会引入与其对应的相关代码和库,以便在生成的固件中支持这些接口 \
(SD卡、EMMC、NOR、NAND)。

EXTRA_OEMAKE=CROSS_COMPILE=arm-none-linux-gnueabihf- DEBUG=1 LOG_LEVEL=40 PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_SPI_NOR=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1



#// 此段代码中的EXTRA_OEMAKE_SERIAL,是和串口相关的UART接口和USB接口, \
在编译过程中需要引入相关接口的功能。当这两个值都被置为1时,说明在当前编译配置下, \
TF-A 项目的编译结果将同时支持两种编程方式:UART 方式和 USB 方式。 \
用户可以根据自己的需要选择最合适的接口进行固件烧录。需要注意的是, \
在 STM32MP1 系列处理器开发过程中,有时可能会出现其他编程方式,如 JTAG 等。 \
在这种情况下,也需要适当调整 EXTRA_OEMAKE 变量的内容以适配这些接口。

EXTRA_OEMAKE_SERIAL= STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1



#// 此时我们编译的是TF-A,所以上面这一句是需要保留执行的,最终得到的是tf-a-xxxx-trusted.stm32文件, \
如果我们想得到和serialboot相关的内容,则需要将以上一句注释掉,转而执行下面的命令

#// 下面的代码也是和串口相关的,使用filte-out命令排除上述对于SD卡、EMMC、NOR和NAND的相关配置, \
只将UART和USB选项置为1,如此编译,将得到tf-a-xxxx-serialboot.stm32文件

EXTRA_OEMAKE_SERIAL=$(filter-out STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_SPI_NOR=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1,$(EXTRA_OEMAKE)) STM32MP_UART_PROGRAMMER=1 STM32MP_USB_PROGRAMMER=1

3. 默认设置

在这部分,Makefile设置了默认的配置选项

# Set default config

#// ELF_DEBUG_ENABLE 变量表示是否启用内建调试符号表,开发者可以选择在编译过程中是否添加调试符号表, \
从而控制编译后的固件大小和调试功能,这里的 ? 是bash扩展语法中的逻辑运算符,表示默认为1, \
如果编译过程中没有明确设置该变量,则按照默认值进行编译

#// TF_A_CONFIG 用于指定编译时所需的 TF-A 核心配置选项。TF-A 配置选项有许多种, \
例如内核版本、CPU 类型、固件压缩方式等等。编译成功后会在build目录中生成三个对应名称的文件夹

ELF_DEBUG_ENABLE ?= 1
TF_A_CONFIG ?=  trusted  optee  serialboot


# Set specific OEMAKE config

#// TF_A_CONFIG_OEMAKE 变量表示 TF-A 配置选项的额外 OEM 参数, \
后面的trusted、optee和serialboot则指定了 OEM 参数的多个实例。

#// trusted,"AARCH32_SP=sp_min":这是为 trusted 组件配置的选项。在这里, \
AARCH32_SP 通常用于指定 TF-A 的安全世界组件(Security Partition)的类型, \
sp_min 表示安全世界的最小配置(minimum),这种配置也被称为最小安全层。

TF_A_CONFIG_OEMAKE =  trusted,"AARCH32_SP=sp_min" optee,"AARCH32_SP=optee" serialboot,"AARCH32_SP=sp_min"


# Set default TFA_DEVICETREE

#// TFA_DEVICETREE 负责编译设备树文件,我们看到下列被注释掉的内容中包含了MP157系列的众多开发板, \
在后续编译是,如果保留它们,就会编译出很多对应的设备树文件,为了简化流程, \
我们只要求编译正点原子的设备树文件。

#TFA_DEVICETREE ?=   stm32mp157d-atk stm32mp157a-dk1 stm32mp157d-dk1 stm32mp157c-dk2 stm32mp157f-dk2   stm32mp157c-ed1 stm32mp157f-ed1   stm32mp157a-ev1 stm32mp157c-ev1 stm32mp157d-ev1 stm32mp157f-ev1 
TFA_DEVICETREE ?= stm32mp157d-atk

#Set default TF_A_ENABLE_DEBUG_WRAPPER

#// TF_A_ENABLE_DEBUG_WRAPPER 变量是一个开关标志,指示是否启用 Debug Wrappers 功能。 \
Debug Wrapper 是一种用于记录和传递调试信息的机制。它可以捕获处理器的状态、异常信息、 \
寄存器值和其他与调试相关的数据,并将这些数据传递给外部调试工具,如 JTAG 调试器或仿真器。 \
这对于分析嵌入式系统的问题、跟踪代码执行、查找故障和进行性能分析非常有用。

TF_A_ENABLE_DEBUG_WRAPPER ?= 1

4. help

使用Makefile文件时,开发者最初对编译的具体设置并不十分了解,这就需要一个模块来列举说明当前的编译配置,这就是help模块的作用,通过使用命令make help,我们可以获取当前的编译配置。

    help:
	@echo
	@echo "Available targets:"
	@echo "  all   : build TF-A binaries for defined config(s)"
	@echo "  clean : clean build directories from generated files"
	@echo
	@echo "TF-A configuration:"
	@echo "  TF_A_CONFIG = $(TF_A_CONFIG)"
	@echo "  TFA_DEVICETREE = $(TFA_DEVICETREE)"
	@echo "  ELF_DEBUG_ENABLE = '$(ELF_DEBUG_ENABLE)' ('1' to export elf files)"
	@echo "  TF_A_ENABLE_DEBUG_WRAPPER = '$(TF_A_ENABLE_DEBUG_WRAPPER)' ('1' to generate tf-a for debugging)"
	@echo
5. all

all 是一个构建目标(target)的名称。all 是一个常见的构建目标名称,如果没有明确指定其他目标,通常被定义为默认目标,在运行 make 命令时将会被构建。

在 TF-A 的 Makefile 中,all 通常代表构建整个 TF-A 固件,包括不同的组件和引导加载程序。构建 all 目标时,通常会触发一系列任务,以生成用于嵌入式系统引导的二进制文件。这些任务包括编译、链接、生成设备树二进制文件、生成引导映像等。

#// 在这里,all: tf意味着all的依赖项是tf
all: tf

#// host_tools 是一个变量,用于指定构建过程中需要在主机(开发计算机)上执行的工具。 \
这些工具通常用于生成或处理与 TF-A 构建相关的文件或数据。host_tools 变量列出了需要在主机上可用的工具, \
并在构建过程中使用这些工具来执行各种任务。

#// 之后的内容定义了 host_tools 目标的构建规则。它通过 $(MAKE) 命令在LOCAL_PATH目录中创建子目录/tools, \
并构建名为 stm32image 的文件。--no-print-directory 选项用于在构建过程中不显示子目录的构建信息, \
以保持输出内容的单一
host_tools:
	@$(MAKE) --no-print-directory -C $(LOCAL_PATH)/tools/stm32image


#// 通过在构建规则中指定 tf: host_tools,Make 工具确保在构建 tf 目标之前,会执行构建 host_tools 目标。
tf: host_tools

#// 最外层的循环遍历了上文(3. 默认设置)中 TF_A_CONFIG 所有的值("trusted"、"optee"、"serialboot"), \
迭代 TF-A 配置中的不同选项。
	for config in $(TF_A_CONFIG) ; do \
		# Init any extraoemake \
        # 此处对应了上文中的EXTRA_OEMAKE部分,初始化一个add_extraoemake 变量 \
		add_extraoemake= ; \
        # 此循环遍历了TF_A_CONFIG_OEMAKE中的所有额外OEMAKE配置选项 \
		for fullconfig in $(TF_A_CONFIG_OEMAKE) ; do \
            # 从内到位:echo $$fullconfig:使用 echo 命令输出 fullconfig 变量的内容, \
            也就是 TF_A_CONFIG_OEMAKE 变量中的一个元素。fullconfig 包含例如"trusted,"、"optee"的字符串; \
            cut -d',' -f1:使用cut命令来分割字符串;-d',':以逗号为界限进行分割;-f1:指定提取第一个字段, \
            即逗号之前的字段。 \
            # 合在一起,这个命令从 fullconfig 中提取配置选项名称,例如 "trusted" 或 "optee" \
			extraconfig=$$(echo $$fullconfig | cut -d',' -f1) ; \
            # 检查 extraconfig 和 config 这两个变量的值是否相等,如果匹配则执行后续命令 \
			if [ "$$extraconfig" = "$$config" ]; then \
                # 类似于上部分,这又是一个字符串分割和提取,依然是以逗号为分隔符, \
                提取逗号后的第二部分字段,比如之前的 "AARCH32_SP=sp_min" 以及其他配置, \
                并将其赋予之前初始化的add_extraoemake变量 \
				add_extraoemake=$$(echo $$fullconfig | cut -d',' -f2) ; \
			fi ; \
		done ; \
        # mkdir -p:按次序建立目录,这里在LOCAL_PATH目录下建立了/build目录, \
        并用使用各个配置$$config的名称命名其中的子目录,这里在/build目录下构建了三个子目录, \
        分别是/optee,/serialboot和/trusted \
		mkdir -p $(LOCAL_PATH)/../build/$$config ; \
        # test 命令是用于执行各种条件测试的 Bash 命令,-n 选项即检查一个字符串是否非空。 \
        对应的的条件就是"$(TFA_DEVICETREE)",即检测设备树文件的名称是否为空(对应的设备树文件是否存在) \
		if test -n "$(TFA_DEVICETREE)" ; then \
            # 检查通过,设备树文件存在,则进入循环,对于每一个TFA_DEVICETREE中的元素dt进行操作 \
			for dt in $(TFA_DEVICETREE) ; do \
                # 如果TF_A_CONFIG(tf-a配置)不是serialboot \
				if [ "$(TF_A_CONFIG)" != "serialboot" ]; then \
                    # 将EXTRA_OEMAKE的参数传给 make,并切换至LOCAL_PATH目录, \
                    使用dt中储存的设备树文件名称来进行编译 \
					$(MAKE) $(EXTRA_OEMAKE) -C $(LOCAL_PATH) DTB_FILE_NAME=$$dt.dtb BUILD_PLAT=$(LOCAL_PATH)/../build/$$config $$add_extraoemake ; \
				else \
                # 如果 TF_A_CONFIG 是 serialboot,则使用EXTRA_OEMAKE_SERIAL的参数传给make, \
                并切换至对应的目录进行编译 \
					$(MAKE) $(EXTRA_OEMAKE_SERIAL) -C $(LOCAL_PATH) DTB_FILE_NAME=$$dt.dtb BUILD_PLAT=$(LOCAL_PATH)/../build/$$config $$add_extraoemake ; \
				fi \
				# Copy binary file with explicit name \
                # 将构建好的.stm32文件拷贝并重命名,这一步之后,就会得到对应的stm32文件, \
                比如在tf-a-stm32mp157d-atk-trusted.stm32这个文件名中,stm32mp157d-atk对应$$dt(设备树名称), \
                trusted对应$$config(配置名称) \
				cp -f $(LOCAL_PATH)/../build/$$config/tf-a-$$dt.stm32 $(LOCAL_PATH)/../build/$$config/tf-a-$$dt-$$config.stm32 ; \
                # 在正点原子的教程中,编译tf-a之前必须安装stm32wrapper4dbg, \
                这个工具就是用来生成调试包(debug wrapper)的 \
				if [ "$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \
					# Generate wrapper for debugging \
                    # 生成调试包,-s命令指定了原始tf-a二进制文件的路径,例如,在编译好的/build/trusted目录中, \
                    原始tf-a文件名称为tf-a-stm32mp157d-atk.stm32;-d指定了调试包的输出路径, \
                    在这里会在/trusted目录中生成一个debug-tf-a-stm32mp157d-atk-trusted.stm32文件 \
					stm32wrapper4dbg -s $(LOCAL_PATH)/../build/$$config/tf-a-$$dt.stm32 -d $(LOCAL_PATH)/../build/$$config/debug-tf-a-$$dt-$$config.stm32 ; \
				fi \
			done ; \
		else \
            # 如果设备树文件不存在,则使用MAKE工具执行EXTRA_OEMAKE的配置,切换到LOCAL_PATH路径, \
            BUILD_PLAT指定了具体的构建路径,在这里还是生成一个/build目录,并在其中按照EXTRA_OEMAKE的配置, \
            依照不同的config值构建子目录,并对tf-a进行编译。接下来一行初始化了tf_version变量, \
            使用find指令来查找指定目录下名称匹配 tf-a*.stm32 模式的文件。在这里,它在目录  \
            $(LOCAL_PATH)/../build/$$config 下查找所有满足条件的文件。 \
            “-exec basename {}” 部分将找到的文件路径转换为文件名,去掉路径部分,以便后续处理。 \
            之后再使用 sed 命令,在输出中执行文本替换操作,将 .stm32 扩展名从文件名中去除, \
            以获得版本信息。最后,将上面的输出赋值给 tf_version 变量, \
            从而将 find 和 sed 命令的结果存储在 tf_version 变量中。 \
			$(MAKE) $(EXTRA_OEMAKE) -C $(LOCAL_PATH) BUILD_PLAT=$(LOCAL_PATH)/../build/$$config $$add_extraoemake; \
			tf_version=$$(find $(LOCAL_PATH)/../build/$$config -name tf-a*.stm32 -exec basename {} \; | sed "s/\.stm32//") ; \
			# Copy binary file with explicit name \
            # 和之前按设备树文件编译的流程一样,将构建好的.stm32文件拷贝并重命名, \
            得到对应的stm32文件。之后再使用stm32wrapper4dbg工具生成debug调试包 \
			cp -f $(LOCAL_PATH)/../build/$$config/$$tf_version.stm32 $(LOCAL_PATH)/../build/$$config/$$tf_version-$$config.stm32 ; \
			if [ "$(TF_A_ENABLE_DEBUG_WRAPPER)" = "1" ]; then \
				# Generate wrapper for debugging \
				stm32wrapper4dbg -s $(LOCAL_PATH)/../build/$$config/$$tf_version.stm32 $(LOCAL_PATH)/../build/$$config/debug-$$tf_version-$$config.stm32 ; \
			fi \
            # 在else分支中,由于没有指定的设备树文件,首选需要确定tf_version,也就是tf-a的版本号。 \
            之后只需按照EXTRA_OEMAKE配置进行编译 \
		fi ; \
		# Copy elf files with explicit name \
        # ELF_DEBUG_ENABLE 控制是否启用或禁用生成 ELF(可执行和链接格式)调试信息的功能
		if [ "$(ELF_DEBUG_ENABLE)" = "1" ] ; then \
            # 如果判定启动ELF调试信息,则意味着在编译过程中已经生成了.elf文件, \
            只需在下面判定文件是否存在,若存在,则拷贝值指定的路径即可。 \
            .elf文件未来会被用作bootloader,在不同的tf-a启动过程阶段(bl2和bl32)中用于引导和管理系统的安全性。 \
            指定的路径是两个,分别是optee、serialboot和trusted目录,以及各个bl2子目录中 \
			if [ -f $(LOCAL_PATH)/../build/$$config/bl2/bl2.elf ] ; then \
				cp -f $(LOCAL_PATH)/../build/$$config/bl2/bl2.elf $(LOCAL_PATH)/../build/$$config/tf-a-bl2-$$config.elf ; \
			fi ; \
			if [ -f $(LOCAL_PATH)/../build/$$config/bl32/bl32.elf ] ; then \
				cp -f $(LOCAL_PATH)/../build/$$config/bl32/bl32.elf $(LOCAL_PATH)/../build/$$config/tf-a-bl32-$$config.elf ; \
			fi ; \
		fi ; \
	done

6. clean

在Makefile中,clean部分通常用于执行清理操作。这意味着它的主要功能是删除构建过程中生成的临时文件、构建输出以及其他不再需要的文件,以便在下次构建之前保持工作目录的整洁和准备。

可以使用make distclean命令来执行clean

# 对于所有TF_A_CONFIG中的配置进行递归强制删除,在这里具体删除的就是/build目录, \
以及其中包含的/optee、/serialboot和/trusted三个子目录中的所有内容。 \
这样就能够保持工作目录的整洁,方便下一次重新编译时重新生成各种配置文件。
clean:
	@for config in $(TF_A_CONFIG) ; do \
		rm -rf $(LOCAL_PATH)/../build/$$config ; \
	done

四、TF-A启动流程简述

理解了Makefile.sdk后,我们大概了解了TF-A的编译配置和编译过程,下面我们转向存有TF-A源码的目录,根据正点原子教程提供的文件,我们的源码目录名称为tf-a-stm32mp1-2.2.r1,如果你使用的是更新版本,目录名称可能会有差异。

1. 不同阶段的BL

在TF-A的源码目录中,我们可以看到名为bl1、bl2、bl2u、bl31和bl32的bootloader子目录,这些对应的就是TF-A对应的启动阶段。TF-A的启动是链式的,不同的阶段有不同的功能,简图如下:

在这里插入图片描述

2. BL1

BL1 是第一个执行的阶段,被设计为 ROM 代码;它被加载并在内部 RAM 中执行。对于 STM32 MPU 来说,它并未被使用。由于 STM32 MPU 拥有自己专有的 ROM 代码,因此可以移除这部分,然后 BL2 成为执行的第一个 TF-A 二进制文件。

一般 BL1 要做的就是初始化 CPU,如果芯片支持不同的启动设备,那么还需要初始化不同的启动设置,比如 NAND、EMMC、SD、USB 或串口等。然后根据 BOOT 引脚的高低电平来判断当前所选择的启动设备,从对应的启动设备中加载 bl2 镜像,并放到对应的内存中,最后跳转到 BL2 镜像并运行。

3. BL2

TF-A 的 BL2 基于设备树配置。它使用与内核相同的设备树(例如源码目录中/fdts/stm32mp157d-atk.dtsi),但仅保留引导阶段的强制节点以减小二进制文件的大小。该设备树是最终 STM32 文件的一部分,以便被 ROM 代码验证并同时加载到 SYSRAM 中。

为了能够被 ROM 代码正确加载到 SYSRAM 中,TF-A BL2 固件需要封装在一个以 STM32 头部开头的二进制文件中。STM32 头部信息对于 ROM 代码加载、验证和启动固件是强制的。由于 ROM 代码只能加载单个二进制文件,STM32 文件必须在单个图像中嵌入头部、设备树和 BL2 二进制固件。

在这里插入图片描述

4. BL2U

BL2U 是Boot Loader Stage 2 Update(BL2U)的缩写。BL2U 是一个用于更新引导加载程序的一部分,通常位于 BL2 的下一个更新阶段。BL2U 主要负责引导加载程序的更新和升级,以确保系统能够加载新版本的引导加载程序或其他相关组件。

BL2U 的主要功能:

  • 引导加载程序更新: BL2U 负责加载和运行新版本的引导加载程序(通常是 BL2 的更新版本),以便引导系统到新的软件版本。

  • 验证和完整性检查: 在加载新引导加载程序之前,BL2U 可能会执行验证和完整性检查,以确保新的软件版本是受信任的,并且没有被篡改。

  • 回滚支持: 如果引导加载程序更新失败或新版本的引导加载程序存在问题,BL2U 可能支持回滚到之前的稳定版本,以确保系统的可用性和稳定性。

  • 配置更新: BL2U 可能还用于更新引导加载程序的配置,例如设备树或其他相关参数,以适应新的硬件或需求。

5. BL31

BL31 是 Boot Loader Stage 3.1 的缩写,BL31 是 TrustZone 技术中安全世界的一部分,主要负责初始化和管理系统的安全性和可信度。

BL31 的功能是确保系统的安全性、可信度和隔离。它为安全的执行环境提供了一个坚实的基础,并负责初始化和管理 TrustZone 安全状态的切换。BL31 通常由芯片制造商或系统设计者提供,以适应特定的硬件和安全需求。这使得系统能够安全地运行受信任的应用程序和服务,从而提供更高级别的安全性。

6. BL32

BL32 是 Boot Loader Stage 3.2 的缩写。BL32 也是 TrustZone 安全世界的一部分,它的主要任务是与 BL31 协同工作。

BL32 提供运行时安全服务,在 TF-A 中默认使用 sp_min。如前文所述 sp_min
是一个最小的 AArch32 安全负载(Secure Payload),整合了 PSCI 库以及 AArch32 的 EL3 运行时软件。sp_min 可以替代可信系统(TEE OS)或者可信执行环境(TEE),比如 OP-TEE。当然了,
STM32MP1 同时支持 sp_min 以及 OP-TEE,用户可以自行选择 bl32 使用哪个软件包。bl32 充当安全监控(secure monitor),因此它向非安全系统(non-secure os,比如 linux)提供了一些安全服务。非安全的应用软件可以通过安全监控调用(secure monitor calls)来使用这些安全服务,这些代码支持标准的服务调用,比如 PSCI。另外,bl32也支持ST32MP1所特有的一些安全服务,可以访问特有的安全外设,比如RCC、PWR、RTC 或 BSEC。

7. BL33

BL33 是 Boot Loader Stage 3.3 的缩写,通常被用作 Non-Secure Monitor 的一部分。BL33 负责引导非安全世界的操作系统或应用程序。我们一般使用 U-Boot 来作为BL33,实现对Linux bootfs的引导。到此为止,我们已经脱离了TF-A所处的安全世界,进入了供用户使用的非安全世界。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值