如何在EFI控制台的startup.nsh中读取按键至变量?
在EFI Shell的startup.nsh中实现按键输入存储与菜单功能
多数原生EFI Shell确实没有内置Input或InputCh命令,UEFI 2.2文档里提到的这类命令并未被广泛实现。要实现类似Windows批处理set /p的功能,主要有两种可行方案:
一、使用现成第三方EFI工具
很多开源EFI工具集里包含能读取按键并写入环境变量的小应用(比如常见的ReadKey或InputVar)。将这类工具放到EFI分区的可访问路径下,就能在startup.nsh中调用:
:MENU_START cls echo 请选择操作: echo ---------------- echo 1. 运行磁盘工具 echo 2. 启动自定义内核 echo 3. 退出Shell echo ---------------- # 调用ReadKey工具,将输入的按键存入CHOICE变量 \EFI\Tools\ReadKey.efi CHOICE # 根据输入执行对应操作 if "%CHOICE%" == "1" then \EFI\Apps\DiskTool.efi elif "%CHOICE%" == "2" then \EFI\Kernel\CustomKernel.efi elif "%CHOICE%" == "3" then exit else echo 无效选项,请按任意键重试... pause goto :MENU_START endif
这类工具可以在开源EFI项目仓库中找到,比如基于EDK2开发的工具集。
二、自行编写极简EFI应用
如果找不到合适的现成工具,用EDK2写一个几百行的小应用就能实现需求,核心是调用UEFI的键盘输入接口并操作环境变量。核心代码示例:
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellLib.h> #include <Library/UefiApplicationEntryPoint.h> EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_INPUT_KEY Key; CHAR16 KeyBuffer[2] = {0}; EFI_STATUS Status; CHAR16 *VarName; // 读取单个按键输入 Status = SystemTable->ConIn->ReadKeyStroke(SystemTable->ConIn, &Key); if (EFI_ERROR(Status)) { Print(L"读取按键失败: %r\n", Status); return Status; } // 转换为可存储的字符串(仅处理可打印字符) if (Key.UnicodeChar >= 0x20 && Key.UnicodeChar <= 0x7E) { KeyBuffer[0] = Key.UnicodeChar; } // 获取脚本传入的变量名参数 VarName = ShellGetArg(1); if (VarName == NULL) { Print(L"请指定要存储的变量名\n"); return EFI_INVALID_PARAMETER; } // 将按键值写入环境变量 Status = ShellSetEnvironmentVariable(VarName, KeyBuffer); if (EFI_ERROR(Status)) { Print(L"写入环境变量失败: %r\n", Status); } return Status; }
用EDK2编译成ReadKey.efi后,就能像第一种方案那样在脚本中调用。
三、无额外工具的替代方案(体验较差)
如果暂时无法添加工具,可通过循环+pause实现菜单,但无法捕获输入值,只能靠用户输入后手动触发,体验不佳,不推荐用于正式场景。
内容的提问来源于stack exchange,提问作者Jiri
相关产品推荐
相关产品推荐

