当我们使用如下 Command 启动 QEMU 的时候,能够将 d:\tmp 目录映射为 fs0:
.\qemu-system-x86_64.exe -bios ovmf.fd -hda fat:rw:d:\tmp\
之后,可以在这个目录中看到一个名为 NvVars 的文件。这次实验的目标是直接修改 NvVars 文件来实现调整启动顺序。例如:启动之后在 Setup 中可以看到如下4个启动设备:
1.进入Shell 后使读取变量的命令,将变量保存在 Result.txt 文件中:
Dmpstore >> result.txt
2.在 Debug Log 中可以看到如下字样,就是说 OVMF 在启动过程中会读取NvVars这个文件作为变量:
InstallProtocolInterface: 964E5B22-6459-11D2-8E39-00A0C969723B 6B6F030
Installed Fat filesystem on 6C14698
FsAccess.c: LoadNvVarsFromFs
FSOpen: Open 'NvVars' Success
FsAccess.c: Read 10590 bytes from NV Variables file
3.进一步分析,读取动作来自 ovmfpkg\library\nvvarsfilelib\FsAccess.c 文件中的LoadNvVarsFromFs() 函数
/**
Loads the non-volatile variables from the NvVars file on the
given file system.
@param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
@return EFI_STATUS based on the success or failure of load operation
**/
EFI_STATUS
LoadNvVarsFromFs (
EFI_HANDLE FsHandle
)
4.具体读取动作在ReadNvVarsFile() 函数中:
/**
Reads the contents of the NvVars file on the file system
@param[in] FsHandle - Handle for a gEfiSimpleFileSystemProtocolGuid instance
@return EFI_STATUS based on the success or failure of the file read
**/
EFI_STATUS
ReadNvVarsFile (
IN EFI_HANDLE FsHandle
)
读取内容
FileContents = FileHandleReadToNewBuffer (File, FileSize);
if (FileContents == NULL) {
FileHandleClose (File);
return EFI_UNSUPPORTED;
}
5.读取之后使用 IterateVariablesInBuffer() 函数进行解析
/**
Iterates through the variables in the buffer, and calls a callback
function for each variable found.
@param[in] CallbackFunction - Function called for each variable instance
@param[in] Context - Passed to each call of CallbackFunction
@param[in] Buffer - Buffer containing serialized variables
@param[in] MaxSize - Size of Buffer in bytes
@return EFI_STATUS based on the success or failure of the operation
**/
STATIC
EFI_STATUS
IterateVariablesInBuffer (
IN VARIABLE_SERIALIZATION_ITERATION_CALLBACK CallbackFunction,
IN VOID *CallbackContext,
IN VOID *Buffer,
IN UINTN MaxSize
)
上面是一些基本的研究,下面尝试直接修改。在Dump 的变量文件Result.txt 中,可以看到 BootOrder 变量:
00000080: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 *................*
00000090: 00 00 00 00 7F FF 04 00-4E AC 08 81 11 9F 59 4D *........N.....YM*
000000A0: 85 0E E2 1A 52 2C 59 B2- *....R,Y.*
Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x0A
00000000: 00 00 01 00 02 00 03 00-04 00 *..........*
Variable NV+RT+BS 'EFIGlobalVariable:Key0002' DataSize = 0x0E
00000000: 00 00 00 40 3C 4A 2D 14-05 00 11 00 00 00 *...@<J-.......*
对应在 NvVars 文件中位于下面几行:
这里,将 00 00 01 00 02 00 03 00-04 00 修改为 00 00 04 00 02 00 03 00-01 00,下次再启动 QEMU 会会先启动到网卡上了。