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

UEFI应用加载NTFS驱动异常:Type与#D未正常分配

EFI应用加载NTFS驱动异常排查求助

我正在开发一款EFI应用,用于加载NTFS驱动(ntfs_x64.efi)。通过EFI Shell执行load ntfs_x64.efi命令加载时,驱动工作完全正常;但通过EFI应用编程加载时,驱动虽能成功加载,但其Type和**#D**字段未被正确分配。

驱动状态对比

DRVVersionTypeCFGDIAG#D#CDriverNameImageName
正常(Shell加载)-正常赋值--绑定设备数---
异常(EFI应用加载)-未赋值--未赋值---

(注:正常、异常状态有对应截图可参考原提问)

以下是加载驱动的代码实现:

EFI_STATUS
EFIAPI
LoadNtfsDriver(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
    EFI_STATUS Status;
    EFI_HANDLE LoadedImageHandle;
    EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
    EFI_DEVICE_PATH_PROTOCOL *DevicePath;
    UINTN ExitDataSize = 4*1024;
    CHAR16 *ExitData = NULL;

    // Allocate memory for ExitData
    ExitData = AllocatePool(ExitDataSize);
    if (ExitData == NULL) {
        Print(L"Failed to allocate memory for ExitData.\n");
        return EFI_OUT_OF_RESOURCES;
    }
    Print(L"Memory allocated\n");

    // Get the Loaded Image Protocol for the current image to access its device handle
    Status = gBS->OpenProtocol(
        ImageHandle,
        &gEfiLoadedImageProtocolGuid,
        (VOID **)&LoadedImage,
        ImageHandle,
        NULL,
        EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    if (EFI_ERROR(Status))
    {
        Print(L"Failed to get LoadedImageProtocol: %r\n", Status);
        return Status;
    }

    // Create a device path for the NTFS driver file
    DevicePath = FileDevicePath(LoadedImage->DeviceHandle, NTFS_DRIVER_PATH);
    if (DevicePath == NULL)
    {
        Print(L"Failed to create device path for %s\n", NTFS_DRIVER_PATH);
        return EFI_NOT_FOUND;
    }

    // Load the NTFS driver (ntfs_x64.efi)
    Status = gBS->LoadImage(
        FALSE,             // Not a Boot Image
        ImageHandle,       // Parent image handle
        DevicePath,        // Path to the NTFS driver
        NULL,              // Optional source buffer
        0,                 // Size of the source buffer
        &LoadedImageHandle // Image handle for the loaded driver
    );
    if (EFI_ERROR(Status))
    {
        Print(L"Failed to load %s: %r\n", NTFS_DRIVER_PATH, Status);
        FreePool(DevicePath);
        return Status;
    }
    Print(L"%s loaded successfully.\n", NTFS_DRIVER_PATH);
    Print(L"Status: %r\n", Status);
    
    // Start the NTFS driver
    Status = gBS->StartImage(
        LoadedImageHandle,
        &ExitDataSize, // Optional exit data size
        &ExitData  // Optional exit data
    );
    if (EFI_ERROR(Status))
    {
        Print(L"Failed to start %s: %r\n", NTFS_DRIVER_PATH, Status);
    }
    else
    {
        Print(L"%s started successfully.\n", NTFS_DRIVER_PATH);
        Print(L"Status: %r\n", Status);
        Print(L"Exit Data: %s\n", ExitData);
    }

    // Free allocated device path memory
    FreePool(DevicePath);

    return EFI_SUCCESS;
}

排查思路与建议

  • 对齐Shell加载的参数上下文
    EFI Shell的load命令会默认处理驱动的依赖协议与设备上下文。尝试将LoadImage的第一个参数改为TRUE(标记为Boot Image),部分驱动依赖此标识完成设备绑定逻辑;同时确认LoadedImage->DeviceHandle是正确的文件系统设备(即EFI应用所在的存储设备),避免设备路径上下文错误。
  • 检查驱动协议注册状态
    驱动的Type和**#D**字段对应其注册的设备类型与绑定设备数。启动驱动后,调用gBS->LocateHandleBuffer查询gEfiDriverBindingProtocolGuid,验证驱动是否正确注册了驱动绑定协议。如果未注册,说明驱动初始化逻辑未执行,需检查启动参数传递是否完整。
  • 分析ExitData细节
    代码中已打印ExitData,部分驱动启动时可能返回警告信息而非错误码,仔细解析ExitData内容,获取初始化失败的具体原因。
  • 验证设备权限与协议状态
    在加载驱动前,调用gBS->ConnectController连接LoadedImage->DeviceHandle,确保文件系统协议完全初始化;同时检查OpenProtocol的权限参数,确保应用拥有足够权限访问目标设备。
  • 模拟Shell环境变量
    部分NTFS驱动依赖Shell环境中的变量(如当前文件系统标识fs0:),加载驱动前可尝试设置对应的环境变量,或检查驱动是否需要特定EFI版本的支持。

内容的提问来源于stack exchange,提问作者Abeer Ul Haq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:22:06