当前位置: 首页 > news >正文

UEFI ——Firmware层级结构

Firmware层级结构

  • Firmware的层次结构
    • Firmware Device (FD)
    • Firmware Volume (FV)
    • Firmware File (FF)
    • Firmware File Section
    • Firmware File System (FFS)
  • Firmware 层级的格式
    • Firmware Volume Format
      • FileSystemGuid
      • Signature
    • Firmware File Format
      • Name
        • VTF
      • Type
  • 总结

UEFI 常常以二进制文件的形式展现出来,这个二进制文件通过某些手段烧录/写入flash上,就成为了计算机启动的关键代码–固件。我们能够从各个计算机厂商的官网上找到相应型号对应的BIOS文件

面对这个二进制文件,很难不去思考的两个问题:

  1. 这个文件内部的结构是什么样的?
  2. UEFI代码中是以什么样的方式组织这个文件的?
    PS:
    1.后文的所有内容都是进行简单的初级介绍,目前还没有详细深入的研究过整个的image的生成过程,因此未能详尽之处有待后续补充了
    2.后续文章中的翻译均为个人翻译,不保证准确性,请参考原文进行理解
    3.后续文件中使用的PI Spec包含了两个版本,因为最新的PI Spec中存在一些链接不能跳转以及图片模糊的问题,因此部分使用了之前版本的PI Spec。如果需要当前文章中的Spec版本可去EDKII网站或者我公众号自己找

Firmware的层次结构

想要说清楚FV中的代码结构,首先先要厘清几个常用的概念,我们以PI Spec中(Volume3)的描述来对这些概念加以区分和说明

Firmware Device (FD)

在这里插入图片描述

Firmware Device 是一个包含了固件代码或者数据的永久的物理存储设备。典型的存储设备flash,也有些其他的永久存储设备。一个物理上的FD可以进行更小的划分形成逻辑上的FD,相似的,许多物理上的小FD也可以聚合形成逻辑上的一个大FD

从上述描述中我们可以知道与FD有关的几个重要信息:

  1. FD 原意想要表示的是物理上存储固件代码的设备,比如常见的flash等,其中保存的就是编译完成之后机器的完整UEFI固件。
    在这里插入图片描述

如图,ROM中包含了某一机器的Firmware 文件,那么这个ROM就可被称之为Firmware Device。物理上,一个存储设备可以被称为一个FD,但是我们当前讨论的是Firmware文件的情况,此时一个完整的固件文件也可以被称之为FD。
2. 我们还可以将FD中的文件从逻辑上划分为更小的块,将这些更更小的块称为逻辑上的FD,这样FD就不仅仅用来指代一个完整的烧录到机器上的文件了,还可以代表文件的某一个层级 (经常用到)
3. 物理上的FD也可以被看成一个逻辑上的大FD(目前没见过这种情况)
通过上面的描述可以看出,无论是物理上还是逻辑上,FV一定是Firmware中最大的一个层级概念

Firmware Volume (FV)

在这里插入图片描述

Firmware Volume 是一种逻辑上的FD。在PI规范中,数据代码的基本存储单元就是FV。每一个FV以某一种file system的格式构成,因此file就是firmware 的基本单元

上述描述我个人觉得是非常抽象的,以我的理解用通俗的话来解释一下

  1. 每个FV是特定代码数据的聚合,每个FV都会实现自己特定的功能
  2. FV是FD的组成模块,若干个FV最终构成FD (若干个逻辑上的FD还可以组成一个大的FD 请理解好FV FD的区分)
  3. FV是由file组成的
    可见,FV是仅次于FD的下一个文件层次,而FV之下的文件层级就是file了

Firmware File (FF)

在这里插入图片描述
这一段太长,翻译部分

Firmware file 是在FV中存储代码或数据的形式,每一个FF都包含了Name Type等属性。
某些特性的FV的存储还要求FF支持额外的属性。特定的FF中的文件数据还以标准的方式细分为了Firmware File Section

简言之,FF是FV的存储形式,FF中的数据还可以更加细分为Firmware File Section

Firmware File Section

在这里插入图片描述

Firmware File Section 是特定File中的独立的部分。每一个Section都包含了Type Size两个 属性。
section可以被大致的归为两个类别: Encapsulation sections & Leaf sections

关于上述的两个section的类别。PI Spec中有更加详细的区别的描述,想要详细了解的请自己阅读PI Spec。总的来说,就是Encapsulation section可能包含了其他section的section,而Leaf section 其中的内容直接就是data 不包含其他的section了,由此也说明了section是可以套用的。

综上我们已经介绍了四个层级的详细情况,这四个层级从大到小依次为 FD->FV->FF->File section
但是经常在很多的说明文章中还会出现一个FFS的概念,为什么我没有介绍这个概念呢? 因为我个人觉得首先这个概念的本意表示的并不是一个文件层级,而是一种组织形式;其次当前这个概念的使用基本上就是替代了FF,表示组成FV的文件,但是这个现象的具体原因并不清楚,也有可能是我理解的有问题。PI Spec中关于FFS的详细描述也介绍一下,具体是什么情况大家自己判断

Firmware File System (FFS)

在这里插入图片描述

FFS描述了FV中file和空闲空间的组织形式,每一种FFS都有一个独特的GUID,firmware利用这个GUID将新发现的FVB与driver相关联。

通过这段说明应该可以说明我之前的观点:FFS本质上是FV内文件的组织形式并非层级结构的一种。但是很多时候在很多地方往往会混用FFS 和 FF,也就是将FFS这个用来描述文件组织形式的词语代指 FV中的文件,这个现象在PI Spec中就能发现: 在Firmware File Format的格式中,结构体名称就是EFI_FFS_FILE_HEADER 明显此时是FFS与FF混用了。
个人建议可以理解成符合FFS的file文件 ,这样就能比较容易的理解这个说法,其实只要看到FFS能够理解到指代的是FV中包含的文件就可以了。

Firmware 层级的格式

接下来就来看这几种文件层级的格式是什么样的,同样这里以PI Spec中的描述为主要的内容,同时会结合对BIOS image的解析对照理解更加方便。同样这个位置也是大致的介绍

Firmware Volume Format

在这里插入图片描述

PI Architecture Firmware Volume Format描述了FV中的二进制布局。FV由header和紧跟在后面的FV data两部分组成。FV header 对应的结构体为EFI_FIRMWARE_VOLUME_HEADER。
FV data的组织形式由GUID来描述,有效的GUID值有两个EFI_FIRMWARE_FILE_SYSTEM2_GUID & EFI_FIRMWARE_FILE_SYSTEM3_GUID

上述一段话主要的内容可以总结为:

  1. 标准的FV format 由两个部分组成: FV header 和 FV data
  2. FV header中的GUID 用来形容FV中的data的组织形式 (Fv的下一层级即为FF,所以此处的组织形式描述的是FF之间的组织形式,即前述FFS)
  3. 有效的GUID有两个 EFI_FIRMWARE_FILE_SYSTEM2_GUID & EFI_FIRMWARE_FILE_SYSTEM3_GUID

FileSystemGuid

EFI_FIRMWARE_VOLUME_HEADER 的结构如下
在这里插入图片描述
前述述第二点,也就是FFS Format ,描述的是同一个FV中FF的组织形式,也就是说FFS的组织形式由header中的GUID来表示。 关于这个部分详细可以参考PI Spec 2.2.2的描述
在这里插入图片描述

PI Firmware File System 是FV中文件的二进制布局 。他是一个平坦的文件系统,没有任何层次结构。所有的文件都直接存储在根路径下。文件是端到端存储的,没有任何目录描述存在哪些文件。想要解析FV获取当前存在的文件就需要将FV从头至尾进行遍历
所有以FFS形式存储的文件必须遵守 “PI Architecture Firmware File System Format” ,这个标准的文件头提供了几个层级的完整性检查,以防发生某种损坏。

在这里插入图片描述

FV header中有一个数据描述了(firmware)file system GUID。有两种类型的FFS:EFI_FIRMWARE_FILE_SYSTEM2_GUID & EFI_FIRMWARE_FILE_SYSTEM3_GUID。小于16M的file文件使用 EFI_FIRMWARE_FILE_SYSTEM2_GUID表示其 组织形式,若存在大于16M的file文件则需要选择EFI_FIRMWARE_FILE_SYSTEM3_GUID的文件组织形式。

两个GUID的具体值可以在PI Spec Vol 3 3.2.2 中看到
在这里插入图片描述

在这里插入图片描述

现在我们已经知道FV Header中是利用 FileSystemGuid 来表示不同的FFS的,
现在就可以找一个实际的UEFI 文件来对应看一下了。

在这里插入图片描述
在这里插入图片描述

上面是我从电脑厂商的官网随便dump的一个UEFI 文件然后用UEFITool进行解析的结果,可以看到这个文件的Volume就是存在了两种文件组织形式:FILE_SYSTEM2FILE_SYSTEM3。两种组织形式对应的GUID在右侧可以看到,可以和前述我们说的GUID完全对应起来,也就验证了我们前述内容的正确性

Signature

除了GUID之外,我们还可以关注一下结构体中的 Signature

在这里插入图片描述

可以看到 Spec中要求这个位置是强制设置为 _FVH 可以直接从二进制文件证实这一点如下

在这里插入图片描述

可以看到二进制文件中的每一个FV的header中都有一个_FVH 作为FV的标志

Firmware File Format

在这里插入图片描述

所有的FFS文件都以一个header开头,这个header 与 FV 的起始8 byte对齐。FFS包含了以下两个部分:header 和 Data
可以创建一个只包含header没有data的file ,使用24byte的空间,这种文件类型被称为 zero-length file
如果file包含data,data要紧跟着header。file内的data格式由header内的Type定义,file的data 格式有两种 EFI_FFS_FILE_HEADER or EFI_FFS_FILE_HEADER2。两种不同类型的header可以在PI Spec中查看

此处还要提醒一个点:前面我们说过很多情况下会用FFS来替代FF,这个位置就是一个很好的例子,PI Spec中直接说了FFS file, 但是明显此时想要形容的是FIrmware File的格式情况,是FFS与FF混用了。此处只是想进一步说明前面我说的混用情况。
两种FileHeader代码中的结构体表述如下
在这里插入图片描述

Name

需要注意的是,这个header中 Name 成员是一个GUID, 详细说明一个这个GUID的情况
在这里插入图片描述

GUID是file的名称,这个GUID作为唯一的标志用以区分file。 任何一个FV中名为某个GUID的文件只能有一个,除非这个file的type为 EFI_FV_FILETYPE_FFS_PAD

VTF

file Name中有一个特殊的名称,那就是 EFI_FFS_VOLUME_TOP_FILE_GUID
在这里插入图片描述

VTF文件必须位于FV的最后,这个文件的最后一个byte也是FV的最后一个byte。无论file是什么类型,VTF的Name GUID必须被定义为 EFI_FFS_VOLUME_TOP_FILE_GUID

查看UEFI 文件中的 VTF文件

在这里插入图片描述

可以看到当前这个VTF对应的Name GUID就是Spec中要求的GUID的值

Type

在这里插入图片描述

比较简单不翻译了。
PI Spec中规定的所有的File type类型如下
在这里插入图片描述

此处说一下 我们说的文件层次结构中的file文件相关的定义可以在 inf 文件中查看。以EDKII代码中定义VFT file为例,查看 SecCore.inf 文件可以看到该file的Name GUID 和 Type
在这里插入图片描述

由于只有EDKII的源代码,所以解析OVMF.fd为,同时对比代码中相应的file GUID 和 Type
在这里插入图片描述

Type为06,对应上面表格中06对应的正好就是PEIM类型

接下来的层级结构就是section了,这层没有详细的看就不详细介绍了,因为EDKII文件都是自动生成的,我平时能用到的最小的层级结构就是file – 用来生成Application

总结

PI Spec中有一副图能够很好的展示 Fireware File FV以下层级结构
在这里插入图片描述

而FD前面已经说过了就是FV按照一定的顺序组合起来的,组合顺序详细可以参考FDF文件。
另外还需要说明一点,就是section中是可以在包含FV的,也就是说这些结构是可以相互嵌套的,(但是只能section中包含FV,目前没有看到别的嵌套形式)
具体的例子可以参考这个结构
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [数据集][目标检测]轴承缺陷划痕检测数据集VOC+YOLO格式1166张1类别
  • wordpress评论ip异常问题
  • 美团面经到店研发
  • 微服务的多面手:Spring Cloud 多数据中心支持全解析
  • 使用Python+moviepy保存截取视频画面
  • javaweb_07:分层解耦
  • Java之TCP编程综合案例
  • 卷积神经网络的相关知识点
  • C++相关概念和易错语法(25)(列表初始化、initializer_list)
  • 【云原生】Prometheus Pushgateway使用详解
  • Java对象头里有哪些信息
  • 如何在linux系统上部署Redis
  • Android12修改设备名称
  • ARM相关知识概括
  • GitHub的详细介绍
  • 【刷算法】从上往下打印二叉树
  • CentOS7简单部署NFS
  • Docker 笔记(2):Dockerfile
  • ES学习笔记(12)--Symbol
  • EventListener原理
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • MaxCompute访问TableStore(OTS) 数据
  • MQ框架的比较
  • TypeScript迭代器
  • 阿里中间件开源组件:Sentinel 0.2.0正式发布
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 在Mac OS X上安装 Ruby运行环境
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • 正则表达式-基础知识Review
  • ​2021半年盘点,不想你错过的重磅新书
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ###C语言程序设计-----C语言学习(6)#
  • #{}和${}的区别?
  • #include
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (06)金属布线——为半导体注入生命的连接
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (20050108)又读《平凡的世界》
  • (6)STL算法之转换
  • (PADS学习)第二章:原理图绘制 第一部分
  • (poj1.3.2)1791(构造法模拟)
  • (超详细)语音信号处理之特征提取
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十) 初识 Docker file
  • (转)大型网站的系统架构
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • *算法训练(leetcode)第四十七天 | 并查集理论基础、107. 寻找存在的路径
  • .Mobi域名介绍