You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UEFI返回内存映射与QEMU配置不符,是哪方问题?

问题分析与解决

一、内存映射获取代码存在逻辑错误

你的memory_map函数处理EFI_BUFFER_TOO_SMALL的方式不符合UEFI规范:

  • UEFI明确规定,当BS->GetMemoryMap()返回EFI_BUFFER_TOO_SMALL时,会自动将*map_size更新为所需的最小缓冲区大小,无需手动计算增量。
  • 你当前每次仅增加单个描述符大小的逻辑,可能导致多次无效循环,甚至在某些场景下无法获取完整的内存映射。

修正后的代码如下:

static efi_status_t memory_map(efi_memory_descriptor_t **map_buf, uintn_t *map_size, uintn_t *desc_size) {
    *map_size = 0; // 初始设为0,让BIOS返回所需大小
    efi_status_t ret;
    uintn_t key;
    uint32_t version;

get_map:
    // 释放之前的缓冲区(首次循环时map_buf为NULL,FreePool会安全处理)
    if (*map_buf != NULL) {
        BS->FreePool((void*)*map_buf);
        *map_buf = NULL;
    }

    ret = BS->AllocatePool(EfiLoaderData, *map_size, (void**)map_buf);
    if (ret != EFI_SUCCESS) {
        ST->ConOut->OutputString(ST->ConOut, L"ERROR: Failed to allocate pool for memory map\n\r");
        return ret;
    }

    ret = BS->GetMemoryMap(map_size, *map_buf, &key, desc_size, &version);
    if (ret == EFI_BUFFER_TOO_SMALL) {
        goto get_map;
    } else if (ret != EFI_SUCCESS) {
        ST->ConOut->OutputString(ST->ConOut, L"ERROR: Failed to get memory map\n\r");
        BS->FreePool((void*)*map_buf);
        *map_buf = NULL;
    }

    return ret;
}

二、QEMU -m 100M的实际含义与统计误区

你看到的350M并非QEMU异常,而是对内存映射的统计逻辑有误:

  • -m 100M是分配给虚拟机的物理内存总容量,但UEFI固件(如OVMF)会占用一部分内存,同时还要为PCI设备、ACPI表、固件保留区等预留空间。
  • 你大概率是累加了所有类型的内存描述符大小,其中包含大量不可用区域:
    • EfiReservedMemoryType(固件保留内存)
    • EfiMemoryMappedIO(设备IO内存)
    • EfiACPIReclaimMemory(ACPI可回收内存)
    • 只有EfiConventionalMemory才是可供引导程序/操作系统使用的常规内存,这部分大小才会接近你设置的100M(扣除固件占用后)。

三、验证与排查方法

  1. 遍历内存映射时,仅统计EfiConventionalMemory类型的内存:
uint64_t total_conventional = 0;
efi_memory_descriptor_t *desc = *map_buf;
for (uintn_t i = 0; i < (*map_size / *desc_size); i++) {
    if (desc->Type == EfiConventionalMemory) {
        total_conventional += desc->NumberOfPages * EFI_PAGE_SIZE;
    }
    desc = (efi_memory_descriptor_t*)((uint8_t*)desc + *desc_size);
}
// 输出total_conventional,结果应接近100M(扣除固件占用部分)
  1. 检查OVMF固件配置:部分OVMF镜像默认启用了SMRAM等额外内存映射,可尝试使用精简版OVMF镜像测试。

内容的提问来源于stack exchange,提问作者Miazite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 20:42:07