4. UEFI应用退出与返回
任务目标
编写一个UEFI应用程序,调用gBS->Exit()退出启动服务并返回固件。该应用在入口点执行后立即退出,返回码为EFI_SUCCESS,用于验证UEFI应用从启动服务环境正确返回固件的过程。
实现原理
UEFI应用通过固件分配的入口点被加载执行。应用可通过系统表EFI_SYSTEM_TABLE中的BootServices指针调用Exit()主动终止自身。调用后控制权交还固件,固件继续执行后续启动策略(如加载下一启动项或进入Shell)。本案例仅演示退出流程本身,不涉及资源清理或额外功能。
完整代码
#include <Uefi.h>
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
// 直接通过启动服务退出,返回EFI_SUCCESS
return SystemTable->BootServices->Exit (
ImageHandle, // 当前应用句柄
EFI_SUCCESS, // 退出码
0, // ExitDataSize
NULL // ExitData
);
}
编译与运行
- 环境准备:安装EDK II开发环境,配置好
WORKSPACE、PACKAGES_PATH等环境变量。 - 创建工程:在
AppPkg/Applications/ExitDemo/下创建ExitDemo.inf文件:
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = ExitDemo
FILE_GUID = 9E4F5A21-3D6C-4B8A-9F2E-7C1D5A8B4E62
MODULE_TYPE = UEFI_APPLICATION
ENTRY_POINT = UefiMain
[Sources]
ExitDemo.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
- 编译:在EDK II构建环境中执行:
build -p AppPkg/AppPkg.dsc -m AppPkg/Applications/ExitDemo/ExitDemo.inf
- 运行:将生成的
ExitDemo.efi复制到UEFI启动介质(如FAT32格式的U盘或QEMU虚拟磁盘),在UEFI Shell中执行:
fs0:\> ExitDemo.efi
验证方法
- 预期行为:应用执行后立即退出,Shell提示符重新出现,无任何输出信息。
- 通过条件:Shell返回提示符且无错误信息,说明
Exit()调用成功,应用已正确返回固件。若在调试器中运行,可观察到Exit()被调用后控制权回到固件Shell。 - 返回码验证:在Shell中执行
echo %lasterror%,若显示Success(或0x0),则确认退出码为EFI_SUCCESS。
常见问题
- 编译失败:确认
MODULE_TYPE为UEFI_APPLICATION且链接了UefiApplicationEntryPoint库。 - 无法在Shell中运行:确认
.efi文件位于可访问的文件系统且格式正确(FAT32)。 - 退出后系统重启:若
Exit()返回而非真正退出,通常是因为入口点返回值未被正确处理。本案例直接调用Exit(),固件应接管控制权;若固件实现有缺陷,可改用return EFI_SUCCESS作为备选方案(但本案例目标是验证Exit()路径)。