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
相关产品推荐
相关产品推荐

