Zephyr MCUBoot

MCUBoot 简介

  • MCUBoot 是可配置的安全引导加载程序,由多个行业领导者维护。它可以作为 第一或第二阶段的引导加载程序运行,支持软件映像的加密验证, 支持的加密方式如下:

    • ECDSA-P256
    • RSA-2048
    • RSA-3072
  • 默认情况下,它支持映像回滚,下载的固件会被试验性地启动一次。 初次升级引导时,如果升级映像将自身标记为已确认,则其将被保留为主映像文件。如果升级映像未被确认,则后续引导将回退至 上一个被确认的映像。如果没有可用的有效映像,作为一种安全 预防措施,设备会将自己变砖。

组成

  • MCUBoot 由两部分组成
    • bootutil (boot/bootutil)
    • boot application (每个平台在 boot目录下都有其对应的boot程序)
  • bootutil 实现了bootloader的大部分功能,但是跳转到主映像程序,这一部分是缺失的,这部分由boot application 替代实现,bootloader的功能是分离的,这样做的目的是为了方便对bootloader进行单元测试。

前提条件

  1. Zephyr所需的第一步是确保您的板子在其设备树中定义了闪存分区,这些分区包括:

    • boot_partition: for MCUboot itself
    • slot0_partition: the primary slot of Image 0
    • slot1_partition: the secondary slot of Image 0
  2. 就目前而言,两个镜像分区必须是连续的。如果MCUboot作为您的第一阶段引导加载程序,则必须配置boot_partition,以便您的SoC从复位时运行它。如果有多个可更新的映像,则其余映像的相应主分区和备用分区也必须定义(例如,Image 1的slot2_partition和slot3_partition)。

  3. 闪存分区通常在zephyr/boards文件夹中名为boards/<arch>/<board>/<board>.dts的文件中定义。

构建Bootloader

  1. 从Zephyr的角度来看,botloader也是一个普通的Zephyr应用程序,虽然CMakeLists.txt中已经完成了绝大部分操作,但是在编译之前仍然需要对一些配置进行修改,例如签名算法和主映像文件是否在每次启动之后都要对其进行验证,设置完成之后跳转到bootloader/mcuboot/boot/zephyr 目录下,然后进行编译:
cd bootloader/mcuboot/boot/zephyr
west build -b <board>
  1. 除了定义在设备树中的分区表,构建bootloader还需要一些和flash 布局有关的信息,这些信息是通过 boot/zephyr/include/target.h 进行收集的,信息源自和board相关的头文件,设备树,以及MCUBoot对不同SOC的配置。

为Bootloader构建APP

  1. 配置文件中启用 MCUboot 组件:打开 Zephyr 的配置文件 prj.conf 或 prj.{board}.conf(其中 {board} 是您所使用的开发板名称),并添加以下选项(选项开启后会自动从设备树中读取主映像分区信息,详细描述请查看partitions章节):
CONFIG_BOOTLOADER_MCUBOOT=y
  • 如果需要使用 MCUboot 的其他特性,如加密或签名,还需要配置相应的选项,MCUBOOT_GENERATE_UNSIGNED_IMAGE 选项未使能时,会开启镜像签名机制,MCUBOOT_SIGNATURE_KEY_FILE 用于设置签名文件的路径,MCUBOOT_ENCRYPTION_KEY_FILE 用于设置加密文件路径,如果没有设置签名和加密文件的路径,最后必须要手动为镜像签名。
  • 为了让app能够正确的运行,chosen节点下的zephyr,code-partition属性必须设置,否则最终生成的程序会链接出错无法运行:
/{
	chosen{
		zephyr,code-partition = &slot0_partition;
	};

&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		/* 64KB for bootloader */
		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 DT_SIZE_K(64)>;
			read-only;
		};

		/* storage: 64KB for settings */
		storage_partition: partition@10000 {
			label = "storage";
			reg = <0x00010000 DT_SIZE_K(64)>;
		};

		/* application image slot: 256KB */
		slot0_partition: partition@20000 {
			label = "image-0";
			reg = <0x00020000 DT_SIZE_K(256)>;
		};

		/* backup slot: 256KB */
		slot1_partition: partition@60000 {
			label = "image-1";
			reg = <0x00060000 DT_SIZE_K(256)>;
		};

		/* swap slot: 128KB */
		scratch_partition: partition@a0000 {
			label = "image-scratch";
			reg = <0x000a0000 DT_SIZE_K(128)>;
		};

	};
};
};
  1. 构建 Zephyr 应用程序:使用 west build 命令构建 Zephyr 应用程序,其中<board> 是您所使用的开发板名称,<app> 是您的应用程序名称:
west build -b <board> <app>

签名

  • 为了对程序进行升级,或者是引导应用程序(当 MCUBOOT_VALIDATE_PRIMARY_SLOT 使能后),必须要对程序进行签名,在MCUBoot中提供了一些用于功能测试的例程,但一定不要将其运用到产品中,因为这些密钥已经被公开到网络上。

密钥创建

./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048
  • 其中-t选项用于指定加密算法

公钥提取

  • 生成的密钥对中包含了公钥和私钥,需要从密钥对中提取公钥并插入bootloader和APP中,CONFIG_BOOT_SIGNATURE_KEY_FILE 选项用于设置生成的密钥对的路径,编译系统会从中提取出C编译器可以使用的公钥,提取出的公钥会被放到 build/zephyr/autogen-pubkey.h 中,然后被编译到程序中。

程序烧录

  • 先将bootloader烧录到芯片中,然后将主程序烧录到 flash 对应分区中,
  • 主镜像程序烧录时不可以进行全片擦除,这样会导致bootloader被擦掉。

APP中使用MCUBoot

  • 在应用程序中使用 MCUboot 库:在应用程序代码中包含 mcuboot.h 头文件,例如:
#include <mcuboot.h>
  • 然后使用其中的 API 来进行固件升级和回滚。例如,以下代码将触发一个固件升级:
int rc = boot_request_upgrade(0);
if (rc) {
    printk("Failed to request upgrade (%d)\n", rc);
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕咚.萌西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值