本文想讨论的是智驾域中的安全启动。

架构

对于域控架构的新能源汽车而言,整车可分为座舱域、动力域、车身域以及智驾域。所谓域控指的是硬件+软件的组成,以智驾域(ADAS)为例,通常具备一个SOC、MCU,软件部分包括底层操作系统、中间层软件、上层应用软件等。

启动过程

从SOC角度探讨典型嵌入式系统的开机启动过程,

  1. BootRom
    芯片上电后ARMcore首先处于复位状态,芯片内部的BootROM中的代码执行,建立最小系统环境,具体为首先芯片上电(POR),时钟初始化,片内SRAM初始化。接下来BootRAM读取GPIO的pin决定从何种介质启动BootLoader,将bootloader的一部分或者全部搬运到片内SRAM中启动

  2. BootLoader
    在启动下一级bootloader前,bootrom还会读取镜像头的签名信息,比较区域存储签名的hash值验证其合法性。接下来bootloader会完成多项工作。
    由于BootROM位于片内,存储有限,整个bootloader被划分为两个阶段,SPL (Secondary Program Loader) 和 U-Boot Proper。spl阶段主要是初始化DDR存储并将完整U-Boot镜像加载到其中开始进行bootloader。U-boot则开始正式初始化多种外设以及内核。在启动外设和内核时,bootloader通过寄存器将启动参数传递,一个典型的存储布局为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+------------------+ 0x00000000
| BootROM (Internal)|
+------------------+
| ... |
+------------------+
| Partition Table | (MBR/GPT)
+------------------+
| SPL / Miniboot | Sector 2048
+------------------+
| U-Boot |
+------------------+
| U-Boot Env |
+------------------+
| Kernel (uImage) |
+------------------+
| Device Tree (dtb)|
+------------------+
| RootFS |
+------------------+

  1. DTS挂载
    开发者编写 .dts (Device Tree Source) 文件,通过 dtc (Device Tree Compiler) 编译成 .dtb (Device Tree Blob)。一个CPU时钟的dts配置为
1
2
3
4
5
6
7
8
9
cpus {
cpu@0 {
compatible = "arm,cortex-a53";
device_type = "cpu";
reg = <0x0 0x0>;
clocks = <&scu_clk>;
clock-latency = <100000>;
};
};
  1. 内核启动
    内核入口通常位于 arch/arm64/kernel/head.S(汇编)。首先进行初始化,通过head.s校验处理器ID、关闭终端,初始化MMU。接下来加载init/main.c :
1
2
3
4
5
setup_arch(): 解析设备树,建立内存管理。
trap_init(): 初始化异常向量表。
sched_init(): 初始化调度器。
time_init(): 初始化系统定时器。
rest_init(): 创建 init 进程(PID 1

最后加载soc专用驱动,如bpu等。
5. 文件系统挂载
内核中存在initramfs和Rootfs,initramfs是小型的基于内存的文件系统,包含必要驱动,Roofs是操作系统文件系统,内核线程执行 kernel_init,尝试挂载根文件系统。一个典型的文件系统是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/
├── bin/ # 基本命令 (busybox, ls, cp)
├── dev/ # 设备节点 (mmcblk0, ttyS0, video0)
├── etc/ # 配置文件 (init.d/, fstab, profile)
├── lib/ # 动态库 (ld-linux.so, libc.so)
├── mnt/ # 临时挂载点
├── proc/ # 进程信息虚拟文件系统
├── root/ # Root用户家目录
├── sbin/ # 系统管理命令 (init, insmod)
├── sys/ # 系统硬件信息虚拟文件系统
├── tmp/ # 临时文件
├── usr/ # 用户应用程序
│ ├── bin/
│ └── lib/ # X3M专属库 (libbpu.so, libdnn.so)
└── var/ # 可变数据 (log, run)

FuSa (function safe)

即功能安全,不存在由电子电气系统的故障行为导致的危险所造成的不合理的风险。风险等级又一共有5个,分别是QM、ASIL A、ASIL B、ASIL C、ASIL D。ASIL(automotive safty integration level) X,需要增加降低风险的措施、QM则只需要尊选标准的质量管理流程即可。
需要从两个方面来评估风险级别:security,即风险对人的严重程度;Probility,即风险发生的可能性,而可能性又可以分为Exposure:暴露概率和Controllability:风险发生的可控制性。
另外一个ASIL系统还可以被拆分成不同等级系统并分别进行安全设计。

efuse(electronic fuse)

定义

即电子熔断器,是一种可编程电子保险丝,是一种用于存储信息和保护芯片的非易失性存储器件。它的原理是基于电子注入和热效应。在eFuse中,短电流脉冲被应用于热致电子发射,这会使电流通过一个非常小的导线。该电流会引起电线中的材料熔断,形成一个永久性的开路。这个过程是不可逆的,一旦eFuse被熔断,就不能再次编程。

作用

可以用于多个安全领域或者实时性要求高的一次性领域,例如芯片保护、电源管理、电路校准等。在芯片保护方面,eFuse可以用于防止电路被过电压或过电流损坏,也可用于防篡改、防破解等。在电源管理方面,eFuse可以用于控制电流和电压,确保电路正常工作。在电路校准方面,eFuse可以用于校准电路参数,例如时钟频率和电流偏置等。

使用

以启动过程中验签pubkey hash为例

efuse烧录

在初始状态中efuse所有比特位为逻辑0或者高阻态,在烧录过程中硬件控制器向特定的bit cell施加一个时间短但电压高的脉冲,导致连接处的硅化物熔断造成物理开路。
在烧录过程中时序控制非常关键时间太短导致熔断不彻底,太长可能损坏周围电路。
烧录过程首先将pubkey转换成hash,然后使设备进入fastboot或者uboot模式利用soc提供的驱动将hash值写入寄存器,同时通过轮询验证结果

验签

在spl启动时都会通过向efuse通电得到一个hash值,然后通过计算来验证key,保证启动的bootloader是安全的。

通过RSA key更换U-boot Pubkey

在烧录后spl已经被efuse中的hash验证通过,spl中包含一个u-boot-spl.dtb设备树,在/signaturre中包含验证下一家u-boot userapp的RSA publkey。重新编译spl,将新的RSA Pubkey打包进入spl的dtb并使用旧私钥重新签名。

安全启动(dm-verify)

因此就可以得到一个安全启动的方案,这依赖于efuse仅能被写入一次数据的特性,来保障安全性。
首先将公钥烧录到efuse,编译生成镜像通过私钥对镜像进行签名,同时将公钥打包进入镜像,系统启动时解析镜像公钥并与efuse比较,公钥正确再对其进行验签。接下来验证系统镜像内容,对系统镜像每4k计算一个hash形成layer0,然后对layer0每4k计算一个hash形成layer1,以此类推形成roothash,并依据此对文件系统校验。


本站由 Edison.Chen 创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。