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

UEFI驱动加入BIOS自启时无法显示Hello World问题求助

问题:UEFI驱动开机自启时无法显示打印内容,黑屏但暂停功能正常

我用EDK2编写了一款UEFI驱动,功能为打印“Hello, World!”并让EFI Shell暂停60秒。手动在EFI Shell中加载该驱动时功能完全正常,但将其打包为.ffs文件加入BIOS实现开机自启后,驱动虽能使开机过程暂停60秒,但期间显示器黑屏,无法看到打印内容。

源码文件

HelloWorld.c

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>

EFI_STATUS
EFIAPI
UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    Print(L"Hello, World!\n");

    gBS->Stall(60000000);

    return EFI_SUCCESS;
}

HelloWorld.inf

[Defines]
    INF_VERSION = 0x00010006
    BASE_NAME = HelloWorld
    FILE_GUID = 77737B1F-8752-4B9A-BACB-921932118B5B
    MODULE_TYPE = UEFI_DRIVER
    VERSION_STRING = 0.1
    ENTRY_POINT = UefiMain

[Sources]
    HelloWorld.c

[Packages]
    MdePkg/MdePkg.dec

[LibraryClasses]
    UefiDriverEntryPoint
    UefiLib
    UefiBootServicesTableLib

HelloWorldPkg.dsc

[Defines]
    PLATFORM_NAME = HelloWorldPkg
    PLATFORM_GUID = B68EEAF1-9723-46CB-A5C4-384826F77110
    PLATFORM_VERSION = 0.1
    DSC_SPECIFICATION = 0x00010005
    SUPPORTED_ARCHITECTURES = X64
    BUILD_TARGETS = DEBUG|RELEASE

[LibraryClasses]
    UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
    UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
    PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
    DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
    BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
    BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
    UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
    DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
    UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
    RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
    DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf

[Components]
    HelloWorldPkg/HelloWorld.inf

问题原因

开机自启的DXE阶段中,系统的控制台输出设备还未完成初始化,此时调用Print()无法将内容输出到显示器。而手动加载时处于EFI Shell环境,控制台已经完全就绪,因此能正常显示。
此外,你的驱动类型为UEFI_DRIVER,这类驱动在DXE阶段执行,此时图形输出协议(EFI_GRAPHICS_OUTPUT_PROTOCOL)可能未初始化,或系统默认控制台输出未绑定到显示器。

解决方法

方法1:等待控制台输出设备就绪

在打印前先确认标准输出设备状态,若未就绪则改用调试输出,修改HelloWorld.c代码:

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PrintLib.h>

EFI_STATUS
EFIAPI
UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
    EFI_STATUS Status;
    // 重置并检查标准输出设备状态
    Status = gST->ConOut->Reset(gST->ConOut, FALSE);
    if (EFI_ERROR(Status)) {
        // 标准输出未就绪时用调试输出
        DebugPrint(DEBUG_INFO, L"Hello, World!\n");
    } else {
        Print(L"Hello, World!\n");
    }

    gBS->Stall(60000000);

    return EFI_SUCCESS;
}

方法2:切换驱动执行阶段

将驱动改为UEFI_APPLICATION类型,通过BIOS启动项设置开机自启,此时会在EFI Shell环境启动后执行,控制台已完全就绪。修改HelloWorld.inf中的配置:

MODULE_TYPE = UEFI_APPLICATION

方法3:使用串口调试输出(开发阶段适用)

若主板支持串口调试,可改用DebugPrint()替代Print(),通过串口工具查看输出。需在DSC文件中替换DebugLib为串口版本:

DebugLib|MdePkg/Library/UefiDebugLibSerial/UefiDebugLibSerial.inf

额外注意事项

  • 打包.ffs文件时,确保驱动被放置在BIOS的DXE阶段执行区域,避免因过早执行导致硬件未初始化。
  • 部分主板开机初期会禁用显示器输出,直到特定阶段才开启,这种情况可通过串口调试确认内容是否正常输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 20:43:29