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

如何通过EDKII编程实现带参数启动UEFI Shell?

解决方案

首先纠正你对协议的理解误区:EFI_SHELL_PARAMETERS_PROTOCOL 是UEFI Shell自身启动后,为后续在Shell环境中运行的第三方UEFI应用提供参数解析能力的协议,由Shell在自身初始化完成后、加载其他应用前安装。你在调用StartImage启动Shell前,Shell的代码还未执行,自然不可能找到这个协议,你之前对规范的描述存在理解偏差。

UEFI标准中所有UEFI应用的启动参数,都是通过其镜像句柄对应的EFI_LOADED_IMAGE_PROTOCOL的LoadOptions、LoadOptionsSize两个字段传递的,UEFI Shell也完全遵循这个规则,你已经拿到了Shell镜像的ImageInfo(就是该协议的实例),直接修改这两个字段即可实现带参数启动。

具体代码修改

在你现有代码的OpenProtocol拿到ImageInfo成功后、调用StartImage之前,添加如下代码即可:

// 示例参数:启动Shell后自动执行echo、ls命令,执行完成后退出
// 参数规则:第一个字段是Shell镜像名,后面跟参数,-c参数表示执行后续字符串中的命令
CONST CHAR16 *ShellArgs = L"Shell.efi -c \"echo Test parameter from loader && ls\"";
// LoadOptions要求是双NULL结尾的UTF-16字符串,所以长度计算要多算2个CHAR16的位置
UINTN ArgsByteSize = (StrLen(ShellArgs) + 2) * sizeof(CHAR16);

// 分配LoadOptions的内存,必须用堆内存,不可用栈内存,避免上下文切换后内存失效
Status = gBS->AllocatePool(EfiLoaderData, ArgsByteSize, &ImageInfo->LoadOptions);
if (!EFI_ERROR(Status)) {
    StrCpy((CHAR16 *)ImageInfo->LoadOptions, ShellArgs);
    ImageInfo->LoadOptionsSize = ArgsByteSize;
} else {
    Print(L"Failed to allocate load options: %r\n, fallback to no args", Status);
    ImageInfo->LoadOptions = NULL;
    ImageInfo->LoadOptionsSize = 0;
}

补充说明

  • Shell常用启动参数:
    • 不带额外参数:直接进入交互模式
    • -v:启动时输出verbose日志
    • -c "命令串":执行指定命令,执行完成后自动退出Shell,多个命令用&&分隔
  • 如果你不需要在Shell退出后保留参数内存,可以在StartImage调用返回后调用gBS->FreePool(ImageInfo->LoadOptions)手动释放内存,不手动释放也会随着Boot Services销毁自动回收。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:06:04