美文网首页
第十六章 Shell 及常用 Shell 命令

第十六章 Shell 及常用 Shell 命令

作者: Maxwell_Li | 来源:发表于2018-09-05 11:21 被阅读0次

作者: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 时通常不带参数(使用系统参数)。

  • UEFI 进入 Shell 时,会将 Shell Protocol 安装到 Shell 的 ImageHandle 上。然后 UEFI 系统中的应用才可以使用 Shell Protocol 服务。
  • 进入 UEFI 后, Shell 首先检查 efi\Boot\ 目录下是否有 startup.nsh 脚本。
    • 如果有,则执行该脚本,然后进入 Shell 命令行等待用户输入;
    • 如果没有,则直接进入命令行等待用户输入。
  • 执行外部命令时:
    1. Shell 先用 Load Image Protocol 将可执行文件载入内存生成 Image;
    2. 在该 Image 上安装 Shell Parameter Protocol;
    3. 调用这个 Image 的入口函数从而执行该外部命令。

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 函数的返回值。

  • 参数 ParentImageHandle 是执行 Execute 命令的 Image 的 ImageHandle,通常是 gImageHandle;
  • 参数 CommandLine 是启动 Shell 时的命令行参数;
  • 参数 Environment 是字符串数组,数组以 NULL 为最后一项,其余每一项表示一个环境变量,格式为 Var=Value;
    • 如果 Environment 为 NULL,当前的环境变量会传递到子 Shell 中,从子 Shell 返回时,对环境变量的更改被保存。
    • 如果 Environment 不为 NULL,子 Shell 使用指定的环境变量,从子 Shell 返回时,对环境变量的更改被丢弃。
  • 参数 StatusCode 是 Shell 命令的返回值,该返回值通过 exit 命令设置。

基本上对于所有 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]
  • -l<lang> 表使用指定的语言显示。
  • handle 是指 UEFI Handle 在系统中的编号。
  • -p <prot_id> 列出所有安装了 protocol prot_id 的设备信息。
  • -d 用于列出驱动相关信息。
  • -v 用于输出 verbose 信息。

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

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

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

Connect [[DeviceHandle] [DriverHandle] | [-c] | [-r]]
  • -c 用于连接控制台设备。
  • -r 用于递归扫描所有 handle,发现匹配的设备和驱动就加进来,没有 -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]]
  • Name是网络适配器的名字。
  • -c 用于清除网络适配器的配置。
  • -l 用于列出网络适配器的配置。
  • -s 用于设备网络适配器的IP地址。

ping命令用于 ping 目标机器。

ping [ -n number] [-l size] TargetIP
  • -l size 用于发送 size 字节的数据。
  • -n number 表示发送数据的次数。
16-1.png

相关文章

  • 第十六章 Shell 及常用 Shell 命令

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

  • Shell脚本

    shell脚本学习笔记 shell命令的组合运用 常用命令组合

  • adb shell uiautomator 命令

    adb shell uiautomator 命令 Tags: adb_shell 常用到的命令: uiautoma...

  • HBASE SHELL常用命令

    HBASE SHELL常用命令 标签: HBase Shell 1. 进入hbase shell console ...

  • adb命令

    常用非Shell命令:1、adb shell dumpsys activity top2、adb shell du...

  • Shell参考资料

    shell 目录 Shell简介 Shell常用命令 Shell里面的括号 Shell里面的单引号和双引号 She...

  • Shell命令汇总

    1、一般常用命令 (1)Shell 常用命令总结 (2)Shell的18条常用命令整理 2、文件操作常用命令 (1...

  • Android NDK开发之旅31--NDK-Linux入门之基

    常用的Linux命令 shell命令有多种,Ubuntu默认使用 B shell。 命令行相关的命令 命令自动补全...

  • 查看当前shell

    查看当前可使用的shell 最常用的查看shell的命令,但不能实时反映当前shell 环境变量中shell的匹配...

  • python 调用linux shell

    常用的几种shell命令调用方式:

网友评论

      本文标题:第十六章 Shell 及常用 Shell 命令

      本文链接:https://www.haomeiwen.com/subject/oayrwftx.html