UEFI - VTF

这篇文章主要介绍UEFI 架构的VTF(Volume Top File), 这个架构讲的是我们bios rom 各个Firmware Volume 组成架构,不是指软件架构 :注 : (CPU X86_64)

VTF
A Volume Top FIle(VTF) is a file that must be located such that the last byte of the file is also the last byte of the firmware volume. a VTF must have the file name GUID of EFI_FFS_VOLUME_TOP_FILE_GUID.

Firmware file system driver code must be aware of this GUID and insert a pad file as necessary to guarantee the VTF is located correctly at the top of the firmware volume on write and update.

CPU INITIALIZATION:
关于CPU 初始化的详细内容请参考“Intel Architectures”, Part3 Chapter 9. 简单讲,就是当CPU out of reset 的时候,BSP 回去执行初始化的代码,其他的AP 进入 Wait For Startup IPI 的状态。这个时候BSP 的CS 寄存器的状态是 Selector = F000h, Base = FFFF 0000h ,Limit = FFFFh。 EIP 寄存器的状态是 0000FFF0h。 这个时候BSP 是在real mode。 我们CPU 寻址呢,如果没有显示更改cs selector 的值,那么它的寻址方式CS.BASE + EIP = FFFF 0000h + FFF0h = FFFF FFF0h,这个就是CPU reset vector 地址 。那么 reset vector 地址对应的数据应该是一条有效的可执行的code。大概如下图,图画的太丑了,将就看吧。
这里写图片描述

假设我们UEFI Firmware 大小有4M, 那么它会被map CPU 地址空间,如黑色线区间(FFFC 0000 - FFFF FFFF) 。CPU 的reset vector 会在红色线的位置(FFFF FFF0)开始读取第一条指令。黄色部分是我们今天介绍的VTF, 因为这个VTF 很小,也不会超过64KB, 所以在黄色线区间跳转也不用担心会改写CS 的值。
因为红色区间(FFFF FFF0 - FFFF FFFF) 只有16个字节的大小,我们要有一条跳转指令,调到黄色线和红色线之间的地方。这个区间的地方code 作用, 大概描述一下包括如下几点:

  • 进入32bit 保护模式
  • 始能一些北桥的寄存器 (不详细讲解)
  • 初始化NEM (No Evict Mode ),就是CAR。
  • 找到SEC 入口地址,然后跳入SEC

本文主要讲解一下 ,build tool 是如何产生VTF;

最后也会有一个目标,就是我们自己写一个VTF,然后能找到SEC 并且,跳入SEC 入口函数,就算成功。

名言说的好“Talk is cheap. Show me the code.”,翻译过来就是“不要穷白活,给我看你的代码”。个人觉得程序员写程序是非常重要的,即使这个function 功能,你大概看懂了,那么自己写一个试试,就算你照着敲代码,然后调试一遍,你会发现很多细节的东西。

Start:
因为用虚拟机比较方便,我们一般学习的时候可以选择(OvmfPkg, Nt32PKg, EmulatorPkg)本人如果学习与机器无关的知识最喜欢用EmulatorPkg, 用惯了linux ,gdb 源码调试又非常方便。机器相关的一般就用实体机器上的ddt 追code。因为今天是关于VTF 的,Emulator 没有VTF 的代码,我们就选择参考OvmfPkg学习一下。

(注: 本人用的是Ubuntu)
- 在目录下建立一个TestPkg文件夹,都是从OvmfPkg 里copy 出来的,这个package 里只放了ResetVector 和 SEC
这里写图片描述
- build -p TestPkg/TestPkg.dsc -j log.txt -d 9
- 我们通过 查看log.txt 可以看到生成Fv 的command 是 GenFV -a Ffs/*.inf -o *.Fv -i *.inf 其中-i 后面跟的.inf 文件是build tool 从Fdf 里提取出来这个Fv 的信息。
- 看code 不如自己用GDB 跟一遍,看看这个流程是怎么跑的,UEFI firmware 无论是 firmware 本身还是build tool, 我们都可以source level 去跟一下具体的流程。

Build Tool Debug
这里只讲一些方法,怎么去debug build tool 。(本文以linux 为例)
- 首先,我们应该了解如何去配置EDK 的build 环境 (具体登入官网查看TianoCore
- 当我们执行过 edksetup.sh ,我就可以执行build 这个命令。
- 找到build 工具的位置 :输入 which build 我们可以看到如下
这里写图片描述
- 打开这个build 脚本长下面的样子
这里写图片描述
代码可能看的烦,举个例子就明白了,还以之前的TestPkg 为例,我们的build 命令是 build -p TestPkg/TestPkg.dsc -j log.txt -d 9
那么执行的时候翻译过来就是这个流程

  • export PYTHONPATH = BaseTool/Source/Python
  • python2 BaseTool/Source/Python/build/build.py

很简单我们手动执行一下这些命令去build 我们的TestPkg 命令如下图
这里写图片描述
好了到这里,剩下就看自己想要看哪一部分了,source lever 很方便。(-m pdb 是python 进行单步执行的命令)

上面的是整个build firmware 的流程,都是用python 串联起来的,我之前为了看这些东西还学了两天python ,现在也忘记了。如果有的同学想去了解也要稍微学点python 。

下面看看我们今天的VTF 是如何产生的
上文提到,我们的FV 是通过 GenFv -a Ffs/*.inf -o *.Fv -i *.inf
这条命令产生的,所以,我们要研究一下GenFv

这个工具源码在BaseTools/Source/C/GenFv 目录下,可执行文件在BaseTools/Source/C/bin 下面。我们为了能source lever debug,我有时候需要修改Makefile 去关掉优化,加上符号信息。其实学习Makefile 还是很重要的。加入的修改信息(header.makefile)去这个文件里加入-g 和 -O0 其实-g 本身就有不用修改,-O0 不改也没事,默认是-O2。

看看下图的效果:
这里写图片描述

我们可以source lever debug GenFv 这个工具了,很方便的,自己跑几遍几遍就明白了。

这里写图片描述

这段程序就会判断我们Fv 里的.ffs 档案,如果是VTF 就把它在Fv 文件末端加入,其他的就从Fv 文件的开始处逐个加入。关于里面的Rebase 这个是我们代码的重定向,以后在介绍。判断VTF 文件是根据 前面提到EFI_FFS_VOLUME_TOP_FILE_GUID 和 “vtf” 关键字,具体参考 IsVtfFile ((EFI_FFS_FILE_HEADER *) FileBuffer);

VTF 生成和Uefi firmware 生成流程如何去debug方法,就介绍到这,之后会写一个VTF 。
但是写VTF 之前 还是应该先了解一下FV 的组成和PE 文件的架构。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页