3. 文件系统与设备管理:设备路径概念、映射设备(map)、文件系统导航(cd, ls, dir)
UEFI Shell 的核心能力之一是对硬件设备与文件系统的统一管理。与操作系统不同,UEFI 环境没有盘符(C:、D:),而是通过 设备路径(Device Path) 和 映射(Mapping) 机制来定位存储设备与文件系统。本章将深入讲解设备路径的结构、map 命令的使用,以及如何在 Shell 中高效导航文件系统。
3.1 设备路径(Device Path)概念
设备路径是 UEFI 规范定义的一种标准化的、与总线无关的硬件寻址方式。每个物理或逻辑设备在固件层面都有一个唯一的设备路径。它由一系列路径节点(Path Node)组成,每个节点描述设备在总线拓扑中的位置。
关键理解: 设备路径是 UEFI 的“硬件身份证”。无论是硬盘、USB 设备、光驱还是网络适配器,都通过设备路径被唯一标识。Shell 脚本中常通过设备路径来精确指定操作目标,避免因映射别名变化导致的错误。
3.1.1 设备路径的典型结构
一个完整的设备路径通常包含以下节点类型(按顺序组合):
| 节点类型 | 描述 | 示例 |
|---|---|---|
| ACPI 节点 | 描述系统总线(如 PCI 根桥) | ACPI(PNP0A03,0) |
| PCI 节点 | 描述 PCI 设备(功能号、设备号) | PCI(0x1F,0x2) |
| SATA 节点 | 描述 SATA 端口与通道 | SATA(0x0,0x0,0x0) |
| 硬盘介质节点 | 描述硬盘分区(MBR/GPT) | HD(1,MBR,0x00000000,0x3F,0x3E8000) |
| 文件路径节点 | 描述文件系统内的路径 | \EFI\BOOT\BOOTX64.EFI |
实战提示: 使用
devtree 命令可以查看完整的设备树结构,展示所有设备的层级关系。这是理解设备路径最直观的方式。
3.2 映射设备(map)
设备路径虽然精确,但冗长且难以记忆。UEFI Shell 提供了 映射(Mapping) 机制,为设备路径分配简短易记的别名(Alias)。map 命令是管理这些映射的核心工具。
3.2.1 map 命令常用用法
| 命令 | 功能 | 示例输出/说明 |
|---|---|---|
map |
列出所有当前映射 | 显示所有块设备、文件系统映射 |
map -r |
重新扫描所有总线并刷新映射 | 热插拔设备后使用 |
map fs0: |
显示 fs0: 对应的完整设备路径 | fs0: ... HD(1,GPT,...) |
map -c |
清除所有用户定义的映射 | 恢复默认映射状态 |
map -u |
仅显示用户定义的映射 | 过滤系统默认映射 |
3.2.2 映射的命名规则
UEFI Shell 自动为设备分配以下类型的映射名称:
- 文件系统映射:
fs0:、fs1:、fs2:… 对应可识别的文件系统分区。 - 块设备映射:
blk0:、blk1:… 对应未格式化或无法识别的块设备。 - 用户定义映射: 可通过
map 别名 设备路径创建自定义别名,如map MYDISK fs0:。
常见陷阱: 映射编号(如 fs0:)在每次启动或重新扫描后可能变化。如果脚本依赖固定映射编号,建议在脚本开头使用
map 命令动态获取目标设备的当前映射,或使用用户定义映射固定别名。
3.2.3 创建持久化映射
用户定义的映射仅在当前 Shell 会话中有效。若需持久化,可将 map 命令写入启动脚本(如 startup.nsh)或使用 set 命令配合环境变量实现。
# 创建用户定义映射
map MYHD fs0:
# 验证映射
map MYHD
# 切换到自定义映射
MYHD:
cd \EFI\BOOT
3.3 文件系统导航(cd, ls, dir)
一旦通过映射进入文件系统,就可以使用熟悉的导航命令操作目录和文件。UEFI Shell 的导航命令与 DOS/Linux 风格类似,但有一些关键差异。
3.3.1 核心导航命令对比
| 命令 | 功能 | 示例 | 注意事项 |
|---|---|---|---|
cd |
切换当前目录 | cd \EFI\BOOT |
使用反斜杠 \ 作为路径分隔符 |
ls |
列出目录内容(详细格式) | ls -l |
-l 显示文件大小和属性 |
dir |
列出目录内容(简洁格式) | dir *.efi |
支持通配符 * 和 ? |
3.3.2 路径表示法
- 绝对路径: 以
\开头,从当前文件系统根目录开始。例如:\EFI\BOOT\BOOTX64.EFI。 - 相对路径: 不以
\开头,从当前工作目录开始。例如:..\..\test.nsh。 - 当前目录:
.表示当前目录;..表示父目录。 - 切换文件系统: 直接输入映射名称加冒号,如
fs1:,即可切换到另一个文件系统。
3.3.3 实战导航示例
# 查看当前所有映射
Shell> map
# 切换到第一个文件系统
Shell> fs0:
fs0:\>
# 查看根目录内容
fs0:\> ls -l
Directory of: fs0:\
01/01/2020 12:00 <DIR> 1024 EFI
01/01/2020 12:00 <DIR> 1024 TOOLS
01/01/2020 12:00 256000 startup.nsh
# 进入 EFI 目录
fs0:\> cd EFI\BOOT
# 列出所有 .efi 文件
fs0:\EFI\BOOT> dir *.efi
Directory of: fs0:\EFI\BOOT
01/01/2020 12:00 983040 BOOTX64.EFI
01/01/2020 12:00 524288 SHELLX64.EFI
# 返回根目录
fs0:\EFI\BOOT> cd \
fs0:\>
效率技巧: 使用
ls -l 可以查看文件大小和属性,对判断文件完整性很有帮助。使用 ls -s 可以按大小排序输出,便于快速定位大文件。
3.4 综合实战:设备发现与文件系统遍历
以下脚本演示了如何结合 map、cd 和 ls 编写一个自动发现并遍历所有文件系统的工具:
# 脚本:list_all_fs.nsh
# 功能:遍历所有文件系统,列出根目录内容
echo "=== 开始扫描所有文件系统 ==="
# 重新扫描总线,确保设备列表最新
map -r
# 获取所有 fs 映射并遍历
for %fs in fs0 fs1 fs2 fs3 fs4 fs5
do
# 检查映射是否存在
map %fs: > nul 2>&1
if %?% == 0 then
echo "----------------------------------------"
echo "文件系统: %fs:"
echo "设备路径: "
map %fs:
echo "根目录内容:"
%fs:
cd \
ls -l
echo ""
endif
endfor
echo "=== 扫描完成 ==="
脚本要点:
map -r确保热插拔设备被识别。map %fs: > nul 2>&1检查映射是否存在,避免访问不存在的设备导致脚本中断。%?%是 UEFI Shell 的环境变量,保存上一条命令的返回值(0 表示成功)。- 遍历范围可根据实际环境调整(如
fs0到fs9)。
3.5 本章小结
- 设备路径 是 UEFI 硬件寻址的基础,由多个路径节点组成,精确描述设备在总线拓扑中的位置。
- map 命令 将冗长的设备路径映射为简短别名(如
fs0:),是 Shell 脚本与硬件交互的桥梁。 - 文件系统导航 使用
cd、ls、dir命令,路径分隔符为反斜杠\,支持绝对路径和相对路径。 - 编写健壮的脚本时,应动态获取映射信息,避免硬编码映射编号。