secure boot (一)FIT Image

前言secure boot 和FIT Image是前段时间接触到的,其实早就该总结下了,奈何懒癌犯了,拖了好久才写出来。之前也有人问我,工作后最大的感受是什么?

前言

很早就应该写关于安全启动和FIT镜像的文章了,但是很久没有写下来。

曾经有人问我,工作后最让你感触的是什么?我的回答是“学得快”。

就嵌入而言,大多数应届毕业生在校时可能没有做过完整的项目,仅靠在校所学的知识很难满足公司的要求。

就基础驱动来说,之前学过魏东山老师的s3c2440课程,但是到了公司才发现这些内容其实都是老的了。

但是,这并不意味着您不需要学习这些东西。我认为学习过程中最重要的是培养自己学习的能力。

许多初学者在刚开始学习时可能会在设置环境时失败。您是否在设置环境时遇到困难并且不知道该怎么办?

我们日常开发中遇到的问题90%网上都有人遇到过并且有相应的解决方案。学习如何使用Bing、Google 和stackoverflow 等搜索工具是一项非常重要的技能。

遇到网上查不到的问题怎么办? 对于软件问题,应该先了解原理,再检查代码逻辑。对于硬件问题,请参考官方手册。 Linux内核、ARM等都提供了完整的文档,大多数问题都在文档中进行了解释。

现在,这已经太过分了。现在,让我们回到主题。

本文主要介绍FIT Image的由来、如何创建、其语法结构以及如何使用bootm启动FIT Image。

本文将帮助您做好安全启动的准备,稍后将对此进行介绍。实现ARMv8 安全启动的一种方法是使用FIT 映像特性。

zImage,uImage, Legacy uImage 和 FIT uImage

编译内核时,它会生成一个名为vmlinux 的elf 可执行文件。这是未经任何处理的原始内核elf文件。然而,最终写入嵌入式设备的并不是这个文件。这是一种经过objcopy工具处理后专门用于写入的图像格式。

原则上,镜像可以直接写入Flash来启动和运行,但Linux内核开发人员认为镜像仍然太大,因此他们压缩了镜像,并为压缩后的镜像文件创建了一个前端,并添加了一些解压缩功能。此代码构建一个名为zImage 的压缩格式的图像文件。

解压时,zImage镜像头中的解压代码进行自解压并运行解压后的内核镜像。

为了成功启动Linux内核,Uboot需要了解有关内核的一些信息。例如镜像的类型(内核镜像、dtb、ramdisk镜像)、镜像在内存中的位置、镜像的链接地址、镜像文件是否被压缩等。

为了获取这些信息,Uboot发明了一种称为uImage(也称为legacy uImage)的内核格式。 uImage由zImage处理。 uboot 有一个名为mkimage 的工具,它会在zImage 中添加一个64 字节的标头,并在标头中存储引导内核所需的信息。一旦uboot启动,它就会从头中读取所需的信息,按照指令执行相应的操作。

有关标头格式,请参阅include/image.h。 mkimage的源代码位于tools/mkimage中

FIT image的来源

为什么在使用旧版uImage 后还要创建FIT uImage?

根据Linus Torvalds 的说法,Arch/arm/mach-xxx 内核中充满了大量的垃圾代码。这是因为内核不关心板上的平台设备、资源、i2c_board_info、spi_board_info等板级细节。如果您有兴趣,请查看s3c2410 板级目录。代码量有几万行。

这就是ARM 社区引入设备树的原因。设备树允许将许多硬件细节直接传输到Linux,而不需要在内核中进行大量冗余编码。

为了更好地支持单个固件的通用性,Uboot也应该支持这个uImage固件。 FIT uImage 中添加了多个dtb 文件和ramdisk 文件。当然,如果需要的话也支持多个内核文件。

内核中FDT的整个过程就是一个扁平化的设备树,FIT的正式名称是扁平化的镜像树。 FIT使用设备树源文件(DTS)语法,生成的图像文件类似于dtb文件(简称itb)。

这样做的目的是允许Uboot通过选择特定的kernel/dtb和ramdisk来启动同一个uImage,从而允许一个uImage用于多种板类型。

关于嵌入式物联网,有很多东西需要学习。如果你不学错路线或者内容,你的工资就会增加。

免费共享约150GB的数据包。学习内容、访谈、项目都比较新、广泛。据估计,在网上购买某些鱼至少要花费几十美元。

点此寻找助手,0元领取:嵌入式物联网学习资料(今日头条)

624a083fc43b4793b92d2852c9cc8b93~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1717817867&x-signature=yy4tIfGSkyWf419aV2ioDj9bFMI%3D

f2620d0bc9e74b8ab97cf82f7b9dccc8~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1717817867&x-signature=9k3tlMrBJONUyAjZOVraq%2BzaXdU%3D

制作FIT Image

创建FIT 映像需要两个工具:mkimage 和dtc。 dtc 必须导入到环境变量$PATH 中,mkimage 将调用dtc。

mkimage 的输入是一个扩展名为.its 的图像源文件,它定义了启动过程中图像的各种属性。只要写出Image的属性就可以了。实际的Image数据在uImage内部,具体路径由它指定。

35bbde1ceafb404b80310a1b356eae6e~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1717817867&x-signature=Z692%2BeByth7hPdVMTPZv%2B4avE%2Bk%3D

下面是内核文件。后面会介绍各个内容的含义。

/* * 包含单个内核的简单U-Boot uImage 源文件*//dts-v1/;/{description=’包含单个Linux 内核的简单映像’ #address-cells=1 {description=’Vanilla Linux kernel’; data=/incbin/(‘./vmlinux.bin.gz’); # 图像数据特定路径类型=’ppc’; os=’linux’; { default=’config@ 1 { description=’Boot Linux kernel’ } };}; mkimage 的输出是一个包含所有必要数据(内核、dtb、ramdisk)的二进制文件。 )。 itb文件创建后,可以直接加载到嵌入式设备上,并通过bootm命令启动。

收集创建FIT 图像所需的四个文件。

mkimage、dtcits(图像源文件(*.its)) 图像数据文件。

its语法结构

uImage Tree 的根节点结构

/o 图像树|- 描述=’图像描述’ |- #address-cells=1 | o 图像@1 | @2 {.} |- 默认=’ conf@1′ | o conf@1 {.} o conf@2 {.} .描述:描述uImage。句子。时间戳:更改镜像镜像的时间。由mkimage 工具自动生成。 Security Boot 还将不同的时间戳视为不同的映像。映像:子映像,例如内核映像、RAM 磁盘映像等。配置:配置项节点。您可以根据不同的场景,将不同类型的二进制文件组合起来形成配置项。 u-boot在启动时逐单元加载并执行配置项,可以方便地针对不同的场景选择不同的配置。

‘/images’ node

该节点包含镜像镜像所需的信息。

o image@1 |- description=’组件子图像描述’ |- data=/incbin/(‘path/to/data/file.bin’) |- type=’子图像类型名称’ |- Arch=’ARCH 名称’ |- os=’操作系统名称’ |- 压缩=’压缩名称’ |- 负载=00000000 |- 条目=00000000 | o hash@1 {.} o hash@2 {.} .description:子镜像的文本描述。你可以随心所欲地写。 type:子镜像的类型,例如standalone、kernel、ramdisk、firmware等。 data:包含节点二进制文件的路径。压缩:压缩方式(无、gzip、bzip2等)。 os:操作系统的名称(solaris、uboot、qnx 等)。 Arch:arm、mips、i386等平台架构。 Entry:二进制文件入口地址,或者链接地址。 load:二进制文件的加载位置。 hash@1:图像中使用的验证算法(sha256、crc32等)。

Hash nodes

o hash@1 |- algo=’哈希或校验和算法名称’ |- value=[哈希或校验和值] algo:算法名称,例如crc32、md5、sha256。 value:算法校验值,即算法计算出来的值。

‘/configurations’ node

o 配置|- default=’默认配置子节点单元名称’ | o config@1 {.} o config@2 {.} .default:默认子节点配置config@ 1: 这个配置我们使用内核映像、RAM 磁盘映像等。

Configuration nodes

o config@1 |- description=’配置描述’ |- kernel=’内核子节点单元名称’ |- ramdisk=’ramdisk 子节点单元名称’ |- fdt=’fdt 子节点单元名称’ [, ‘ fdt |overlay 子节点单元名称’,] |- fpga=’fpga 子节点单元名称’ |-loadables=’loadables 子节点单元名称’ 描述:配置名称。 kernel:镜像类型为kernel的单元名称。 ramdisk:镜像类型为ramdisk的单元名称。 fdt:图像类型为fdt的单元名称。 loadables:其他可加载二进制文件的列表。 U-Boot 在指定的起始地址加载每个二进制文件。

举例

下面是一个包含内核、RAM 磁盘和FDT BLOB 映像的多个配置的文件。它包括三种配置,每种配置都有不同的内核、ramdisk 和fdt。默认配置项由“default”指定。当然,你也可以在运行时指定。

/* * 包含多个内核、ramdisk 和FDT BLOB 的U-Boot uImage 源文件*//dts-v1/;/{ description=’各种内核、ramdisk 和FDT BLOB’ #address-cells=1 ;=’vanilla-2.6.23′; 数据=/incbin/(‘./vmlinux.bin.gz’); arch=’ppc’; 负载=00000000 { algo=’ 2.6.23′ ; 数据=/incbin/(‘./2.6.23-denx.bin.gz’); 操作系统=’gzip’; 哈希@1 { 算法=’sha1′ } ; 数据=/incbin/(‘./2.4.25-denx.bin.gz) ‘); 压缩=00000000; @1 { 描述=’eldk-4.2-ramdisk’; /(‘./eldk-4.2-ramdisk’); arch=’gzip’; 条目=00000000; hash @ 1 { algo=’eldk-3.1-ramdisk’ ; ppc’; 条目=’fdt@1 }; 数据=’flat_dt’; { 描述=’tqm5200s-fdt’; 压缩=’none’; 哈希@ 1 { 默认值=’config@1′;config’; 1′ }; 描述=’tqm5200s kernel@ 2′; fdt=’fdt@2′ }; 描述=’tqm5200s denx-2.4.25 配置’;

FIT Image的编译和启动

在服务器上,您可以使用mkimage 工具创建FIT 映像。

下面是kernel_fdt.its,它是用来创建下面的itb的。

/* * 包含单个内核和FDT blob 的简单U-Boot uImage 源文件*//dts-v1/;/{ description=’包含单个Linux 内核和FDT blob 的简单映像’ #address -cells=1; kernel@1 { 描述=’Vanilla Linux 内核’; data=/incbin/(‘./vmlinux.bin.gz’); arch=’ppc’;=’sha1′ };data=/incbin/(‘./target.dtb’); arch=’ppc’; 哈希@1 { 算法=’crc32′;=’sha1′ 配置{ 默认=’ conf@1′; Description=’FDT kernel=’fdt@1′;};};}; $ mkimage -f kernel_fdt.its kernel_fdt.itbdtc: DTS -DTB on File’ Kernel_fdt.its PTION3360 使用Linux 内核和FDT Blobcreated: 3 月11 日星期二16:29:22 2008 Image 0 (kernel@1)Description:Virginia

nilla Linux kernel Type: Kernel Image Compression: gzip compressed Data Size: 1092037 Bytes = 1066.44 kB = 1.04 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: crc32 Hash value: 2c0cc807 Hash algo: sha1 Hash value: 264b59935470e42c418744f83935d44cdf59a3bb Image 1 (fdt@1) Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Size: 16384 Bytes = 16.00 kB = 0.02 MB Architecture: PowerPC Hash algo: crc32 Hash value: 0d655d71 Hash algo: sha1 Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def Default Configuration: ‘conf@1’ Configuration 0 (conf@1) Description: Boot Linux kernel with FDT blob Kernel: kernel@1 FDT: fdt@1在当前目录下就可以找到kernel_fdt.itb,itb文件就可以加载到设备上启动。
> tftp 900000 /path/to/tftp/location/kernel_fdt.itbUsing FEC deviceTFTP from server 192.168.1.1; our IP address is 192.168.160.5Filename ‘/path/to/tftp/location/kernel_fdt.itb’.Load address: 0x900000Loading: ################################################################# ###########doneBytes transferred = 1109776 (10ef10 hex)=> iminfo## Checking Image at 00900000 … FIT image found FIT description: Simple image with single Linux kernel and FDT blob Created: 2008-03-11 15:29:22 UTC Image 0 (kernel@1) Description: Vanilla Linux kernel Type: Kernel Image Compression: gzip compressed Data Start: 0x009000ec Data Size: 1092037 Bytes = 1 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: crc32 Hash value: 2c0cc807 Hash algo: sha1 Hash value: 264b59935470e42c418744f83935d44cdf59a3bb Image 1 (fdt@1) Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Start: 0x00a0abdc Data Size: 16384 Bytes = 16 kB Architecture: PowerPC Hash algo: crc32 Hash value: 0d655d71 Hash algo: sha1 Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def Default Configuration: ‘conf@1’ Configuration 0 (conf@1) Description: Boot Linux kernel with FDT blob Kernel: kernel@1 FDT: fdt@1=> bootm## Booting kernel from FIT Image at 00900000 … Using ‘conf@1’ configuration Trying ‘kernel@1’ kernel subimage Description: Vanilla Linux kernel Type: Kernel Image Compression: gzip compressed Data Start: 0x009000ec Data Size: 1092037 Bytes = 1 MB Architecture: PowerPC OS: Linux Load Address: 0x00000000 Entry Point: 0x00000000 Hash algo: crc32 Hash value: 2c0cc807 Hash algo: sha1 Hash value: 264b59935470e42c418744f83935d44cdf59a3bb Verifying Hash Integrity … crc32+ sha1+ OK Uncompressing Kernel Image … OK## Flattened Device Tree from FIT Image at 00900000 Using ‘conf@1’ configuration Trying ‘fdt@1’ FDT blob subimage Description: Flattened Device Tree blob Type: Flat Device Tree Compression: uncompressed Data Start: 0x00a0abdc Data Size: 16384 Bytes = 16 kB Architecture: PowerPC Hash algo: crc32 Hash value: 0d655d71 Hash algo: sha1 Hash value: 25ab4e15cd4b8a5144610394560d9c318ce52def Verifying Hash Integrity … crc32+ sha1+ OK Booting using the fdt blob at 0xa0abdc Loading Device Tree to 007fc000, end 007fffff … OK[ 0.000000] Using lite5200 machine description[ 0.000000] Linux version 2.6.24-rc6-gaebecdfc (m8@hekate) (gcc version 4.0.0 (DENX ELDK 4.1 4.0.0)) #1 Sat Jan 12 15:38:48 CET 2008

bootm启动不同的配置

对于FIT Image,bootm有多种启动方式。
1. bootm <addr1>2. bootm [<addr1>]:<subimg1>3. bootm [<addr1>]#<conf>[#<extra-conf[#…]]4. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2>5. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> [<addr3>]:<subimg3>6. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> <addr3>7. bootm [<addr1>]:<subimg1> – [<addr3>]:<subimg3>8. bootm [<addr1>]:<subimg1> – <addr3>对于有多种镜像,多套配置的itb,都是以configurations 中default 指定的配置启动。
bootm 200000也可以手动指定使用那套配置
bootm 200000#cfg@1也可以手动搭配不同的镜像节点启动
bootm 200000:kernel@1 800000:ramdisk@2bootm 200000:kernel@1 800000:ramdisk@1 800000:fdt@1bootm 200000:kernel@2 200000:ramdisk@2 600000bootm 200000:kernel@2 – 200000:fdt@1如果bootm的时候不指定地址,则会使用CONFIG_SYS_LOAD_ADDR配置的地址。

总结

本文对FIT Image作了简单的介绍,更详细的内容可以参考官方文档。后面有时间会动手制作一个FIT Image在板子上跑下。
FIT Image可以兼容于多种板子,而无需重新进行编译烧写。对于有多个kernel节点或者fdt节点等等,兼容性更强。同时,可以有多种configurations,来对kernel、fdt、ramdisk来进行组合。

本文参考

https://www.elecfans.com/emb/20190402899374.html
http://www.wowotech.net/u-boot/fit_image_overview.html
howto.txt
command_syntax_extensions.txt
source_file_format.txt
来源:嵌入式与Linux那些事
本文转载自“嵌入式与Linux那些事”,如有侵权,请联系删除原文链接:secure boot (一)FIT Image
版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

原创文章,作者:小条,如若转载,请注明出处:https://www.sudun.com/ask/85182.html

Like (0)
小条的头像小条
Previous 2024年6月1日 上午11:37
Next 2024年6月1日 上午11:38

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注