Step to UEFI (230)OVMF 一个FV 的打包过程分析

前面介绍了如何EDK2在编译的最后过程中使用了 GenFds 进行打包。分析的目标是 QEMU 的 BIOS 文件 OVMF.FD,使用 UEFITool NE 打开之后,可以看到有三个 FV ,我们以中间的为例,分析它的生成方法。整体分析过程比较枯燥,对于大多数人来说了解大致的步骤就可以了。

首先,在 FDF 文件中,给出了这个 FV 的GUID 可以看到:

[FV.FVMAIN_COMPACT]
FvNameGuid         = 48DB5E17-707C-472D-91CD-1613E7EF51B0
FvAlignment        = 16
ERASE_POLARITY     = 1
MEMORY_MAPPED      = TRUE
STICKY_WRITE       = TRUE
LOCK_CAP           = TRUE
LOCK_STATUS        = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP  = TRUE
WRITE_STATUS       = TRUE
WRITE_LOCK_CAP     = TRUE
WRITE_LOCK_STATUS  = TRUE
READ_DISABLED_CAP  = TRUE
READ_ENABLED_CAP   = TRUE
READ_STATUS        = TRUE
READ_LOCK_CAP      = TRUE
READ_LOCK_STATUS   = TRUE

上面的FV 是由两个 Section 构成的,一个是 PEIFV,另一个是 DXEFV:

1.下面是对于 PEIFV 的定义:

PEIVFV 定义
[FV.PEIFV]
FvNameGuid         = 6938079B-B503-4E3D-9D24-B28337A25806
BlockSize          = 0x10000
FvAlignment        = 16
ERASE_POLARITY     = 1
MEMORY_MAPPED      = TRUE
STICKY_WRITE       = TRUE
LOCK_CAP           = TRUE
LOCK_STATUS        = TRUE
WRITE_DISABLED_CAP = TRUE
WRITE_ENABLED_CAP  = TRUE
WRITE_STATUS       = TRUE
WRITE_LOCK_CAP     = TRUE
WRITE_LOCK_STATUS  = TRUE
READ_DISABLED_CAP  = TRUE
READ_ENABLED_CAP   = TRUE
READ_STATUS        = TRUE
READ_LOCK_CAP      = TRUE
READ_LOCK_STATUS   = TRUE

APRIORI PEI {
  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
}

2.下面是 DXEFV 的定义

DXEFV的定义

[FV.DXEFV]

FvForceRebase      = FALSE

FvNameGuid         = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1

BlockSize          = 0x10000

FvAlignment        = 16

ERASE_POLARITY     = 1

MEMORY_MAPPED      = TRUE

STICKY_WRITE       = TRUE

LOCK_CAP           = TRUE

LOCK_STATUS        = TRUE

WRITE_DISABLED_CAP = TRUE

WRITE_ENABLED_CAP  = TRUE

WRITE_STATUS       = TRUE

WRITE_LOCK_CAP     = TRUE

WRITE_LOCK_STATUS  = TRUE

READ_DISABLED_CAP  = TRUE

READ_ENABLED_CAP   = TRUE

READ_STATUS        = TRUE

READ_LOCK_CAP      = TRUE

READ_LOCK_STATUS   = TRUE

APRIORI DXE {

  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf

  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf

  INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf

!if $(SMM_REQUIRE) == FALSE

  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf

!endif

}

这里可以使用 UEFITool 直接将内容解压出来,例如:

必须选择 Extract Body

可以用 Z7 查看解压出来的文件,但是7Z 只能看到 PEIFV 看不到DXEFV, 我猜测是因为格式原因,只能看到前面一半:

7Z 打开查看的结果

具体的 DXEFV 和 PEIFV 可以在 \Build\OvmfX64\DEBUG_VS2015x86\FV 下面看到:

使用这两个文件生成的

有了这两个文件,就可以生成出现在 OVMF.FD  中的 FV 了。为了便于描述,使用下面的流程图:

生成的流程和关系

CMD1:   生成 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.1fv.sec

GenSec -s EFI_SECTION_FIRMWARE_VOLUME_IMAGE -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.1fv.sec d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\PEIFV.Fv

CMD2:   生成9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.2fv.sec

GenSec -s EFI_SECTION_FIRMWARE_VOLUME_IMAGE -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.2fv.sec d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\DXEFV.Fv

CMD3:  将上面两个文件合成为一个文件 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy

GenSec --sectionalign 128 --sectionalign 16 -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.1fv.sec d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.2fv.sec

CMD4: 对上面的文件进行压缩,生成 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.tmp 文件,从 11MB 压缩到了1MB左右

LzmaCompress -e -o d:\\i2c\\Build\\OvmfX64\\DEBUG_VS2015x86\\FV\\Ffs\\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.tmp d:\\i2c\\Build\\OvmfX64\\DEBUG_VS2015x86\\FV\\Ffs\\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy

CMD5: 继续打包生成 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.tmp

GenSec -s EFI_SECTION_GUID_DEFINED -g EE4E5898-3914-4259-9D6E-DC7BD79403CF -r PROCESSING_REQUIRED -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.tmp

CMD6:生成 FFS文件,9E21FD93-9C72-4c15-8C4B-E77F1DB2D792.ffs

GenFfs -t EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE -g 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792.ffs -i d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792FVMAIN_COMPACT\9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided

CMD7:最终生成  FVMAIN_COMPACT.Fv,用 Beyond Compare 可以看到这个是 OVMF.FD 的一部分。

GenFv -a d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\Ffs\FVMAIN_COMPACT.inf -o d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\FVMAIN_COMPACT.Fv -i d:\i2c\Build\OvmfX64\DEBUG_VS2015x86\FV\FVMAIN_COMPACT.inf

生成的FVMAIN_COMPACT.Fv 就是 OVMF 中间的一部分。

发表回复

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