👹
Carlos's Tech Blog
  • 🧔ECUs
    • ZYNQ_Documents
      • [ZYNQ] 构建ZYNQ的BSP工程
      • [ZYNQ] 启动流程
      • [ZYNQ] Secure Boot Flow
      • [ZYNQ] Provisioning Guideline
      • [ZYNQ] Decrypting Partition by the Decrypt Agent Using PUF key
      • [ZYNQ] enabling the cryptsetup on ramdisk
      • [ZYNQ] Encrypt external files based on file system using PUF key
      • [ZYNQ] Loading an Encrypted Linux kernel at U-Boot with a KUP Key
      • [ZYNQ] cross-compile the cryptsetup on Xilinx ZYNQ aarch64 platform
      • [ZYNQ] Linux Linaro系统镜像制作SD卡启动
    • S32G_Documents
      • [S32G] Going through the s32g hard/soft platform
      • [S32G] S32g247's Secure Boot using HSE firmware
        • S32g2 HSE key config
        • How S32g verify secure boot image
        • S32g secure boot signature generation
        • How to download and build S32g Secure boot image
        • [S32G] OTA with Secure Boot
    • RT117x_Documents
      • [RT-117x]IMX RT1170 Provisioning Guideline
      • [RT-117x] Going through the MX-RT1170 hard/soft platform
      • [RT-117x] i.MX-RT1170's Secure Boot
        • [RT-117x]Signing image with the HSM (SignServer)
    • LS104x_Documents
      • [LS104x] bsp project
      • [LS104x] boot flow
      • [LS104x] secure boot
      • [LS104x] Application Note, Using the PKCS#11 in TCU platform
      • [LS104x] 使用ostree更新rootfs
      • [LS104x] ostree的移植
      • [LS104x] Starting with Yocto
      • [LS104x] 使用FIT的kernel格式和initramfs
    • IMX6/8_Documents
      • [IMX6] Defining A U-Boot Command
      • NXP IMX6 嵌入式板子一些笔记
      • NXP-imx6 initialization
    • Vehicle_Apps
      • [SecOC] Tree
        • [SecOC] SecOC Freshness and MAC Truncation
  • 😾TECH
    • Rust Arm OS
      • ARMv7m_Using_The_RUST_Cross_Compiler
    • ARM
      • ARM-v7-M
        • 01_ARMv7-M_处理器架构技术综述
        • 02_ARMv7-M_编程模型与模式
        • 03_ARMv7-M_存储系统结构
        • 04_ARMv7-M_异常处理及中断处理
      • ARM-v8-A
        • 02_ARMv8_基本概念
        • 03_ARMv8_指令集介绍_加载指令集和存储指令集
        • 04_ARMv8_指令集_运算指令集
        • 05_ARMv8_指令集_跳转_比较与返回指令
        • 06_ARMv8_指令集_一些重要的指令
        • 0X_ARMv8_指令集_基于汇编的UART驱动
        • 07_ARMv8_汇编器Using as
        • 08_ARMv8_链接器和链接脚本
        • 09_ARMv8_内嵌汇编(内联汇编)Inline assembly
        • 10_ARMv8_异常处理(一) - 入口与返回、栈选择、异常向量表
        • 11_ARMv8_异常处理(二)- Legacy 中断处理
        • 12_ARMv8_异常处理(三)- GICv1/v2中断处理
        • 13_ARMv8_内存管理(一)-内存管理要素
        • 14_ARMv8_内存管理(二)-ARM的MMU设计
        • 15_ARMv8_内存管理(三)-MMU恒等映射及Linux实现
        • 16_ARMv8_高速缓存(一)cache要素
        • 17_ARMv8_高速缓存(二)ARM cache设计
        • 18_ARMv8_高速缓存(三)多核与一致性要素
        • 19_ARMv8_TLB管理(Translation Lookaside buffer)
        • 20_ARMv8_barrier(一)流水线和一致性模型
        • 21_ARMv8_barrier(二)内存屏障案例
      • ARM Boot Flow
        • 01_Embedded_ARMv7/v8 non-secure Boot Flow
        • 02_Embedded_ARMv8 ATF Secure Boot Flow (BL1/BL2/BL31)
        • 03_Embedded_ARMv8 BL33 Uboot Booting Flow
      • ARM Compiler
        • Compiler optimization and the volatile keyword
      • ARM Development
        • 在MACBOOK上搭建ARMv8架构的ARM开发环境
        • Starting with JLink debugger or QEMU
    • Linux
      • Kernel
        • 0x01_LinuxKernel_内核的启动(一)之启动前准备
        • 0x02_LinuxKernel_内核的启动(二)SMP多核处理器启动过程分析
        • 0x21_LinuxKernel_内核活动(一)之系统调用
        • 0x22_LinuxKernel_内核活动(二)中断体系结构(中断上文)
        • 0x23_LinuxKernel_内核活动(三)中断体系结构(中断下文)
        • 0x24_LinuxKernel_进程(一)进程的管理(生命周期、进程表示)
        • 0x25_LinuxKernel_进程(二)进程的调度器的实现
        • 0x26_LinuxKernel_设备驱动(一)综述与文件系统关联
        • 0x27_LinuxKernel_设备驱动(二)字符设备操作
        • 0x28_LinuxKernel_设备驱动(三)块设备操作
        • 0x29_LinuxKernel_设备驱动(四)资源与总线系统
        • 0x30_LinuxKernel_设备驱动(五)模块
        • 0x31_LinuxKernel_内存管理(一)物理页面、伙伴系统和slab分配器
        • 0x32_LinuxKernel_内存管理(二)虚拟内存管理、缺页与调试工具
        • 0x33_LinuxKernel_同步管理_原子操作_内存屏障_锁机制等
        • 01_LinuxDebug_调试理论和基础综述
      • Userspace
        • Linux-用户空间-多线程与同步
        • Linux进程之间的通信-管道(上)
        • Linux进程之间的通信-管道(下)
        • Linux进程之间的通信-信号量(System V)
        • Linux进程之间的通信-内存共享(System V)
        • Linux进程之间的通信-消息队列(System V)
        • Linux应用调试(一)方法、技巧和工具 - 综述
        • Linux应用调试(二)工具之coredump
        • Linux应用调试(三)工具之Valgrind
        • Linux机制之内存池
        • Linux机制之对象管理和引用计数(kobject/ktype/kset)
        • Linux机制copy_{to, from}_user
        • Linux设备树 - DTS语法、节点、设备树解析等
        • Linux System : Managing Linux Services - inittab & init.d
        • Linux System : Managing Linux Services - initramfs
      • Kernel Examples
        • Linux Driver - GPIO键盘驱动开发记录_OMAPL138
        • 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl
        • 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write
        • 基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ
        • Linux内核调用SPI驱动_实现OLED显示功能
        • Linux内核调用I2C驱动_驱动嵌套驱动方法MPU6050
    • OPTEE
      • 01_OPTEE-OS_基础之(一)功能综述、简要介绍
      • 02_OPTEE-OS_基础之(二)TrustZone和ATF功能综述、简要介绍
      • 03_OPTEE-OS_系统集成之(一)编译、实例、在QEMU上执行
      • 05_OPTEE-OS_系统集成之(三)ATF启动过程
      • 06_OPTEE-OS_系统集成之(四)OPTEE镜像启动过程
      • 07_OPTEE-OS_系统集成之(五)REE侧上层软件
      • 08_OPTEE-OS_系统集成之(六)TEE的驱动
      • 09_OPTEE-OS_内核之(一)ARM核安全态和非安全态的切换
      • 10_OPTEE-OS_内核之(二)对安全监控模式的调用的处理
      • 11_OPTEE-OS_内核之(三)中断与异常的处理
      • 12_OPTEE-OS_内核之(四)对TA请求的处理
      • 13_OPTEE-OS_内核之(五)内存和cache管理
      • 14_OPTEE-OS_内核之(六)线程管理与并发
      • 15_OPTEE-OS_内核之(七)系统调用及IPC机制
      • 16_OPTEE-OS_应用之(一)TA镜像的签名和加载
      • 17_OPTEE-OS_应用之(二)密码学算法和安全存储
      • 18_OPTEE-OS_应用之(三)可信应用的开发
      • 19_OPTEE-OS_应用之(四)安全驱动开发
      • 20_OPTEE-OS_应用之(五)终端密钥在线下发系统
    • Binary
      • 01_ELF文件_目标文件格式
      • 02_ELF文件结构_浅析内部文件结构
      • 03_ELF文件_静态链接
      • 04_ELF文件_加载进程虚拟地址空间
      • 05_ELF文件_动态链接
      • 06_Linux的动态共享库
      • 07_ELF文件_堆和栈调用惯例以ARMv8为例
      • 08_ELF文件_运行库(入口、库、多线程)
      • 09_ELF文件_基于ARMv7的Linux系统调用原理
      • 10_ELF文件_ARM的镜像文件(.bin/.hex/.s19)
    • Build
      • 01_Script_makefile_summary
    • Rust
      • 02_SYS_RUST_文件IO
    • Security
      • Crypto
        • 1.0_Security_计算机安全概述及安全需求
        • 2.0_Security_随机数(伪随机数)
        • 3.0_Security_对称密钥算法加解密
        • 3.1_Security_对称密钥算法之AES
        • 3.2_Security_对称密钥算法之MAC(CMAC/HMAC)
        • 3.3_Security_对称密钥算法之AEAD
        • 8.0_Security_pkcs7(CMS)_embedded
        • 9.0_Security_pkcs11(HSM)_embedded
      • Tools
        • Openssl EVP to implement RSA and SM2 en/dec sign/verify
        • 基于Mac Silicon M1 的OpenSSL 编译
        • How to compile mbedtls library on Linux/Mac/Windows
    • Embedded
      • eMMC启动介质
  • 😃Design
    • Secure Boot
      • JY Secure Boot Desgin
    • FOTA
      • [FOTA] Module of ECUs' FOTA unit design
        • [FOTA] Tech key point: OSTree Deployment
        • [FOTA] Tech key point: repositories role for onboard
        • [FOTA] Tech key point: metadata management
        • [FOTA] Tech key point: ECU verifying and Decrpting
        • [FOTA] Tech key point: time server
      • [FOTA] Local-OTA for Embedded Linux System
    • Provisioning
      • [X-Shield] Module of the Embedded Boards initialization
    • Report
由 GitBook 提供支持
在本页
  • 1. 安全引导原理
  • 1.1 ARMv7安全引导过程
  • 1.1 ARMv8安全引导过程
  • 2. ATF启动过程
  1. TECH
  2. OPTEE

05_OPTEE-OS_系统集成之(三)ATF启动过程

https://github.com/carloscn/blog/issues/95

上一页03_OPTEE-OS_系统集成之(一)编译、实例、在QEMU上执行下一页06_OPTEE-OS_系统集成之(四)OPTEE镜像启动过程

最后更新于1年前

ATF作为最底层固件,OP-TEE OS、 BootLoader、Linux内核的加载都是由ATF来完成的,而且ATF实现了安全引导的功能。bl31运行于EL3,待系统启动完成后,在REE侧或TEE侧触发的安全监控模式调用(smc)都会进入bl31中被处理。OP-TEE启动完成后会返回一个包含用于处理各种类型的安全监控模式调用的函数指针结构体变量,该变量会被添加到bl31的handle中,用于处理REE侧触发的安全监控模式调用。bl2启动时通过触发安全监控模式调用通知bl1将CPU控制权限交给bl31,bl31通过解析特定段中是否存在OP-TEE的入口函数指针来确定是否需要加载OP-TEE。OP-TEE启动后会触发安全监控模式调用重新进入到bl31中继续执行。bl31通过查询链表的方式获取下一个需要被加载REE侧的镜像文件,并设定好REE侧运行时CPU的状态和运行环境,然后退出EL3进入REE侧镜像文件的启动,一般第一个REE侧镜像文件为 BootLoader,BootLoader会加载Linux内核。

1. 安全引导原理

安全引导功能的原理就是采用链式验签的方式启动系统,也就是在系统启动过程中,在加载下一个阶段的镜像之前都会对需要被加载的镜像文件进行电子验签,只有验签操作通过后,该镜像才能被加载到内存中,然后系统才会跳转到下一个阶段继续执行,整个验签链中的任何一环验签失败都会导致系统挂死,系统启动过程中的第一级验签操作是由ChipRom(BootROM)来完成的。只要芯片一出厂,用户就无法修改固化在芯片中的这部分代码,因此无法通过修改第一级验签结果来关闭安全引导功能。而且验签操作使用的RSA公钥或者哈希值将会被保存在OTP/efuse中,该区域中的数据一般只有ChipRom(BootROM)和TEE能够读取且无法被修改。RSA公钥或者哈希值将会在产品出厂之前被写入到OTP/efuse中,而且不同厂商使用的密钥会不一样。

在谷歌的安全引导功能白皮书中提出了安全引导功能实现方案的设计建议。谷歌建议将镜像文件 的电子签名信息和验签使用的RSA公钥保存在电子证书中,系统在启动的过程中首先会验证电子证书的合法性,如果验证通过则需从电子证书中获取签名信息和RSA公钥,然后再利用它们对镜像文件进行验证。整个验证过程就是先验证证书,验证证书通过后再去验证镜像文件的合法性。但是在实际实现过程中,大多数芯片厂商是将签名信息与需要被验签的镜像文件打包在一起,而RSA公钥则会被打包到执行验证操作的镜像文件中。

不同厂商可能会对镜像文件进行加密操作,使保存在设备中的镜像文件都是以密文的形式存在。 在启动过程中,首先会验证密文镜像文件的合法性然后再进行解密镜像文件的操作,这些都完成后才会将明文的镜像文件加载到内存中然后再执行跳转操作。

1.1 ARMv7安全引导过程

对于安全引导功能的实现和验证过程各家芯片公司的方案都不一样,这是由该芯片的启动流程以及启动所需镜像文件来决定的,但都会遵循链式验签启动的原则。ARMv7架构并没有使用ATF,系统的启动流程与以前一样使用BootLoader来引导Linux内核和TEE OS。

1.1 ARMv8安全引导过程

ARMv8架构之后ARM提供了ATF, BootLoader、TEE镜像文件、Linux内核镜像文件、 recovery镜像文件都是由ATF来进行引导和加载而不是由ChipRom(BootROM)成的。ChipRom(BootROM)只会去验证ATF中bl1的合法性,后续引导过程同样也是按照链式验签的方式进行,符合TBBR规范。在 ARMv8架构中整个安全引导的流程如图所示。

ARMv8架构中引入了ATF,同时在ATF中提供了安全引导的功能,BootLoader镜像、Linux内核、 recovery镜像和TEE OS镜像文件的签名方式都由ATF决定。当然开发者也可以对ATF进行定制化,修改ATF中的验签过程,但是修改后的验签方案需要符合TBBR规范。

2. ATF启动过程

ATF的启动过程根据ARMv8的运行模式(AArch32/AArch64)会有所不同,但基本一致。在AArch32中是不会去加载bl31而是将EL3或者 Monitor模式的运行代码保存在bl32中执行。在AArch64中,ATF的完整启动流程如图所示。

在上述启动过程中,从一个镜像跳转到另外一个镜像文件执行的方式各不相同,以下为镜像跳转的过程和方式说明。

1.bl1跳转到bl2执行

在bl1完成了将bl2镜像文件加载到RAM中的操作、中断向量表的设定以及其他CPU相关设定后, bl1_main函数会解析出bl2镜像文件的描述信息,获取入口地址,并设定下一个阶段的cpu上下文。这些操作完成之后,调用el3_exit函数来实现bl1到bl2的跳转,进入bl2中开始执行。

2.bl2跳转到bl31执行

在bl2中将会加载bl31、bl32、bl33的镜像文件到对应权限的内存中,并将该三个镜像文件的描述 信息组成一个链表保存起来,以备bl31启动bl32和bl33使用。在AArch64中,bl31为EL3的执行软件, 其运行时的主要功能是对安全监控模式调用(smc)指令和中断处理,运行在ARM的Monitor模式中。

bl32一般为TEE OS镜像文件。 bl33为正常世界状态的镜像文件,例如uboot、EKD2等。当前该部分为BootLoader部分的镜像文件,再由BootLoader来启动Linux内核镜像。

从bl2跳转到bl31是通过带入bl31的入口点信息作为参数,然后调用安全监控模式调用指令,触发 在bl1中设定的安全监控模式调用请求,该请求处理完成后会将中央处理器的执行权限交给bl31,并跳转到bl31中去执行。

3.bl31跳转到bl32执行

在bl31中会执行runtime_service_inti函数,该函 数会调用注册到EL3中所有服务的初始化函数,其中有一个服务项就是TEE服务,该服务项的初始化函数会将TEE OS的初始化函数赋值给bl32_init变量,当所有服务项执行完初始化后,在bl31中会调 用bl32_init执行的函数来跳转到TEE OS中并开始执 行TEE OS的启动。

4.bl31跳转到bl33执行

当TEE-OS镜像启动完成后会触发一个ID为 TEESMC_OPTEED_RETURN_ENTRY_DONE的安全监控模式调用,该调用是用来告知EL3 TEE OS镜像已经完成了初始化,然后将CPU的状态恢复到 bl31_init的位置继续执行。

bl31通过遍历在bl2中记录的所有镜像信息的链表来找到需要执行的bl33的镜像。然后通过获取到bl33镜像的信息,设定下一个阶段的CPU上下文,退出el3后进入到bl33镜像中开始执行。

ATF具体过程参考:02_Embedded_ARMv8 ATF Secure Boot Flow (BL1/BL2/BL31)

😾