1、什么是BootRom
启动ROM是一种用于启动计算机系统的只读存储器(ROM)。它有两种类型:一种是掩模启动ROM,一旦写入后无法更改;另一种是启动EEPROM。开机时,硬件通常未初始化。为了继续启动,系统可能需要从某个外围设备读取引导程序。通常,在软件中实现从外部存储设备读取的例程比在硬件中实现更容易。启动ROM提供了一个存储初始加载代码的地方,在处理器开始执行时,这个位置是立即可用的。
关注MROM(Mask ROM)和EEPROM之间的区别。
掩膜ROM(MROM) | 电可擦除可编程ROM(EEPROM) | |
---|---|---|
基本定义 | 在芯片制造过程中,通过掩膜工艺将数据直接写入芯片,之后无法更改的只读存储器。 | 允许通过电信号进行多次擦除和重新编程的可编程只读存储器。 |
数据修改能力 | 不可修改,数据一旦写入便永久保存。 | 可通过电信号进行多次擦除和重新编程。 |
编程方式 | 厂家在制造过程中通过掩膜工艺写入数据,用户无法更改。 | 用户可以通过电子操作进行编程,无需外部设备(如紫外线灯)。 |
擦除方式 | 无法擦除,数据一旦写入便永久存在。 | 通过电信号进行擦除,无需紫外线照射。 |
特点 | 成本低(大批量生产时),稳定性高,数据不会丢失,但灵活性差,适合固定数据应用。 | 灵活性高,可多次编程和擦除,但成本相对较高(尤其是小批量时)。 |
应用场景 | 1. 固件存储,如电视、音响等消费类电子产品的启动代码。 | 1. 计算机主板上的BIOS芯片,用于存储硬件配置数据。 |
2. 不需要数据更新的嵌入式系统。 | 2. 需要频繁更新数据的嵌入式系统,如工业控制设备。 | |
3. 早期计算机系统中的固件和操作系统存储。 | 3. 智能卡,如电话卡、身份证、信用卡的数据存储(尽管现代智能卡可能使用更先进的存储技术)。 | |
4. 调试和开发过程中的临时数据存储。 |
差异总结
- 数据修改性:MROM一旦数据写入便不可更改,而EEPROM支持多次擦除和重写。
- 编程与擦除方式:MROM通过厂家在制造过程中写入数据,EEPROM则通过电子操作进行编程和擦除。
- 成本:MROM在大批量生产时成本较低,而EEPROM的成本相对较高,尤其是小批量时。
- 应用场景:MROM适用于固定数据且不需要更改的场合,如消费类电子产品的固件;而EEPROM适用于需要频繁更新数据的场景,如计算机主板BIOS、工业控制设备和调试开发过程中的数据存储。
- 启动ROM被映射到内存的一个固定位置,处理器被设计为在重置后从这个位置开始执行。通常,它与CPU位于同一个芯片上,但也可以是一个外部ROM芯片,这在旧系统中很常见。在现代系统中,无论是集成到CPU中还是外部ROM芯片,启动ROM通常使用NOR闪存,这种闪存支持原地执行。
- 然后,启动ROM将初始化启动所需的硬件总线和外围设备。在某些情况下,启动ROM能够初始化RAM,而在其他情况下,这取决于引导程序来完成。
- 在硬件初始化结束时,启动ROM会尝试从外部外围设备(如eMMC、microSD卡、外部EEPROM等)或通过总线上的特定协议(如USB、UART等)加载引导程序。
- 在许多片上系统中,启动ROM尝试加载引导程序的外围设备或总线(例如嵌入式引导程序的eMMC,或用于UEFI实现的外部EEPROM),以及它们的加载顺序,都是可以配置的。这种配置可以通过在片上系统内部烧录一些电子保险丝来编码这些信息,或者通过设置片上系统的特定引脚或跳线为高或低。
- 一些启动ROM能够检查引导程序的数字签名,如果签名无效或未用授权密钥签名,它们将拒绝运行引导程序并停止启动。在某些启动ROM中,用于验证签名的公钥的哈希值被编码在片上系统的电子保险丝中。一些片上系统启动ROM还支持公钥基础设施,证书颁发机构(CA)的公钥哈希值被编码在电子保险丝中,然后启动ROM能够通过使用CA公钥(其哈希值编码在电子保险丝中)来验证引导程序是否由授权密钥签名。
这里就是和OTP进行配合使用。
这个特性可以用来实现安全特性,或者作为信任链中的硬件信任根,但一旦配置后,用户就被剥夺了用他们想要的引导程序替换的自由。正因为如此,这个特性引起了自由软件社区的强烈担忧。
就在跳转到引导程序之前,一些片上系统还会从内存映射中移除启动ROM,而其他系统则不会,这使得可以从后续分析中转储启动ROM。如果启动ROM仍然可见,引导程序也可以调用启动ROM的代码(有时这些代码是有文档记录的)。
本质是就是为了安全考虑。一旦BootROM完成了它的任务,例如初始化硬件和加载引导程序,它可能会被设计为从内存映射中移除,以防止未授权的访问或篡改。这样可以确保系统的安全性,因为BootROM中可能包含关键的启动代码和安全相关的程序。这里的移除就是让你不能访问,并不是物理意义上的移除。
当片上系统进入挂起到RAM模式时,在许多情况下,处理器完全关闭,而RAM被置于自刷新模式。在恢复时,启动ROM再次执行,许多启动ROM能够检测到片上系统是否处于挂起到RAM状态,并且可以通过直接跳转到内核来恢复,然后由内核负责再次打开之前关闭的外围设备,并恢复计算机之前的状态。
所以站在系统的角度,待机唤醒和启动的流程某种程度是很相似的。
2.BootRom为什么要固化在芯片内部
BootROM(启动只读存储器)被嵌入到芯片内部的原因主要包括以下几点:
-
快速启动:BootROM位于处理器芯片内部,因此它能够被快速访问,这有助于系统在上电后迅速开始执行启动代码。
-
安全性:由于BootROM是只读的,这使得存储在其中的关键启动代码不易被篡改或删除,为系统提供了一个安全的启动基础。
-
可靠性:嵌入在芯片内部的BootROM不易受到物理损坏,这有助于保证系统在各种环境下都能可靠地启动。
-
成本效益:将BootROM集成到芯片中可以减少外部组件的需求,从而降低系统的整体成本。
-
一致性和简化设计:所有使用相同处理器的系统都会有相同的BootROM,这有助于确保启动过程的一致性,并简化了系统设计。
-
保护知识产权:BootROM中的代码通常属于芯片制造商的知识产权,将其嵌入芯片可以更好地保护这些代码不被非法复制或逆向工程。
-
减少外部接口需求:由于BootROM是内部的,它减少了对外部存储器接口的需求,从而简化了电路设计。
-
支持安全启动过程:许多现代处理器的BootROM包含安全启动功能,可以验证即将执行的代码的完整性和来源,这是保护系统免受恶意软件攻击的重要安全特性。
总的来说,将BootROM集成到芯片内部是为了提供快速、安全、可靠的启动过程,同时也有助于保护制造商的知识产权和简化系统设计。
3、BootRom的必要性
BootROM(启动只读存储器)在许多计算机和嵌入式系统中是必不可少的组件,原因包括:
-
初始硬件初始化:当计算机通电时,它需要初始化硬件组件。BootROM包含执行此初始设置的代码,包括配置内存、设置I/O端口和初始化外围设备。
-
提供启动代码:BootROM提供处理器执行的第一阶段启动代码。这段代码对于启动系统和加载启动过程的下一阶段至关重要。
-
安全性:BootROM可以包含安全启动等安全功能,确保系统在启动时只运行授权的代码。这有助于防止恶意软件在启动时破坏系统。
-
可靠性:由于BootROM是硬件的一部分并且是不可挥发的,即使系统断电,它也保留启动代码。这确保了只要BootROM未损坏,系统总是可以启动。
-
速度:将启动代码放在处理器可以快速访问的ROM中,与从外部源获取代码相比,这加快了启动过程。
-
简单性:BootROM简化了系统设计,因为它将初始启动逻辑集中在一个地方。这使得管理和更新启动过程变得更加容易。
-
恢复模式:如果主系统软件损坏,BootROM可以提供恢复模式,允许用户将系统恢复到工作状态。
-
可升级性:虽然BootROM本身通常是只读的,但许多系统允许通过外部存储或网络连接在初始BootROM阶段之后更新启动过程或添加新功能。
-
一致性:BootROM确保每次启动都遵循相同的初始过程,这对于保持一致的系统行为很重要。
-
支持旧系统:在某些情况下,BootROM提供对旧系统的支持或与软件的以前版本向后兼容。
-
嵌入式系统:在嵌入式系统中,BootROM通常用于初始化设备并加载定制的操作系统或固件,以满足设备特定需求。
-
减少外部依赖:通过在芯片上拥有启动代码,没有依赖于可能失败或被移除的外部存储介质。
BootROM是系统启动过程的基本部分,为系统开始操作提供了可靠和安全的起点。没有BootROM,系统将没有一致和可靠的方法来初始化硬件和启动操作系统。
4、BootRom的工作内容
BootROM(Boot Read-Only Memory)是嵌入式系统中的一个关键组件,它负责在系统启动时执行初始的硬件初始化和加载引导程序。以下是BootROM的主要工作内容和特点:
1. 系统启动初始化:
- 系统启动初始化:BootROM在系统上电或复位时被执行,负责进行基本的硬件初始化,如设置时钟、复位外设、配置I/O引脚等 。
BootROM代码通常是用汇编语言写的,因为它需要直接与硬件打交道。下面是一个汇编语言示例,展示了在ARM架构上进行系统初始化的过程:
.section .text .global _start _start: /* 设置系统时钟 */ ldr r0, =0x12340000 /* 时钟控制器的基地址 */ ldr r1, =0x0001C000 /* 时钟设置值 */ str r1, [r0, #0x4] /* 设置系统时钟频率 */ /* 初始化内存控制器 */ ldr r0, =0x12345000 /* 内存控制器的基地址 */ ldr r1, =0x00000001 /* 内存控制器初始化值 */ str r1, [r0, #0x0] /* 初始化内存控制器 */ /* 初始化中断控制器 */ ldr r0, =0x12350000 /* 中断控制器的基地址 */ ldr r1, =0x00000002 /* 中断控制器初始化值 */ str r1, [r0, #0x4] /* 初始化中断控制器 */ /* 配置I/O引脚 */ ldr r0, =0x12360001 /* GPIO控制器的基地址 */ mov r1, #1 /* 设置引脚为输出模式 */ str r1, [r0] /* 配置引脚 */ /* 检测启动设备并加载引导加载程序 */ ldr r0, =0x12370000 /* 启动设备接口的基地址 */ ldr r1, =0x00000003 /* 启动设备检测命令 */ str r1, [r0] /* 发送检测命令 */ ldr r1, [r0] /* 读取检测结果 */ cmp r1, #0 beq fail /* 如果没有检测到启动设备,跳转到失败处理 */ /* 加载引导加载程序到RAM */ ldr r0, =0x20000000 /* 引导加载程序的加载地址 */ ldr r1, =0x12370004 /* 启动设备的数据端口 */ load_bootloader: ldr r2, [r1] /* 从启动设备读取一个字 */ str r2, [r0] /* 将读取的数据写入RAM */ add r0, r0, #4 /* 更新加载地址 */ cmp r0, #0x20000100 /* 检查是否加载完成 */ ble load_bootloader /* 跳转到引导加载程序执行 */ b _start_bootloader fail: /* 失败处理 */ b fail /* 进入死循环 */ _start_bootloader: ldr r0, =0x20000000 /* 加载地址 */ bx r0 /* 跳转到引导加载程序 */ .pool |
代码解释
-
设置系统时钟:
ldr r0, =0x12340000 /* 时钟控制器的基地址 */ ldr r1, =0x0001C000 /* 时钟设置值 */ str r1, [r0, #0x4] /* 设置系统时钟频率 */
这里假设时钟控制器的基地址是
0x12340000
,通过设置特定的寄存器值来配置系统时钟频率。 -
初始化内存控制器:
ldr r0, =0x12345000 /* 内存控制器的基地址 */ ldr r1, =0x00000001 /* 内存控制器初始化值 */ str r1, [r0, #0x0] /* 初始化内存控制器 */
这里假设内存控制器的基地址是
0x12345000
,通过写入特定的初始化值来初始化内存控制器。 -
初始化中断控制器:
ldr r0, =0x12350000 /* 中断控制器的基地址 */ ldr r1, =0x00000002 /* 中断控制器初始化值 */ str r1, [r0, #0x4] /* 初始化中断控制器 */
这里假设中断控制器的基地址是
0x12350000
,通过写入特定的初始化值来初始化中断控制器。 -
配置I/O引脚:
ldr r0, =0x12360001 /* GPIO控制器的基地址 */ mov r1, #1 /* 设置引脚为输出模式 */ str r1, [r0] /* 配置引脚 */
这里假设GPIO控制器的基地址是
0x12360001
,通过写入特定的值来配置I/O引脚为输出模式。 -
检测启动设备并加载引导加载程序:
ldr r0, =0x12370000 /* 启动设备接口的基地址 */ ldr r1, =0x00000003 /* 启动设备检测命令 */ str r1, [r0] /* 发送检测命令 */ ldr r1, [r0] /* 读取检测结果 */ cmp r1, #0 beq fail /* 如果没有检测到启动设备,跳转到失败处理 */ ldr r0, =0x20000000 /* 引导加载程序的加载地址 */ ldr r1, =0x12370004 /* 启动设备的数据端口 */ load_bootloader: ldr r2, [r1] /* 从启动设备读取一个字 */ str r2, [r0] /* 将读取的数据写入RAM */ add r0, r0, #4 /* 更新加载地址 */ cmp r0, #0x20000100 /* 检查是否加载完成 */ ble load_bootloader |
这里假设启动设备接口的基地址是 0x12370000
,通过发送检测命令并读取结果来判断是否有启动设备。如果有启动设备,从启动设备读取数据并加载到RAM中。
- 跳转到引导加载程序执行:
b _start_bootloader 失败处理: fail: b fail /* 进入死循环 */ 引导加载程序的入口点: _start_bootloader: ldr r0, =0x20000000 /* 加载地址 */ bx r0 /* 跳转到引导加载程序 */ |
这个示例展示了BootROM在系统启动初始化阶段可能执行的一些操作,包括设置时钟、初始化内存控制器、配置I/O引脚、检测启动设备并加载引导加载程序等。实际的BootROM代码会更加复杂,并且需要根据具体的硬件平台和需求进行调整。
2. 引导加载程序:
- 引导加载程序:BootROM的主要任务是找到并加载引导加载程序(Bootloader)。它通常从固定位置读取引导加载程序,如内置存储(如eMMC、NAND、NOR闪存)或外部存储(如SD卡、USB设备) 。
BootROM(Boot Read-Only Memory)是嵌入式系统中负责启动过程的一段固件,它在系统上电或复位时执行。BootROM的主要任务是找到并加载引导加载程序(Bootloader),这通常涉及以下步骤:
-
系统上电或复位:当电源接通或复位按钮被按下,处理器开始从BootROM存储的地址执行代码。
-
执行BootROM中的初始化代码:BootROM包含的代码会进行基本的硬件设置,包括配置时钟、初始化内存控制器、设置I/O引脚等。
-
检测启动设备:BootROM会检查连接的启动设备,如eMMC、NAND、NOR闪存或外部存储器(如SD卡、USB设备)。
检测启动设备是BootROM加载Bootloader过程中的一个关键步骤。这个过程涉及到检查系统中可用的启动媒体,如内置存储(eMMC、NAND、NOR闪存)或外部存储(SD卡、USB设备),并确保系统能够从这些设备之一启动。
检测启动设备的实现:
1. **初始化启动设备接口**:BootROM首先初始化与启动设备通信所需的接口。这可能包括设置正确的时钟频率、配置I/O引脚和启用相应的控制器(如SD/MMC控制器、USB主机控制器等)。 2. **检测设备存在**:通过读取设备的ID寄存器或发送检测命令来验证设备的物理存在。例如,对于NAND闪存,可能需要发送一个读取ID命令;对于SD卡,可能需要检查卡检测引脚的状态。 3. **读取启动设备信息**:一旦设备被检测到,BootROM会读取存储在设备上的启动信息。这可能包括启动扇区的内容、文件系统上的特定文件或启动参数。 4. **加载Bootloader**:BootROM根据读取的信息加载Bootloader。这通常涉及到将Bootloader的二进制数据从启动设备传输到RAM或其他内存区域。 5. **验证Bootloader**:在某些系统中,BootROM可能会对加载的Bootloader进行校验,以确保其完整性和安全性。这可以通过比较Bootloader的哈希值或检查数字签名来完成。 6. **跳转到Bootloader**:一旦Bootloader被加载和验证,BootROM会跳转到Bootloader的入口点,将控制权交给Bootloader。
示例代码:
以下是一个简化的伪代码示例,展示了BootROM如何检测启动设备并加载Bootloader:
.section .text .global _start _start: /* 初始化启动设备接口 */ INIT_BOOT_DEVICE_INTERFACE /* 检测设备存在 */ CALL CHECK_DEVICE_PRESENT CMP R0, #0 BEQ FAIL /* 读取启动设备信息 */ CALL READ_BOOT_DEVICE_INFO /* 加载Bootloader */ CALL LOAD_BOOTLOADER /* 验证Bootloader (可选) */ CALL VERIFY_BOOTLOADER /* 跳转到Bootloader */ BX BOOTLOADER_ENTRYPOINT FAIL: /* 处理失败情况 */ HALT INIT_BOOT_DEVICE_INTERFACE: /* 初始化代码 */ RET CHECK_DEVICE_PRESENT: /* 设备检测代码 */ RET READ_BOOT_DEVICE_INFO: /* 读取信息代码 */ RET LOAD_BOOTLOADER: /* 加载代码 */ RET VERIFY_BOOTLOADER: /* 验证代码 */ RET |
在这个例子中,INIT_BOOT_DEVICE_INTERFACE
、CHECK_DEVICE_PRESENT
、READ_BOOT_DEVICE_INFO
、LOAD_BOOTLOADER
和VERIFY_BOOTLOADER
是代表不同步骤的函数。实际的实现会依赖于具体的硬件和启动设备。
请注意,这个过程可能会因不同的硬件平台和BootROM的实现而有所不同。例如,某些系统可能支持从多个启动设备启动,并允许用户通过设置跳线或配置文件来选择首选的启动设备。此外,一些系统可能还包括更复杂的错误处理和恢复机制。
-
加载Bootloader:一旦检测到启动设备,BootROM会从预设的位置读取Bootloader的代码。这个过程可能涉及到读取存储设备的驱动代码。
-
跳转到Bootloader:BootROM将Bootloader加载到RAM中,并跳转到Bootloader的入口点,将控制权交给Bootloader。
以下是一个实际的例子,展示了在基于ARM的嵌入式系统中,BootROM如何加载Bootloader:
.section .text .global _start _start: /* 初始化CPU和基本硬件设置 */ ldr r0, =0x12340000 /* 时钟控制器的基地址 */ ldr r1, =0x0001C000 /* 时钟设置值 */ str r1, [r0, #0x4] /* 设置系统时钟频率 */ /* 初始化内存控制器 */ ldr r0, =0x12345000 /* 内存控制器的基地址 */ ldr r1, =0x00000001 /* 内存控制器初始化值 */ str r1, [r0, #0x0] /* 初始化内存控制器 */ /* 检测启动设备 */ ldr r0, =0x12370000 /* 启动设备接口的基地址 */ ldr r1, =0x00000003 /* 启动设备检测命令 */ str r1, [r0] /* 发送检测命令 */ ldr r1, [r0] /* 读取检测结果 */ cmp r1, #0 beq fail /* 如果没有检测到启动设备,跳转到失败处理 */ /* 加载Bootloader到RAM */ ldr r0, =0x20000000 /* 引导加载程序的加载地址 */ ldr r1, =0x12370004 /* 启动设备的数据端口 */ load_bootloader: ldr r2, [r1] /* 从启动设备读取一个字 */ str r2, [r0] /* 将读取的数据写入RAM */ add r0, r0, #4 /* 更新加载地址 */ cmp r0, #0x20000100 /* 检查是否加载完成 */ ble load_bootloader /* 跳转到Bootloader */ b _start_bootloader fail: /* 失败处理 */ b fail /* 进入死循环 */ _start_bootloader: ldr r0, =0x20000000 /* 加载地址 */ bx r0 /* 跳转到引导加载程序 */ |
在这个例子中,_start
是BootROM的入口点,它会自动被执行。ldr
和str
指令用于加载和存储操作,cmp
和beq
指令用于条件判断和跳转。load_bootloader
标签下的代码负责从启动设备加载Bootloader到RAM中。最后,_start_bootloader
标签下的代码负责跳转到Bootloader的入口点。
请注意,这个例子是高度简化的,实际的BootROM代码会更加复杂,并且需要根据具体的硬件平台和需求进行调整。实际的BootROM代码通常会用汇编语言编写,并且包含更多的错误处理和设备支持代码。
-
安全启动:许多现代系统的BootROM包含安全机制,验证引导加载程序的完整性和真实性,以防止运行未经授权的软件。这些机制可能包括签名验证、加密等 。
-
故障恢复:如果引导加载程序损坏或缺失,BootROM可以进入恢复模式,允许用户通过特定接口(如串口、USB)更新或恢复系统 。
-
工作流程:典型的BootROM工作流程包括上电/复位、硬件初始化、启动设备检测、引导加载程序加载,如果加载失败则进入恢复模式 。
-
特点:
- 只读存储器:BootROM存储在ROM中,通常不可更改,确保引导代码在系统启动时始终可用 。
- 小型化:BootROM代码通常非常小,只有几个KB到几十KB,以确保快速启动和最小的存储占用 。
- 安全性:BootROM常包含安全特性,确保只有经过认证的引导加载程序和操作系统能够启动,从而保护系统免受恶意软件攻击 。
-
实际应用示例:在智能手机中,BootROM负责初始化处理器和基本外设,并加载安卓引导加载程序。在物联网设备中,BootROM负责初始化设备并加载实时操作系统(RTOS)或嵌入式Linux。在某些计算机系统中,BootROM用于加载BIOS或UEFI固件,进一步初始化硬件并加载操作系统 。
BootROM是嵌入式系统启动过程中的一个关键组件,它通常存储在不可更改的ROM中,以确保系统启动的可靠性和安全性。理解BootROM的工作原理对开发和调试嵌入式系统至关重要。
5、如何确定启动方式
BootROM确定引导模式或方法通常涉及以下几个方面:
-
启动模式引脚(Boot Mode Pins):许多系统设计中会使用启动模式引脚(如BOOT_MODE)来选择启动源。这些引脚的电平状态(高或低)在系统上电复位(POR)期间被采样一次,并存储在特定的寄存器中,如slcr.BOOT_MODE寄存器 。
-
内部保险丝或寄存器设置:某些系统中,BootROM可能会检查内部保险丝或特定寄存器的设置来确定是否需要执行安全启动或其他特殊启动模式。
-
存储设备的状态:BootROM可能会检查连接的存储设备状态,例如,检查SD卡是否已插入,或者检查NAND、NOR闪存是否准备就绪。
-
预设的启动顺序:如果没有特定的启动设备被选中,BootROM可能会按照预设的启动顺序尝试从不同的设备加载引导程序。
-
特殊命令或配置文件:在某些系统中,BootROM可能会查找存储在特定位置的特殊命令或配置文件,以确定引导模式。
-
硬件故障状态:如果系统由于硬件故障而未能从常规启动设备加载,BootROM可能会选择从备用设备或恢复模式启动。
例子:
以下是一个简化的伪代码示例,展示了BootROM如何确定引导模式并加载Bootloader:
.section .text .global _start _start: /* 检查启动模式引脚状态 */ ldr r0, =BOOT_MODE_PINS_ADDRESS ldr r1, [r0] cmp r1, #0 beq use_nor_flash /* 检查是否选择安全启动 */ ldr r2, =SECURE_BOOT_REGISTER ldr r3, [r2] cmp r3, #SECURE_BOOT_MAGIC beq secure_boot /* 默认引导模式 */ b default_boot use_nor_flash: /* 从NOR闪存加载Bootloader */ /* ... */ b jump_to_bootloader secure_boot: /* 执行安全启动流程 */ /* ... */ b jump_to_bootloader default_boot: /* 执行默认引导流程 */ /* ... */ jump_to_bootloader: /* 跳转到Bootloader */ /* ... */ bx BOOTLOADER_ENTRYPOINT BOOT_MODE_PINS_ADDRESS: .word 0x12340000 SECURE_BOOT_REGISTER: .word 0x12345000 SECURE_BOOT_MAGIC: .word 0xA5A5A5A5 BOOTLOADER_ENTRYPOINT: .word 0x20000000 |
在这个例子中,_start
是BootROM的入口点。代码首先检查启动模式引脚的状态,然后检查是否选择了安全启动。如果没有特定的启动模式被选择,它将执行默认的引导流程。最后,控制权被跳转到Bootloader。
6、如何保证BootRom的安全
6、如何保证BootRom的安全
-
固定在硬件中:
- BootROM代码被固化在芯片的只读存储器中,这意味着它在芯片制造过程中被烧录,并且之后无法被用户或软件更改。这种物理固定提供了最基本的安全保障,因为任何尝试读取或修改BootROM的行为都会被硬件阻止。
-
只读属性:
- BootROM的存储区域被设计为只读,防止了任何形式的写入操作。这种属性确保了BootROM中的代码和数据不会因为恶意软件或意外的错误而被改变。
-
加密和签名:
- BootROM代码可能使用加密技术来保护其内容不被读取或篡改。此外,代码可能包含数字签名,确保在启动过程中可以验证其完整性和来源。
-
一次性编程存储器(eFUSE):
- eFUSE是一种特殊的存储技术,一旦编程后就无法更改。这用于存储关键的安全参数,如安全启动密钥。eFUSE的一次性特性确保了存储在其中的根密钥不会被泄露或替换。
-
安全启动模式:
- BootROM支持安全启动模式,这通常涉及到使用公钥/私钥对来验证Bootloader的签名。只有验证通过的Bootloader才能被加载和执行。
-
隔离执行环境:
- 某些CPU设计了隔离的执行环境,如ARM的TrustZone,这允许BootROM在一个受保护的环境中运行,确保其代码和数据不受外部因素的影响。
-
物理保护:
- BootROM作为芯片的一部分,受益于物理保护措施,如防篡改封条和安全封装。这些措施可以防止物理攻击,如芯片脱焊或使用探针读取存储器内容。
-
最小化攻击面:
- BootROM代码被设计得尽可能简洁,以减少潜在的攻击面。这意味着只包含必要的功能,并且避免了不必要的复杂性。
-
错误检测和恢复:
- BootROM可能包含错误检测和恢复机制,如CRC校验或校验和,以确保代码的完整性。如果检测到错误,BootROM可以采取恢复措施,如从备份中恢复或请求用户干预。
-
安全更新:
- 虽然BootROM通常不可更改,但一些系统可能包含特殊的更新机制,允许在不破坏安全性的前提下更新BootROM。
-
防回滚机制:
- 通过在eFUSE中烧录版本信息,BootROM可以确保系统不会被降级到旧的、可能存在漏洞的固件版本。
-
启动过程的监控:
- BootROM可以监控整个启动过程,确保每个步骤都按照预期执行。如果检测到异常,BootROM可以拒绝启动或进入安全模式。
-
专用内存区域:
- BootROM可能会被映射到专用的内存地址区域,这些区域可能被设计为不可读或不可写,以防止未授权的访问。
这些措施共同构成了BootROM的多层安全防护,确保了系统在启动时的安全性和可靠性。
7、BootRom如何保证整系统的安全
7、BootRom如何保证整系统的安全
-
Root of Trust (RoT):
- RoT是整个系统安全的基础,通常由硬件组成,如芯片内的BootROM。
- 它负责在系统启动时执行第一个指令,并确保所有后续软件的验证和加载。
-
Boot ROM/Bootloader Verification:
- BootROM中的代码会检查Bootloader的签名,确保它没有被篡改。
- 这通常涉及到使用公钥基础设施(PKI),其中BootROM包含一个或多个预先安装的公钥,用于验证Bootloader的签名。
-
Firmware Image Verification:
- 每个固件组件(如操作系统、内核、应用程序)在执行前都应进行哈希验证。
- 这可以通过将固件的哈希值与存储在安全位置(如eFUSE)中的哈希值进行比较来完成。
-
Chain of Trust:
- 信任链确保每个启动阶段都会验证下一个阶段的软件。
- 例如,BootROM验证Bootloader,Bootloader验证操作系统的启动加载程序,依此类推。
-
Error Handling:
- 如果在验证过程中发现错误,如签名不匹配,BootROM应拒绝加载该组件并可能报告错误。
- 这可以防止恶意软件或损坏的固件被执行。
-
Secure Boot Keys and Certificate Management:
- 密钥和证书的安全管理是确保BootROM安全的关键。
- 这包括使用加密算法(如RSA或ECC)生成的密钥对,以及如何分发和存储这些密钥。
-
eFUSE:
- eFUSE是一种一次性可编程的存储技术,用于存储如安全启动密钥等敏感数据。
- 一旦编程,eFUSE中的数据就无法更改,为系统提供了一个高度安全的数据存储点。
-
Security Engine:
- 安全引擎是处理器内的专用硬件模块,用于执行加密操作,如AES或RSA。
- 它通常只能由BootROM或安全操作系统访问,以确保加密操作的安全性。
-
Code Isolation:
- BootROM代码应与其他系统代码隔离,以防止潜在的未授权访问。
- 这可以通过将BootROM放置在内存的受保护区域或使用硬件内存保护机制来实现。
-
Hardware Protections:
- 硬件保护机制,如内存保护单元(MPU)和安全执行环境(TEE),可以用来保护BootROM代码。
- 这些机制可以确保即使在高权限模式下,也只有授权的代码才能访问BootROM。
-
Minimalism:
- BootROM代码应保持简洁,只包含必要的功能。
- 这减少了潜在的攻击面,因为更少的代码意味着更少的可能漏洞。
-
Physical Security:
- 物理安全措施,如防篡改封条和安全封装,可以防止对设备的物理攻击。
- 这些措施有助于确保BootROM不会被物理方式访问和篡改。
-
Regular Security Audits:
- 定期进行安全审计可以帮助发现和修复BootROM中的安全漏洞。
- 这包括代码审查、渗透测试和使用自动化工具来识别安全问题。
-
Update and Patch Management:
- BootROM和其他关键固件组件应设计为可以安全地接收和应用更新。
- 这通常涉及到一个安全的更新机制,确保更新过程本身不会被利用。
-
Anti-rollback Mechanisms:
- 防回滚机制,如在eFUSE中烧录版本信息,可以确保设备不会降级到旧的、可能不安全的固件版本。
- 这有助于防止攻击者安装已知存在漏洞的旧固件。
通过这些措施的详细实施,BootROM可以为嵌入式系统提供一个安全的启动环境,从而保护整个系统免受恶意软件和其他安全威胁的侵害。
8、BootROM和OTP的关系
8、BootROM和OTP的关系
BootROM(Boot Read-Only Memory)与OTP(One-Time Programmable Memory)的合作主要用于确保设备的安全性和完整性。以下是一些具体的应用场景:
-
安全启动(Secure Boot):
- BootROM使用存储在OTP中的密钥来验证Bootloader的签名,确保系统启动时加载的是经过认证的固件 。
-
设备身份验证:
- OTP存储器中的唯一设备标识符(如MAC地址、序列号)可用于设备身份验证,确保只有合法的设备才能启动或连接到网络 。
-
加密密钥存储:
- 敏感的加密密钥和证书可以安全地存储在OTP中,这些密钥用于数据加密和解密,保护用户数据不被未授权访问 。
-
配置参数存储:
- 设备的配置参数,如网络设置、用户偏好等,可以存储在OTP中,确保即使在设备断电后也能恢复这些设置 。
-
防篡改保护:
- OTP的一次性编程特性使其成为防止硬件篡改的理想选择。任何试图读取或修改OTP中数据的行为都会使芯片永久失效,从而提供了一种防止篡改的硬件级保护 。
-
OTA(Over-The-Air)升级:
- 在OTA升级过程中,BootROM可以利用OTP来确定固件的合法性和完整性,确保只有经过验证的更新才能被应用到设备上 。
-
调试和校准:
- 在芯片生产过程中,OTP可以用来存储校准参数,这些参数在设备制造后用于调整模拟电路,确保设备性能 。
-
安全补丁管理:
- 系统可以使用OTP来存储有关可信补丁或更新的信息,以确保只有来自可信源的补丁被应用到系统中 。
-
启动完整性检查:
- OTP中的值可以用于在每次启动时生成或验证哈希值,以确保引导代码和系统文件未被篡改 。
-
防止未授权访问:
- OTP中的信息可以用于创建访问控制规则,确保只有经过授权的实体才能访问系统的关键资源和功能 。
总结:
这些应用场景展示了BootROM和OTP如何共同工作,以提供强大的安全保障。通过将关键的安全相关的数据存储在OTP中,并由BootROM在系统启动时进行验证,可以确保设备的安全性和数据的完整性。