当前位置: 首页 > news >正文

SOC- armv8 启动流程和安全启动

一、启动的软件架构,即bootloader 有哪几部分

(1)芯片的bootrom 固件,每个芯片厂家不一样;

(2)ATF 固件,即 arm-trusted-firmware; 有一个开源的ATF:TF-A/trusted-firmware-a.git - TrustedFirmware Git 浏览器

(3)uboot;

  (4) kernel;(不算bootloader 的范畴)

二、启动流程

        Armv8的启动流程包含多个阶段,典型地有BL1、BL2、BL31、BL32、BL33,根据需求的不同,这些阶段可以适当地裁剪或添加。为了方便描述,后面我们的讨论将基于以上这些官方定义的标准阶段,它们的源码会被编译成独立的启动镜像,并被保存到特定的存储介质中。由于一般的存储介质(如spi flash、nand flash、emmc、ssd等)都不支持代码的直接执行,因此需要在启动时先将镜像加载到可直接执行代码的存储介质,如SRAM或DDR中,然后运行相关代码。其典型的加载流程如下:

        

  1. BL1是启动的第一阶段,该镜像必须要存储在可直接执行的介质中。若芯片支持XIP启动方式,其可被存储在片外可直接执行的介质中(如norflash)。若不支持XIP,则需要存储在芯片的片内ROM中,此时在芯片出厂后该部分代码就将被固化,后续再也不能被修改和升级。若芯片要支持安全启动,则需要将bootrom作为启动时的信任根,此时除调试阶段外,SOC必须禁用XIP。关于安全启动我们在第三部分介绍;
  2. BL2镜像由BL1加载,此时DDR还没有被初始化,因此它需要被加载到片内的SRAM中执行,一般在这个阶段会完成DDR的初始化,因此后面的镜像都可以被加载到DDR中。从上图可知,BL31、BL32和BL33都是由BL2加载的,其中BL31和BL32是可选的,若系统不支持TRUST OS,则可去掉BL32,若不支持EL3异常等级及secure monitor,则可去掉BL31
  3. BL33一般指uboot,一般通过它最终启动操作系统内核

        Armv8架构典型的启动流程如下:

以上流程中我们假定系统支持的最高异常等级为EL3,且支持secure monitor和TRUST OS,同时BL2运行在secure EL1,BL33运行在non secure EL1或non secure EL2状态
(1)由于armv8架构规定,arm核复位后默认会进入当前系统支持的最高异常等级,因此BL1运行在EL3,它执行完成后会通过异常返回ERET的方式跳转到BL2
(2 - 3)BL2执行完成后需要跳转到BL31,由于BL31运行在EL3异常等级,而BL2根据需求不同可能运行于secure EL1或EL3。当BL2运行于EL3时可直接通过ERET方式跳转到BL31中,但若其运行在secure EL1时,则只能通过smc异常触发进入EL3异常等级。
  显然,此时BL31由于尚未设置其自身的smc异常处理程序而无法直接处理该异常,因此,为了完成跳转流程,BL1需要先代理该异常的处理。因此BL1在退出之前先设置smc异常处理函数,BL2触发smc启动BL31时,BL1捕获该异常并根据BL2传入的参数设置BL31的入口地址和系统初始状态,并通过ERET跳转到BL31的入口地址处执行
(4)BL32阶段会运行TRUST OS,它运行于secure EL1异常等级,BL31可根据其镜像加载信息设置入口地址以及其它状态,并完成跳转
(5 - 6)BL32加载完成后将通过SMC返回到BL31,然后由BL31跳转到non secure EL1或non secure EL2以执行BL33

上面这部分总结就是:如何通过异常处理,来启动整个 bl1,bl2, bl31,bl32,bl33;

三、TF-A 安全启动

在Armv8架构里,ARM为安全引入了Trust Firmware作为整体解决方案,开源库地址:TF-A/trusted-firmware-a.git - TrustedFirmware Git 浏览器

根据官网介绍,TF为Armv8-A和Armv8-M提供了安全软件的参考实现,为SoC开发人员和oem提供了符合相关Arm规范的参考可信代码库。,各家厂商基于这个进行DIY。

 

其中,

TF-A (Trusted Firmware-A,也叫ATF)是专门为Armv7\v8-A架构内核设计的参考安全固件;
TF-M则是为Armv8-M、Armv8.1-M架构(如Cortex-M33、M55等)提供了安全处理环境(SPE,Secure Processing Environment)的参考实现。

 TF-A(AArch64)的启动引导过程一共分为5个单独启动阶段,每个阶段运行在不同的内核异常等级,流程如下:

 每个阶段功能定义如下:

  • BL1(Boot Loader stage 1):BL1一般指运行存放在芯片内部BootROM的代码,这部分代码由SoC厂商在芯片流程时固化进去,不能再做修改;该阶段运行在Armv8的EL3等级,如果支持安全启动,BootROM在构建信任链的时候就显得尤为关键,主要用于校验BL2 Boot Firmware并完成加载和跳转,这也是和目前接触过的车规MCU安全启动流程最明显的区别;
  • BL2(Boot Loader stage 2:):Boot Firmware由BL1从引导介质中(例如NOR Flash、SD/eMMC)加载运行(例如DDR),它的主要作用是初始化平台所需要存储介质、配置MMU、校验BL31\32\33并完成加载等,值得注意,BL2依旧运行在EL3等级。
  • BL31(Boot Loader Stage 3-1):BL2加载BL31后,并把控制权交由BL31(此时仍旧运行在EL3等级),从上图可以看到BL31仍旧需要运行在可信RAM中,它主要为引导加载程序和操作系统提供初始化服务,例如GIC初始化、电源控制设备初始化、MMU使能和重定向等等;完成上述初始化后,如有BL32 trusted OS镜像,BL31加载BL32并跳转运行;
  • BL32:可信的操作系统,例如OP-TEE(Open source Project Trusted Execution Environment )、安卓Trusty TEE
  • BL33:常见的Bootloader(U-Boot/UEFI),运行在Armv8 EL2等级,完成启动后运行Kernel

 在开源库中每个阶段都可以单独进行编译,因此很明显启动流程可以根据需求进行裁剪,

但值得一提的是,上述启动流程有个前提假设:那就是这些镜像文件存储的物理介质一般都不支持xip,所以需要在启动时将上述镜像加载到SRAM或者DDR上运行;这是与带有eFlash的MCU的安全启动流程的另一个明显区别。

其实比较复杂一点的地方就是 BL31 的 secure monitor 和 BL32 的OP-TEE 可信操作系统;这是因为这个两个系统,不会把占用的内存进行回收,是一直占用内存,也是专业一点的名字就是runtime service ,提供运行时的服务。当有异常产生时,会调用里面的函数进行执行。这里不展开具体的代码展示。

提供OP-TEE的搭建说明:

里面有ARM V7和ARM V8两个架构的搭建说明,官方部分ARM V8的相关指令如下:

$ mkdir optee
$ cd optee
$ repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml
$ repo sync
$ cd build
$ make toolchains
$ make run

 由于国内访问有限制,需要在上面的基础上做一些简单的改动,修改repo默认的镜像源地址,如下即可:

Ubuntu 22.04/20.04


$ mkdir optee

$ cd optee
$ curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o ~/bin/repo
$ chmod a+x ~/bin/repo

$ export PATH=~/bin:$PATH
$ vim ~/.bashrc

//将以下内容添加到.bashrc的末尾
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'

//重新启动终端,继续以下命令
$ repo init -u https://github.com/OP-TEE/manifest.git -m qemu_v8.xml

$ repo sync

$ cd build

$ make toolchains

$ sudo make plat=qemu -j3 run

编译时间会比较长,另外如果是虚拟机的话,建议一开始存储内存就给的稍微多一些

执行完最后的命令后会出现三个终端(Normal World、Secure World、命令行shell终端)

在qemu后面输入c,启动两个系统的运行

其中Normal终端中的打印的为BL1 - BL3启动阶段,非安全部分的LOG,以及从BL3跳转到UBOOT并从UBOOT引导Linux的所有输出

Secure World为OP-TEE OS的输出LOG。

四、镜像跳转方式

前面我们聊到镜像跳转时可能需要使用到ERET或SMC指令,下面我们再看下跳转时的细节

4.1 Smc异常处理流程

        smc是armv8支持的异常跳转指令,它用于程序从EL1或EL2跳转到EL3异常等级。其跳转流程如下:

        以atf的BL1 smc处理流程为例,EL1调用者通过smc指令陷入到EL3异常,此后CPU将跳转到EL3异常向量表的vector_entry SynchronousExceptionA64入口处,该函数解析esr_el3寄存器的异常原因,若其为smc异常,就跳转到smc处理函数smc_handler64中。smc_handler64解析通过x0 – x7寄存器传入的参数获取smc命令类型,执行特定的命令处理函数,并通过寄存器x0 – x4返回处理结果。对于异常向量表跳转入口选择原则可参考以下博文:
lgjjeff:armv8中断路由机制

4.2 ERET跳转流程

ERET指令用于从异常处理流程中返回,在介绍异常返回流程之前,我们先看一下armv8异常跳转的流程。Armv8触发异常或中断后硬件将会执行以下操作:
(1)将PSTATE寄存器的内容保存到SPSR_ELx中,其中x表示异常进入的异常等级,如smc异常将会陷入EL3,因此相应的寄存器就为SPSR_EL3
(2)将异常处理完成后需要返回的地址保存在ELR_ELx中
(3)设置中断和异常掩码DAIF,以关闭所有中断和异常
(4)若异常是同步异常或SError中断,异常状态信息将被保存在ESR_ELx中,该信息可用于分析异常发生的原因
(5)若异常为指令异常、数据异常或对齐错误等,则触发异常对应的内存地址将被保存到FAR_ELx寄存器中
(6)栈指针切换为目标异常等级的栈指针寄存器SP_ELx
(7)程序跳转到对应的异常处理入口,执行异常处理程序
  在异常执行完成后,可通过ERET指令返回被异常中断程序的断点处继续执行,该指令将使硬件执行以下操作:
(1)用SPSR_ELx寄存器的内容恢复PSTATE寄存器
(2)用ELR_ELx寄存器的内容恢复PC值
  从以上流程可以看到,执行ERET指令后程序的执行流将由SPSR_ELx和ELR_ELx决定。因此,我们在执行镜像之间的跳转,只要在ERET之前将ELR_ELx设置为待跳转镜像的入口地址,并设置正确的SPSR_ELx即可完成

五、内存规划

5.1 内存规划原则

嵌入式系统的内存一般包含ROM、SRAM和DDR,其中ROM和SRAM位于SOC片内,DDR位于芯片外部。它们的特点如下:
(1)ROM中的内容断电后不会消失,不仅可用于代码执行,还可以用于镜像存储,但其只有只读权限
(2)SRAM和DDR中的内容在断电后都会消失,因此只能被用于代码的动态执行,而不能用于镜像存储
(3)ROM和SRAM都是直接连接总线上,系统上电后即可直接执行。而DDR需要通过DDR phy和DDR controller连接到总线上,因此使用之前必须要先对其执行初始化操作
  根据上述各种内存的特点和前面镜像加载启动流程的需求,在内存规划中我们需要考虑以下几个问题:
(1)由于BL1需要固化到ROM中,且是系统最先执行的,因此ROM地址需要被映射到cpu的重启地址处
(2)由于ROM是只读的,BL1镜像除了代码段和只读数据段之外还包含可读写数据段,这部分数据在BL1启动时需要从ROM重定位到SRAM中
(3)由于BL1被固化在ROM中,芯片出产后就不能更改,因此DDR初始化代码不能集成到BL1中。故BL2需要被加载到SRAM中执行,且在BL2中执行DDR初始化流程
(4)BL2之后的其它镜像既可以运行于SRAM中,也可以运行于DDR中
(5)从前面的镜像启动流程可知,若BL2运行于secure EL1下,当其执行完成后,需要通过smc再次陷入BL1去执行BL31流程,因此BL2和BL1的地址不能有重叠
(6)BL31除了执行启动流程外,在系统运行过程中还会以secure monitor的方式驻留,为normal空间的smc异常提供服务历程,以及为normal os和trust os之间提供消息转发、中断路由转发等功能。因此,BL31镜像需要永久驻留内存,在系统启动完成后不能被回收
(7)与BL31类似,BL32在启动后需要驻留内存为系统提供安全相关服务,因此为其所分配的内存也不能被回收(8)除此之外,BL1、BL2和BL33(一般为uboot)的内存在系统启动完成后都可以被释放给操作系统使用。

5.2 qemu virt平台内存规划示例

根据以上内存规划原则,qemu virt machine各启动阶段的内存规划如下:

类型起始地址结束地址长度是否secure内存作用
ROM0x000000000x00020000128kYesBL1(bootrom)
SRAM0x0e04e0000x0e06000072kYesBl1(rw data)
SRAM0x0e0000000x0e0010004kYesShared ram
SRAM0x0e01b0000x0e040000148kYesBL2
SRAM0x0e0400000x0e060000128kYesBL31
SRAM0x0e0010000x0e040000252kYESBL32
DDR0x600000000x1000000002.5GNOBL33

 从上面的BL31和BL32的内存规划,是占用的SRAM空间,不是占用DDR空间,也就是OP-TEE系统(BL32)和sercure monitor (BL31)是占用SRAM内存,不是DDR内存 。

相关文章:

  • 虚拟表格实现全解析
  • 机器学习数学基础:29.t检验
  • 【新人系列】Python 入门(三十一):内存管理
  • Java中JDK、JRE,JVM之间的关系
  • 2025开源数据工程全景图
  • 【Java进阶学习 第一篇】Java中的继承
  • Ubuntu搭建RTSP服务器
  • DeepSeek学术指南:利用DeepSeek撰写学术论文和需要注意的问题
  • Git 中 rebase, squash, amend 的作⽤
  • 服务器配置-从0到分析2:服务器基本设置
  • 第4章 信息系统架构(四)
  • Git企业开发
  • 机器学习笔记——常用损失函数
  • python 神经网络教程,神经网络模型代码python,小白入门基础教程
  • 云端SaaS系统架构设计
  • Web入侵实战分析-常见web攻击类应急处置实验2
  • 【随手笔记】NB和4G信号杂记
  • golang--字符串处理(rune类型)
  • Qt开源项目获取
  • 【GORM学习笔记】GORM介绍以及增删改查相关操作
  • 网站开发技术html/seo提升排名
  • 做贵网站多少钱/友情链接百科
  • 建设网站机构/互联网推广引流公司
  • 钢板防护罩做网站/全网搜索
  • 网站开发怎样验收/站长工具seo综合查询源码
  • 咨询公司排名前十/徐州seo外包