Skip to the content.

具体的源码分析

OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c

[!NOTE] 参考神奇海螺的意见,有待验证

这个文件为什么这么长?

这个文件 (OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c) 是 EDK II 项目中用于 OVMF (Open Virtual Machine Firmware) 的一个库实现。它主要负责处理从 QEMU 获取启动顺序信息,并根据这些信息来 控制虚拟机中的设备连接和启动选项排序。

为什么这个文件有2000多行?主要有以下几个原因:

核心功能 这个库的主要目标是:

  1. 从 QEMU 的 fw_cfg 接口读取 “bootorder” 配置
  2. 将 OpenFirmware 设备路径转换为 UEFI 设备路径
  3. 根据转换后的路径连接设备树
  4. 重写 UEFI 的 BootOrder 变量

复杂性来源 (导致代码量大)

  1. 设备路径转换逻辑复杂 代码需要处理多种不同类型的 OpenFirmware 设备路径到 UEFI 设备路径的转换,每种设备类型都需要专门的处理逻辑:
    • PCI 设备路径 (包括 PCI 桥、IDE、SATA、SCSI、NVMe、USB 存储等)
    • MMIO 设备路径 (如 virtio-mmio 设备)
    • 每种转换都需要解析特定格式并生成对应的 UEFI 设备路径节点
  2. 解析器实现详细 包含复杂的字符串解析逻辑来处理 OpenFirmware 路径格式,包括:
    • 字符分类函数
    • 数值解析 (十六进制列表解析)
    • 设备路径节点解析
    • 错误处理和边界检查
  3. 多种使用场景 代码实现了多个不同的 API 函数:
    • ConnectDevicesFromQemu() - 连接设备
    • SetBootOrderFromQemu() - 设置启动顺序
    • StoreQemuBootOrder() - 存储启动顺序
    • GetFrontPageTimeoutFromQemu() - 获取前端页面超时时间
  4. 容错和兼容性 代码包含了大量的边界检查、错误处理和兼容性处理,例如特殊处理 rom@ 设备路径来兼容 QEMU 的某些行为。

  5. 内存管理 需要动态分配和释放内存来存储临时数据结构,以及处理设备路径的转换结果 。

总的来说,虽然核心概念相对简单(读取配置并按此排序启动),但由于需要 支持各种不同类型的硬件设备路径转换、完善的错误处理、内存管理和 QEMU 兼容性,使得实现变得相当复杂,因此代码量达到了2000多行。这是典型的固 件开发特性:需要详尽地处理各种硬件情况和边界条件。

这段代码是什么意思

  DEBUG ((
    DEBUG_VERBOSE,
    "%a: DriverName=\"%.*a\" UnitAddress=\"%.*a\" DeviceArguments=\"%.*a\"\n",
    __func__,
    OfwNode->DriverName.Len,
    OfwNode->DriverName.Ptr,
    OfwNode->UnitAddress.Len,
    OfwNode->UnitAddress.Ptr,
    OfwNode->DeviceArguments.Len,
    OfwNode->DeviceArguments.Ptr == NULL ? "" : OfwNode->DeviceArguments.Ptr
    ));

1 函数名: DriverName=”驱动名” UnitAddress=”单元地址” DeviceArguments= “设备参数”

三个组件的含义

  1. DriverName (驱动名)
    • 对应OFW路径中的驱动/设备名部分
    • 例如在 /pci@i0cf8/ide@1,1/drive@0/disk@0 中,pci、ide、drive、disk 都是驱动名
  2. UnitAddress (单元地址)
    • 对应OFW路径中@符号后面的部分
    • 表示设备的地址或标识符
    • 例如 i0cf8、1,1、0 等
  3. DeviceArguments (设备参数)
    • 对应OFW路径中:符号后面的部分(如果存在)
    • 提供额外的设备参数
    • 在很多情况下为空

示例 如果OFW路径是 /pci@i0cf8/ide@1,1/drive@0/disk@0,可能会输出:

1 ParseOfwNode: DriverName=”pci” UnitAddress=”i0cf8” DeviceArguments=”” 2 ParseOfwNode: DriverName=”ide” UnitAddress=”1,1” DeviceArguments=”” 3 ParseOfwNode: DriverName=”drive” UnitAddress=”0” DeviceArguments=”” 4 ParseOfwNode: DriverName=”disk” UnitAddress=”0” DeviceArguments=””

这个DEBUG输出帮助开发者调试设备路径解析过程,确认每个节点的三个组成部分是否被正确解析。

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。