[QEMU]QEMU 固件配置 (fw_cfg) 设备

来宾端硬件接口
此硬件接口允许客户机检索各种数据项(blob),这些数据项可能会影响固件本身的配置方式,或者可能包含要为客户机操作系统安装的表。示例包括设备启动顺序、ACPI 和 SMBIOS 表、虚拟机 UUID、SMP 和 NUMA 信息、用于直接 (Linux) 内核启动的内核/初始化映像等。
选择器(控制)寄存器
只写
位置:取决于平台(IOport 或 MMIO)
宽度:16 位
字节序:小端序(如果 IOport)或大端序(如果 MMIO)
写入此寄存器可设置固件配置项目的索引,随后可以通过数据寄存器访问该项目。
设置选择器寄存器将导致数据偏移量设置为零。数据偏移量会影响通过数据寄存器访问哪些数据,下面将对此进行说明。
选择器寄存器的 Bit14 指示是否正在写入配置设置。值为 0 表示仅读取项目,并且将忽略对数据端口的所有写入访问权限。值为 1 表示可以通过写入数据寄存器来覆盖项目的数据。换言之,当选择器值介于 0x4000 0x7fff 或 0xc000 0xffff 之间时,将启用配置写入模式。
注意
从 QEMU v2.4 开始,不再支持写入 fw_cfg 数据寄存器,并且将被忽略(被视为无操作)!
注意
从 QEMU v2.9 开始,写入操作将恢复,但只能通过 DMA 接口恢复(见下文)。此外,任何特定项目的可写性在选择器键值中独立于 Bit14 进行控制。
选择器寄存器的 Bit15 指示配置设置是否特定于体系结构。值为 0 表示该项是通用配置项。值为 1 表示该项特定于特定体系结构。换言之,通用配置项目使用介于 0x0000-0x7fff 之间的选择器值进行访问,而体系结构特定的配置项目使用介于 0x8000-0xffff 之间的选择器值进行访问。
数据寄存器
读/写(自 QEMU v2.4 起忽略写入,但请参阅 DMA 接口)
位置:取决于平台(IOport)1或 MMIO)
宽度:8 位(如果是 IOport),8/16/32/64 位(如果是 MMIO)
字节序:字符串保留
1
在将数据寄存器公开为 IOport 的平台上,其端口号将始终比选择器寄存器的端口号大 1。换句话说,两个端口重叠,不能单独映射。
数据寄存器允许访问每个固件配置数据项的字节数组。通过写入选择器寄存器来选择特定项目,如上所述。
最初,在写入选择器寄存器后,数据偏移量将设置为零。每次成功访问数据寄存器都会将数据偏移量增加适当的访问宽度。
每个固件配置项目都有与该项目关联的最大数据长度。在数据偏移量超过此最大数据长度的末尾后,任何读取都将返回0x00的数据值,并且将忽略所有写入。
数据寄存器的 N 字节宽读取将以子字符串的形式返回所选固件配置项的下一个可用 N 字节,地址顺序递增,类似于 memcpy()。
注册位置
x86, x86_64
选择器寄存器 IOport:0x510
数据寄存器 IOport:0x511
DMA 地址 IOport: 0x514
手臂
选择器寄存器地址:基数 + 8(2 字节)
数据寄存器地址:基数 + 0(8 字节)
DMA 地址地址:基本地址 + 16(8 字节)
接口
fw_cfg设备使用 ACPI ID 定义。由于我们希望 ACPI 表通过fw_cfg设备本身传递到来宾中,因此来宾端固件无法使用 ACPI 查找fw_cfg。但是,固件完成 ACPI 表的设置并将控制权移交给来宾内核后,后者可以使用 fw_cfg ACPI 节点来更准确地列出正在使用的 IOport 或 MMIO 区域。QEMU0002
固件配置项
签名(密钥0x0000,FW_CFG_SIGNATURE
)
通过使用密钥0x0000()选择“签名”项,并从数据寄存器读取四个字节,可以验证fw_cfg选择器和数据寄存器的存在。如果fw_cfg设备存在,则读取的四个字节将包含字符 。FW_CFG_SIGNATURE
QEMU
如果 DMA 接口可用,则读取 DMA 地址寄存器将返回0x51454d5520434647(大端格式)。QEMU CFG
修订/特征位图(键0x0001,FW_CFG_ID
)
此项是一个 32 位小端序无符号 int,用于检查已启用的功能。
位 0:传统接口。始终设置。
位 1:DMA 接口。
文件目录(密钥0x0019,FW_CFG_FILE_DIR
)
存储在选择器键0x0020或更高(或更高)处的固件配置项在目录结构中具有关联的条目,这使得来宾端固件更容易识别和检索它们。此文件目录的格式(来自 QEMU 源代码树中)如下所示,为清楚起见,略带注释:FW_CFG_FILE_FIRST
fw_cfg.h
struct FWCfgFiles { /* the entire file directory fw_cfg item */ uint32_t count; /* number of entries, in big-endian format */ struct FWCfgFile f[]; /* array of file entries, see below */};struct FWCfgFile { /* an individual file entry, 64 bytes total */ uint32_t size; /* size of referenced fw_cfg item, big-endian */ uint16_t select; /* selector key of fw_cfg item, big-endian */ uint16_t reserved; char name[56]; /* fw_cfg item name, NUL-terminated ascii */};
所有其他数据项
请查阅 QEMU 源代码,了解最新、最权威的选择器键列表及其各自项目的用途、格式和可写性。
范围
从理论上讲,可能最多有0x4000个通用固件配置项,以及最多0x4000个特定于体系结构的固件配置项。
选择器注册
范围使用情况
0x0000 - 0x3fff
通用(0x0000 - 0x3fff,通常是 RO,可能通过 QEMU v2.9+ 中的 DMA 接口进行 RW)
0x4000 - 0x7fff
通用(0x0000 - 0x3fff,RW,在 QEMU v2.4+ 中忽略)
0x8000 - 0xbfff
特定 (0x0000 - 0x3fff,通常是 RO,可能通过 QEMU v2.9+ 中的 DMA 接口进行 RW)
0xc000 - 0xffff
特定(0x0000 - 0x3fff,RW,在 v2.4+中忽略)
实际上,允许的固件配置项目的数量取决于计算机类型/版本。
来宾端 DMA 接口
如果设置了特征位图的位 1,则存在 DMA 接口。这不会取代现有的fw_cfg界面,它是一个附加组件。此接口可通过 64 位宽地址寄存器使用。
地址寄存器采用大端格式。寄存器的值为 0,在启动时和操作之后。写入最低有效值的一半(偏移量为 4 时)会触发操作。这意味着具有 32 位地址的操作只需一次写入即可触发,而具有 64 位地址的操作可以通过一次 64 位写入或两次 32 位写入来触发,从最高有效部分(偏移量 0 处)开始。
在此寄存器中,应写入RAM中结构的物理地址。这是结构的格式:FWCfgDmaAccess
FWCfgDmaAccess
typedef struct FWCfgDmaAccess { uint32_t control; uint32_t length; uint64_t address;} FWCfgDmaAccess;
结构的字段处于大端模式,最低地址的字段为字段。control
该字段具有以下位:control
位 0:错误
第 1 位:读取
第 2 位:跳过
第 3 位:选择。上面的 16 位是选定的索引。
第 4 位:写入
触发操作时,如果字段设置了位 3,则上面的 16 位将解释为固件配置项目的索引。这与编写选择器寄存器具有相同的效果。control
如果字段设置了位 1,则将执行读取操作。 当前选择器和偏移量的字节将被复制到字段指定的物理 RAM 地址中。control
length
address
如果字段设置了位 4(而不是位 1),则将执行写入操作。 字节将从字段指定的物理 RAM 地址复制到当前选择器和偏移量。QEMU 可防止在与当前选择器关联的项目结束之后开始或完成写入(即,无法调整项目大小)。截断的写入将完全删除。对只读项目的写入也会被拒绝。所有这些写入错误都将位 0(错误位)设置为字段。control
length
address
control
如果字段设置了位 2(既不设置位 1 也不设置位 4),则将执行 skip 操作。当前选择器的偏移量将是高级字节。control
length
要检查结果,请阅读以下字段:control
错误位设置
出了点问题。
清除所有位
传输已成功完成。
否则
传输仍在进行中(由于实现不是异步的,因此今天不会发生,但将来可能会发生)。
外部提供的项目
从 v2.4 开始,“file”fw_cfg项(即,上面带有选择器键的项目,以及fw_cfg文件目录结构中具有相应条目的项目)可以通过 QEMU 命令行插入,使用以下语法:FW_CFG_FILE_FIRST
-fw_cfg [name=]<item_name>,file=<path>
艺术
-fw_cfg [name=]<item_name>,string=<string>
从 v5.1 开始,QEMU 允许某些对象生成特定于fw_cfg的内容,然后使用以下语法,使用命令行中的“gen_id”选项将内容与“文件”项相关联:
-object <generator-type>,id=<generated_id>,[generator-specific-options] \-fw_cfg [name=]<item_name>,gen_id=<generated_id>
有关更多文档,请参见 QEMU 手册页。
建议仅使用纯 ASCII 字符的item_name。
以 开头的项目名称是为用户保留的。QEMU 永远不会创建具有此类名称的条目,除非用户明确排序。opt/
为避免不同用户之间发生冲突,强烈建议您使用以 开头的名称,其中 RFQDN 是您控制的反向完全限定域名。例如,如果SeaBIOS想要定义其他名称,则前缀将是合适的。opt/RFQDN/
opt/org.seabios/
由于历史原因,是为 OVMF 固件保留的。opt/ovmf/
前缀是为 QEMU 本身保留的。opt/org.qemu/
使用不以 开头的名称具有潜在危险性,并且完全不受支持。QEMU 将警告您尝试。opt/
使用不以开头的名称是可以容忍的“gen_id”(即,警告被抑制),但您必须确切地知道自己在做什么。opt/
所有外部提供fw_cfg项目对客人都是只读的。