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

UEFI应用调用gRT->GetVariable()返回Not Found问题求助

问题描述

在搭载Ubuntu系统的QEMU环境中,编写的UEFI应用调用gRT->GetVariable()读取名为my_variable的变量时,返回Not Found状态,但通过Ubuntu脚本设置变量后,在UEFI Shell中使用dmpstore命令可确认变量存在,值为0x64(100),且具备Non-Volatile、Boot Service Access、Runtime Service Access属性,符合UEFI应用访问的要求。

UEFI应用读取变量的核心代码:

EFI_STATUS
EFIAPI
UefiMain(
    IN EFI_HANDLE ImageHandle,
    IN EFI_SYSTEM_TABLE *SystemTable
) {
    EFI_STATUS Status;
    UINT8 CheckValue;
    UINTN DataSize = sizeof(CheckValue);
    UINT32 Attributes;  

    Status = gRT->GetVariable(
        L"my_variable",
        &MyGuid,
        &Attributes,    
        &DataSize,
        &CheckValue
    );
    if (EFI_ERROR(Status)) {
        Print(L"Error: variable not found. Returning\n");
        return EFI_SUCCESS;
    }

    if (CheckValue != 100) {
        Print(L"Variable is not set to 100. Returning\n");
        return EFI_SUCCESS;
    }

    // 后续逻辑(省略)
    return EFI_SUCCESS;
}

Ubuntu设置变量的脚本:

#!/bin/bash

VAR_NAME="my_variable"
GUID="12345678-1234-1234-1234-123456789abc"
DATA_FILE="/tmp/check_data"

echo -ne '\x07\x00\x00\x00\x64' > "$DATA_FILE"

sudo efivar --name "${GUID}-${VAR_NAME}" --write --data "$DATA_FILE"

rm "$DATA_FILE"
排查与解决方法

1. 确认GUID完全匹配

UEFI变量通过GUID+变量名唯一标识,必须确保代码中的MyGuid定义与脚本中的GUID完全一致,包括字节序和大小写:

  • 脚本中的GUID为12345678-1234-1234-1234-123456789abc,对应的C语言GUID定义应为:
EFI_GUID MyGuid = {
    0x12345678,
    0x1234,
    0x1234,
    {0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}
};
  • 常见错误:Data4的字节顺序颠倒,或GUID某一段数值写错。

2. 检查变量名的Unicode编码一致性

UEFI变量名采用UTF-16LE编码,代码中L"my_variable"会生成正确的UTF-16LE字符串,需确保:

  • 脚本中的VAR_NAME与代码中的变量名完全一致(大小写、拼写无错误)。
  • 纯ASCII名称无需额外编码处理,efivar会自动转换为UTF-16LE。

3. 修正变量数据格式

脚本中写入的前4字节\x07\x00\x00\x00属于冗余数据,UEFI变量数据部分无需前缀,直接存储原始字节流即可,建议修改脚本:

echo -ne '\x64' > "$DATA_FILE"

冗余数据虽不会直接导致Not Found,但可能引发后续读取逻辑异常。

4. 解决QEMU与主机EFI变量隔离问题

这是最可能的根本原因:Ubuntu主机的efivar操作的是主机自身的UEFI变量存储,而QEMU运行OVMF固件时默认使用独立的变量镜像文件(如OVMF_VARS.fd),两者完全隔离。

解决方法:

  • 在QEMU内部设置变量:启动QEMU进入UEFI Shell,执行命令:
    setvar my_variable -guid 12345678-1234-1234-1234-123456789abc -nv -bs -rt -byte 0x64
    
  • 保存OVMF变量镜像:在UEFI Shell中设置变量后,确保QEMU启动时加载修改后的OVMF_VARS.fd。
  • QEMU启动时注入变量:通过命令行参数直接传递变量(需QEMU支持):
    qemu-system-x86_64 ... -global driver=efi-variable,property=variable-name,value="my_variable" -global driver=efi-variable,property=variable-guid,value="12345678-1234-1234-1234-123456789abc" -global driver=efi-variable,property=variable-data,value="\x64"
    

5. 验证UEFI应用的编译链接

确保代码中的MyGuid已正确定义并链接:

  • 检查编译时是否存在MyGuid未定义的警告/错误,未定义的GUID会导致传递给GetVariable的地址无效,进而返回Not Found。
  • 确认GUID定义已包含在编译范围内,或通过头文件正确引入。

6. 检查变量属性的有效性

确保变量未被设置EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS或EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS属性,这类属性会限制未授权的读取操作。若存在此类属性,需重新设置变量时移除,或在代码中添加认证逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 17:29:56