欢迎光临散文网 会员登陆 & 注册

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

2022-07-20 17:55 作者:-小白之家-  | 我要投稿

来宾端硬件接口

此硬件接口允许客户机检索各种数据项(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_SIGNATUREQEMU

如果 DMA 接口可用,则读取 DMA 地址寄存器将返回0x51454d5520434647(大端格式)。QEMU CFG

修订/特征位图(键0x0001,FW_CFG_ID)

此项是一个 32 位小端序无符号 int,用于检查已启用的功能。

  • 位 0:传统接口。始终设置。

  • 位 1:DMA 接口。

文件目录(密钥0x0019,FW_CFG_FILE_DIR)

存储在选择器键0x0020或更高(或更高)处的固件配置项在目录结构中具有关联的条目,这使得来宾端固件更容易识别和检索它们。此文件目录的格式(来自 QEMU 源代码树中)如下所示,为清楚起见,略带注释:FW_CFG_FILE_FIRSTfw_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中结构的物理地址。这是结构的格式:FWCfgDmaAccessFWCfgDmaAccess

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 地址中。controllengthaddress

如果字段设置了位 4(而不是位 1),则将执行写入操作。 字节将从字段指定的物理 RAM 地址复制到当前选择器和偏移量。QEMU 可防止在与当前选择器关联的项目结束之后开始或完成写入(即,无法调整项目大小)。截断的写入将完全删除。对只读项目的写入也会被拒绝。所有这些写入错误都将位 0(错误位)设置为字段。controllengthaddresscontrol

如果字段设置了位 2(既不设置位 1 也不设置位 4),则将执行 skip 操作。当前选择器的偏移量将是高级字节。controllength

要检查结果,请阅读以下字段: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项目对客人都是只读的。


[QEMU]QEMU 固件配置 (fw_cfg) 设备的评论 (共 条)

分享到微博请遵守国家法律