第十六章 Shell 及常用 Shell 命令

2018-09-05  本文已影响0人  Maxwell_Li

作者:Maxwell Li
日期:2017/12/20
未经作者允许,禁止转载本文任何内容。如需转载请留言。


[TOC]

16.1 Shell 的编译与执行

ShellPkg 目录下包含了 Shell 的源代码,可以通过以下命令编译获得 shell.efi。

build -a IA32 -p ShellPkg\ShellPkg.dsc
build -a X64 -p ShellPkg\ShellPkg.dsc

将32位或64位的 shell.efi 复制到 ESP 分区的 efi\boot 目录下并重命名为 BootIA32.efi 或 BootX64.efi,启动 UEFI 系统时就会执行 BootIA32.efi 或 BootX64.efi 从而进入 Shell。

该方式启动 Shell 时通常不带参数(使用系统参数)。

Shell 启动参数:

shell.efi [ShellOpt-options] [options] [file-name [file-name-options]]

Shell 启动参数表

启动参数 作用
-nostartup 进入 Shell 时不执行脚本 startup.nsh
-noconsoleout Shell 标准输出不显示
-noconsolein Shell 无标准输入
-delay[:n] 指定等待 startup.nsh 启动的时间。默认是5秒,-delay:0 表示立即执行
-nointerrupt 不支持 <Ctrl+C> 的终止程序功能
-nomap 启动后不显示块设备的 map 信息
-noversion 启动后不显示 version
-startup 进入 Shell 是执行脚本 startup.nsh

当 ShellOpt-optitions 和 options 中均不包含 -startup 时,可以使用 file-name [file-name-options] 指定 Shell 启动后要执行的文件。如果启动参数中既有 -startup 又有 file-name [file-name-options],则 file-name [file-name-options] 被忽略。

16.2 Shell 服务

Shell 为程序开发者提供了两种使用 Shell 服务的方式:使用 Shell Protocol 和 Shell Parameters Protocol;使用 UEFIShellLib 提供的函数。

Shell Protocol 提供服务

EFI_SHELL_PROTOCOL 结构体如下:

typedef struct _EFI_SHELL_PROTOCOL {
  EFI_SHELL_EXECUTE                         Execute;                    // 执行 Shell 命令行命令
  EFI_SHELL_GET_ENV                         GetEnv;                     // 获得环境变量的值
  EFI_SHELL_SET_ENV                         SetEnv;                     // 设置环境变量的值
  EFI_SHELL_GET_ALIAS                       GetAlias;                   // 获得 Shell 命令的别名
  EFI_SHELL_SET_ALIAS                       SetAlias;                   // 设置 Shell 命令的别名
  EFI_SHELL_GET_HELP_TEXT                   GetHelpText;                // 获得 Shell 命令的帮助信息
  EFI_SHELL_GET_DEVICE_PATH_FROM_MAP        GetDevicePathFromMap;       // 从 Map 名获得 DevicePath
  EFI_SHELL_GET_MAP_FROM_DEVICE_PATH        GetMapFromDevicePath;       // 从 DevicePath 获得 Map 名
  EFI_SHELL_GET_DEVICE_PATH_FROM_FILE_PATH  GetDevicePathFromFilePath;
  EFI_SHELL_GET_FILE_PATH_FROM_DEVICE_PATH  GetFilePathFromDevicePath;
  EFI_SHELL_SET_MAP                         SetMap;                     // 设置设备的 Map 名
  EFI_SHELL_GET_CUR_DIR                     GetCurDir;
  EFI_SHELL_SET_CUR_DIR                     SetCurDir;
  EFI_SHELL_OPEN_FILE_LIST                  OpenFileList;
  EFI_SHELL_FREE_FILE_LIST                  FreeFileList;
  EFI_SHELL_REMOVE_DUP_IN_FILE_LIST         RemoveDupInFileList;
  EFI_SHELL_BATCH_IS_ACTIVE                 BatchIsActive;              // 是否正在执行脚本
  EFI_SHELL_IS_ROOT_SHELL                   IsRootShell;                // 是否为 Root
  EFI_SHELL_ENABLE_PAGE_BREAK               EnablePageBreak;            // 启动分屏显示模式
  EFI_SHELL_DISABLE_PAGE_BREAK              DisablePageBreak;           // 禁止分屏显示模式
  EFI_SHELL_GET_PAGE_BREAK                  GetPageBreak;               // 获取当前分屏显示模式状态
  EFI_SHELL_GET_DEVICE_NAME                 GetDeviceName;              // 获取设备的名字
  EFI_SHELL_GET_FILE_INFO                   GetFileInfo;
  EFI_SHELL_SET_FILE_INFO                   SetFileInfo;
  EFI_SHELL_OPEN_FILE_BY_NAME               OpenFileByName;
  EFI_SHELL_CLOSE_FILE                      CloseFile;
  EFI_SHELL_CREATE_FILE                     CreateFile;
  EFI_SHELL_READ_FILE                       ReadFile;
  EFI_SHELL_WRITE_FILE                      WriteFile;
  EFI_SHELL_DELETE_FILE                     DeleteFile;
  EFI_SHELL_DELETE_FILE_BY_NAME             DeleteFileByName;
  EFI_SHELL_GET_FILE_POSITION               GetFilePosition;
  EFI_SHELL_SET_FILE_POSITION               SetFilePosition;
  EFI_SHELL_FLUSH_FILE                      FlushFile;
  EFI_SHELL_FIND_FILES                      FindFiles;
  EFI_SHELL_FIND_FILES_IN_DIR               FindFilesInDir;
  EFI_SHELL_GET_FILE_SIZE                   GetFileSize;
  EFI_SHELL_OPEN_ROOT                       OpenRoot;                   // 打开设备的根目录
  EFI_SHELL_OPEN_ROOT_BY_HANDLE             OpenRootByHandle;           // 打开 Handle 指定的设备根目录
  EFI_EVENT                                 ExecutionBreak;             // 用户按下“Ctrl+C”时触发该事件
  UINT32                                    MajorVersion;
  UINT32                                    MinorVersion;
  // Added for Shell 2.1
  EFI_SHELL_REGISTER_GUID_NAME              RegisterGuidName;
  EFI_SHELL_GET_GUID_NAME                   GetGuidName;
  EFI_SHELL_GET_GUID_FROM_NAME              GetGuidFromName;
  EFI_SHELL_GET_ENV_EX                      GetEnvEx;
} EFI_SHELL_PROTOCOL;

EFI_SHELL_PROTOCOL 的 Execute 服务函数原型如下:

typedef EFI_STATUS (EFIAPI *EFI_SHELL_EXECUTE) (
  IN EFI_HANDLE   *ParentImageHandle,      // 执行 Execute 函数的 ImageHandle
  IN CHAR16       *CommandLine OPTIONAL,   // Shell 命令行命令
  IN CHAR16       **Environment OPTIONAL,  // 环境变量
  OUT EFI_STATUS  *StatusCode OPTIONAL     // Shell 命令返回值
  );

该函数会启动一个子 Shell,并在子 Shell 中执行指定命令,命令的退出码将作为 Execute 函数的返回值。

基本上对于所有 Shell Protocol 中的函数,在 UefiShellLib 中都有与之对应的函数。例如 Shell Protocol 中的 Execute 函数, UefiShellLib 提供了对应的 ShellExecute 函数,函数原型如下:

EFI_STATUS EFIAPI ShellExecute (
  IN EFI_HANDLE   *ParentHandle,
  IN CHAR16       *CommandLine OPTIONAL,
  IN BOOLEAN      Output OPTIONAL,
  IN CHAR16       **EnvironmentVariables OPTIONAL,
  OUT EFI_STATUS  *Status OPTIONAL
  )

Output 为 TURE,表示现实调试信息。

UefiShellLib 的初始化

gEfiShellProtocol 是 EFI_SHELL_PROTOCOL* 类型的变量,由 UefiShellLib 提供。Library 可以提供构造函数,构造函数在 ENTRY_POINT 之前执行。在 UefiSHellLib 的工程文件中定义了 CONSTRUCTOR 和 DESTRUCTOR。引用 UeifShellLib 时,“Status=ShellLibConstructor(ImageHandle, SystemTable);”会被添加到 ProcessLibraryConstructorList 函数中,从而在调用 ShellAppMain 之前执行。

16.3 Shell 脚本

在 UEFI Shell 中可以执行 Shell 脚本,Shell 脚本是以 .nsh 为扩展名的文件,在脚本中可以执行 Shell 命令和外部命令,也可以使用内置的流程控制命令 for、endfor、goto、if、else、endif、exit。

if 语句比较运算符

运算符 含义
gt 大于
lt 小于
ne 等于
ugt 无符号值大于
ult 无符号值小于
eq 相等
ge 大于或等于
le 小于或等于
= = 相等
uge 无符号值大于或等于
ule 无符号值小于或等于

if语句布尔函数说明

布尔函数 当返回值为 TRUE 时 当返回值为 FALSE 时
isInt(para) para 是数字 para 不是数字
Exists file file 存在 file 不存在
Avaliable file file 存在于 path 指定的目录或当前目录 均不存在
Profile para para 匹配 profile 中某项 para 不匹配 profile 中任一项

16.4 Shell 内置命令

16.4.1 调试设备的相关命令

deme 命令用于查看内存或设备内存。address、size 都是十六进制数,-MMIO 指定地址为设备内存。

dmem [-b] [address] [size] [-MMIO]

mm 命令用于查看或修改 MEM(系统内存)、MMIO(设备内存)、IO(寄存器)、PCI(PCI 配置空间)、PCIE(PCIE 配置空间)。

mm address [value] [-w 1|2|4|8] [-MEM| -MMIO | -IO | -PCI | -PCIE] [-n]

address 为地址;value 为要写入的值;-w 后跟访问宽度;-n 表示非交互模式,若不指定 -n,则该命令会进入交互模式。

pci 命令显示 PCI 设备列表或显示 PCI 配置空间。

pci [Bus Dev [Func] [-s Seg] [-i]]

不带参数的 pci 命令用于列出所有 PCI 设备。带参数时,总线号(Bus)\设备号(Dev)\功能号(Func)用于指定 PCI 设备。-s Seg 用于指定 Segment。Func 和 Seg 默认值为0。

16.4.2 驱动相关命令

dh 命令用于列出系统中的所有设备信息,或某个设备的相关信息。

dh [-l<lang>] [handle | -p <prot_id>] [-d] [-v]

device 命令用于显示所有被驱动管理的设备。

drivers 命令用于列出系统中的 driver。

Connect 命令用于加载驱动到设备上并启动加载的驱动。

Connect [[DeviceHandle] [DriverHandle] | [-c] | [-r]]

load 命令用于加载驱动。

load [-nc] file [file2 ...]

-nc 表示只加载驱动到内存,不进行 connect。不带 -nc 选项时,load 加载驱动后会调用 connect 将该驱动加载到匹配的设备上。

unload 命令用于将驱动从内存中清楚。

unload [-n] [-v] Handle

-n 表示在执行 unload 过程中跳过所有提示信息,不需要用户确认。

16.4.3 网络相关命令

ifconfig 命令用于配置网络设备。

ifconfig [-?] [-c [Name]] [-l [Name]] [-s <Name> dhcp | <static <IP><MASK><Geteway>> [permanent]]

ping命令用于 ping 目标机器。

ping [ -n number] [-l size] TargetIP
16-1.png
上一篇 下一篇

猜你喜欢

热点阅读