2. UEFI基础概念

要真正把 UEFI Shell 脚本写好,不能只记命令,而要先理解它运行在什么固件环境里、由谁加载、能访问哪些资源。UEFI 不是“新版 BIOS”这么简单,它是一套以接口规范为核心的固件运行环境。本节从规范、与传统 BIOS 的差异、启动流程以及 UEFI Shell 的生态定位四个角度,建立后续脚本开发的底层认知。

一、UEFI 规范是什么

UEFI(Unified Extensible Firmware Interface,统一可扩展固件接口)是由 UEFI Forum 维护的一套接口规范。它规定了固件在平台初始化完成后,向操作系统加载器、驱动和应用程序暴露哪些服务与数据结构。规范本身不是代码,而是“契约”:只要固件实现了这些接口,上层程序就可以在 Intel、AMD、ARM 等不同平台上以一致方式运行。

UEFI 规范中最关键的两类服务是:

  • 启动服务(Boot Services):在操作系统接管前可用,提供内存分配、协议句柄管理、事件、镜像加载(LoadImage/StartImage)等能力。UEFI Shell 和大多数 UEFI 应用都运行在启动服务阶段。
  • 运行时服务(Runtime Services):操作系统运行期间仍可调用,例如读写 NVRAM 变量、获取时间、复位系统等。

此外,UEFI 用“协议(Protocol)”组织功能,例如 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL 提供文件系统访问,EFI_SHELL_PROTOCOL 提供 Shell 环境能力。脚本能操作文件、变量、设备,本质上都是通过这些协议间接完成的。

二、传统 BIOS 与 UEFI 的核心区别

传统 BIOS 以 16 位实模式运行,依赖中断向量(INT 10h、INT 13h 等)提供显示和磁盘服务,磁盘分区受 MBR 限制,启动过程相对封闭。UEFI 则以 32/64 位保护模式为主,使用协议和服务替代中断调用,支持 GPT 分区、大于 2TB 的磁盘、图形化界面和网络栈。

对比维度 传统 BIOS UEFI
运行模式 16 位实模式 32/64 位保护模式
服务方式 中断调用(INT 13h 等) 协议 + 启动/运行时服务
分区方案 MBR,2TB 限制 GPT,支持超大磁盘
启动文件 引导扇区 + 引导代码 ESP 分区中的 .efi 应用
可扩展性 弱,依赖厂商实现 强,驱动/应用可模块化加载
Shell 支持 基本没有 内置 UEFI Shell 环境
记忆要点:BIOS 靠“中断”,UEFI 靠“协议”;BIOS 启动看引导扇区,UEFI 启动找 ESP 分区里的 .efi 文件。

三、UEFI 启动流程

典型 UEFI 启动可分为以下几个阶段:

  1. SEC 阶段:上电后执行安全验证与临时内存初始化,是固件最早运行的代码。
  2. PEI 阶段:初始化内存控制器和基本芯片组,为后续阶段准备可用的内存环境。
  3. DXE 阶段:加载并调度各类驱动,建立协议数据库,是 UEFI 功能最丰富的阶段。
  4. BDS 阶段:根据启动项(BootOrder、Boot#### 变量)选择启动设备,加载 ESP 分区中的 BOOTX64.EFI 或指定 .efi 应用。
  5. TSL 阶段:操作系统加载器接管后,调用 ExitBootServices 结束启动服务,进入 OS 运行阶段。

UEFI Shell 通常是在 BDS 阶段被选择启动的一个特殊 .efi 应用。它既可以作为临时维护入口,也可以作为脚本自动化平台。

UEFI 启动阶段与 UEFI Shell 的定位 SEC 安全验证/临时内存 PEI 内存/芯片组初始化 DXE 驱动调度/协议建立 BDS 选择启动项/加载.efi TSL OS 接管/退出启动服务 UEFI Shell(Shell.efi) 运行于 Boot Services 阶段的特殊 UEFI 应用 BDS 可启动 Shell 脚本自动化 批量部署/配置 .nsh 脚本执行 固件维护 刷写/变量管理 设备诊断 开发调试 驱动加载验证 协议测试

四、UEFI Shell 在固件生态中的定位

UEFI Shell 是固件生态中的“命令行工作台”。它位于 DXE/BDS 之后、操作系统之前,具备以下独特价值:

  • 无需操作系统:在 OS 尚未安装或无法启动时,仍可访问文件系统、变量、设备。
  • 脚本化能力:支持 .nsh 脚本,可完成条件判断、循环、变量替换和命令组合。
  • 协议访问入口:通过 dh、devices、drivers 等命令观察固件内部结构。
  • 可移植性:同一套脚本可在不同厂商、不同架构的 UEFI 平台上运行(前提是接口一致)。

在固件开发与运维中,UEFI Shell 常被用于:批量刷写固件、设置启动项、导出 NVRAM 变量、验证驱动加载、执行工厂测试脚本。它既是开发者的调试工具,也是产线和运维的自动化载体。

五、常见误区与复盘

误区一:把 UEFI Shell 当成 Linux Shell。UEFI Shell 的命令集、路径分隔符、变量语法都与 Linux 不同。例如路径使用 fs0:\ 而非 /,脚本扩展名为 .nsh。

误区二:认为 UEFI 一定比 BIOS 快。启动速度取决于固件实现和启动项配置,UEFI 的优势主要在可扩展性和大磁盘支持,而非绝对速度。

误区三:忽略启动服务与运行时服务的边界。脚本运行在 Boot Services 阶段,一旦 OS 调用 ExitBootServices,Shell 环境即结束,不能把 Shell 脚本当作常驻服务。

理解这些基础概念后,后续编写 UEFI Shell 脚本时,就能清楚知道每条命令运行在哪个阶段、依赖哪些协议、受哪些边界约束。这是写出稳定、可移植脚本的前提。