You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于imx6ull+Yocto:如何用FitImage签名验证根文件系统?

基于Yocto的imx6ull根文件系统dm-verity验证实现方案

先明确核心问题:必须用initramfs

因为内核启动时,根文件系统还未挂载,无法直接读取哈希树和签名信息来完成dm-verity校验,必须依赖initramfs在根文件系统挂载前完成dm-verity设备的创建与校验逻辑。


1. Yocto环境配置(开启dm-verity相关支持)

在项目的local.conf中添加以下配置:

# 安装dm-verity用户空间工具
IMAGE_INSTALL:append = " device-mapper dm-verity"
# 内核开启dm-verity及签名验证支持
KERNEL_FEATURES:append = " features/device-mapper/verity.scc"
# 追加哈希算法内核配置(以SHA256为例)
KERNEL_CONFIG_FRAGMENTS += "${WORKDIR}/verity-config.cfg"

在verity-config.cfg文件中补充内核开关:

CONFIG_CRYPTO_SHA256=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y  # 开启根哈希的签名验证

2. 生成根文件系统的哈希树与根哈希签名

步骤1:构建根文件系统镜像

先通过Yocto构建出根文件系统镜像(比如rootfs.ext4),确保镜像为只读格式(后续挂载时设为ro)。

步骤2:生成dm-verity哈希树与根哈希

用veritysetup工具生成哈希树并导出根哈希:

# 生成哈希树文件rootfs_verity.hash
veritysetup format rootfs.ext4 rootfs_verity.hash
# 提取根哈希到文件
veritysetup verify rootfs.ext4 rootfs_verity.hash | grep "Root hash" | awk '{print $3}' > rootfs_roothash.txt

步骤3:签名根哈希

复用你之前用于FitImage签名的RSA密钥对,对根哈希进行签名:

openssl dgst -sha256 -sign private_key.pem -out rootfs_roothash.sig rootfs_roothash.txt

3. 将哈希树、签名整合到FitImage

修改FitImage的DTS配置文件,新增根文件系统哈希树、签名相关节点,并在启动参数中传递校验信息:

/ {
    images {
        rootfs {
            description = "Root Filesystem";
            data = /incbin/("rootfs.ext4");
            type = "filesystem";
            arch = "arm";
            os = "linux";
            compression = "none";
            hash-1 {
                algo = "sha256";
            };
        };
        rootfs_verity_hash {
            description = "RootFS Verity Hash Tree";
            data = /incbin/("rootfs_verity.hash");
            type = "verity-hash";
            arch = "arm";
            os = "linux";
            compression = "none";
            hash-1 {
                algo = "sha256";
            };
            # 对哈希树本身做签名(复用FitImage的签名密钥)
            signature-1 {
                algo = "sha256,rsa2048";
                key-name-hint = "your-signing-key-name";
                signer = "your-signer-id";
            };
        };
    };
    configurations {
        default = "config-1";
        config-1 {
            kernel = "kernel";
            rootfs = "rootfs";
            verity-hash = "rootfs_verity_hash";
            # 传递dm-verity校验参数给内核
            bootargs = "console=ttymxc0,115200 root=/dev/mapper/rootfs ro verity.rootdev=/dev/mmcblk1p2 verity.roothash=$(cat rootfs_roothash.txt) verity.signature=$(cat rootfs_roothash.sig | base64 -w0)";
        };
    };
};

注:/dev/mmcblk1p2是根文件系统所在分区,需根据你的硬件实际分区调整;签名内容用base64编码避免命令行转义问题。

4. 配置initramfs完成dm-verity初始化

步骤1:Yocto启用initramfs

在local.conf中添加:

INITRAMFS_IMAGE = "core-image-minimal-initramfs"
INITRAMFS_IMAGE_BUNDLE = "1"

步骤2:编写initramfs初始化脚本

在自定义meta层中添加init脚本(比如meta-custom/recipes-core/initramfsscripts/files/init),内容如下:

#!/bin/sh
# 挂载基础文件系统
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /tmp

# 从内核cmdline提取参数
ROOTDEV=$(cat /proc/cmdline | awk -F 'verity.rootdev=' '{print $2}' | awk '{print $1}')
ROOTHASH=$(cat /proc/cmdline | awk -F 'verity.roothash=' '{print $2}' | awk '{print $1}')
SIG=$(cat /proc/cmdline | awk -F 'verity.signature=' '{print $2}' | awk '{print $1}' | base64 -d)

# 创建临时文件存储签名
echo "$SIG" > /tmp/roothash.sig

# 初始化dm-verity设备
veritysetup create rootfs $ROOTDEV /dev/mmcblk1p3 --root-hash $ROOTHASH --signature /tmp/roothash.sig

# 挂载dm-verity设备作为根文件系统
mount /dev/mapper/rootfs /rootmnt
# 切换根文件系统
pivot_root /rootmnt /rootmnt/initramfs
exec /sbin/init

注:/dev/mmcblk1p3是哈希树镜像所在分区,若把哈希树打包进initramfs,可改用loop设备挂载。

5. 验证测试

  1. 用Yocto构建完整的签名FitImage,烧写到imx6ull的存储设备
  2. 启动设备,查看内核日志,确认dm-verity: verified OK的输出
  3. 尝试修改根文件系统分区的内容,重启后会触发dm-verity校验失败,系统无法正常启动

内容的提问来源于stack exchange,提问作者cherry411

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:12:09