BIOS/UEFI基础——写一个自己的shell命令
来源:互联网 发布:linux awk命令详解 编辑:程序博客网 时间:2024/06/06 15:15
本文在UDK2015的基础上,写一个shell命令,并在shell下运行。
一些说明
UEFI下的shell有两个版本,一个是shell ver 1的版本,对应EdkShellPkg;另一个是shell ver 2的版本,对应ShellPkg。
目前UDK2015中已经没有EdkShellPkg的源码了,需要另外下载。
所以本文以ShellPkg中的源代码为基础。
光一个shell没有办法直接运行,本文将shell依附在OVMF上,因此本文编译使用的是OvmfPkgX64.dsc。
使用OVMF的好处是可以通过qemu来运行,另外一个好处是,OvmfPkgX64.dsc已经包含了ShellPKg.dsc,因此不需要额外做什么操作。
关于OVMF的编译可以参考OVMF基础。
添加源代码
前面已经讲到,shell的源码位于ShellPkg目录下:
其中:
Application包含的是shell本身,以及一些简单的应用示例。这些应用——包括shell本身——都可以在shell下直接运行。
Include包含一些必须的头文件。
Library包含了shell所需的基本库和shell下可以执行的命令:
在shell ver 2中,shell命令都包含了库中。比如上面的UefiShellNetwork1CommandsLib,它内部就包含了ifconfig和ping两个命令。
在shell ver 2中,各个命令按照功能划分在不同的目录下。
本文就要按照上面的形式,来创建一个自己的Lib,并在其中实现命令。
创建OemLib
这里需要说明的是inf和uni文件:
inf用于编译,表示的是一个模块。
uni是一个字符串的文件,用于显示shell命令中的一些帮助命令或者错误信息。
之后需要将inf文件添加到ShellPkg.dsc中:
这样才能编译到OVMF中去。
具体的代码
#include "UefiShellOemCommandLib.h"CONST CHAR16 gShellOemFileName[] = L"ShellCommand";EFI_HANDLE gShellOemHiiHandle = NULL;/** Return the file name of the help text file if not using HII. @return The string pointer to the file name.**/CONST CHAR16*EFIAPIShellCommandGetManFileNameOem ( VOID ){ return gShellOemFileName;}/** Constructor for the Shell xxx Command library. Install the handlers for xxx UEFI Shell command. @param ImageHandle The image handle of the process. @param SystemTable The EFI System Table pointer. @retval EFI_SUCCESS The Shell command handlers were installed sucessfully. @retval EFI_UNSUPPORTED The Shell level required was not found.**/EFI_STATUSEFIAPIShellOemCommandLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ){ gShellOemHiiHandle = NULL; // // check our bit of the profiles mask // if ((PcdGet8 (PcdShellProfileMask) & BIT3) == 0) { return EFI_SUCCESS; } gShellOemHiiHandle = HiiAddPackages ( &gShellOemHiiGuid, gImageHandle,// gShellOemHiiGuid需要在ShellLibHiiGuid.h和ShellPkg.dec中定义,并声明在UefiShellOemCommandLib.inf UefiShellOemCommandLibStrings, NULL// UefiShellOemCommandLibStrings就对应到UefiShellOemCommandLib.uni ); if (gShellOemHiiHandle == NULL) { return EFI_DEVICE_ERROR; } // // Install our Shell command handler // ShellCommandRegisterCommandName ( L"helloworld", ShellCommandRunHelloWorld, ShellCommandGetManFileNameOem, 0, L"helloworld", TRUE , gShellOemHiiHandle, STRING_TOKEN (STR_GET_HELP_OEM)// STR_GET_HELP_OEM在UefiShellOemCommandLib.uni中定义 ); return EFI_SUCCESS;}/** Destructor for the library. free any resources. @param ImageHandle The image handle of the process. @param SystemTable The EFI System Table pointer.**/EFI_STATUSEFIAPIShellOemCommandLibDestructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ){ if (gShellOemHiiHandle != NULL) { HiiRemovePackages (gShellOemHiiHandle); } return EFI_SUCCESS;}其它文件的代码略。
运行结果
运行qemu,在打开qemu窗口后按键,会进行UEFI的Front Page。
选择Boot Manager,进入shell,运行helloworld的结果:
以上的例子可以在https://code.csdn.net/jiangwei0512/bios_git.git这个git仓库中找到,具体的代码可能有些许差异。
- BIOS/UEFI基础——写一个自己的shell命令
- BIOS/UEFI基础——UEFI网络框架之概述
- BIOS/UEFI基础——UEFI网络框架之UNDI
- BIOS/UEFI基础——UEFI网络框架之SNP
- BIOS/UEFI基础——UEFI网络框架之MNP
- BIOS/UEFI基础——UEFI网络框架之ARP
- BIOS/UEFI基础——UEFI网络框架之TCP4
- BIOS/UEFI基础——UEFI网络框架之MNP2
- BIOS/UEFI基础——UEFI网络框架之IP4
- BIOS/UEFI基础——基础知识
- BIOS/UEFI基础——EDK
- BIOS/UEFI基础——EFI_HANDLE
- BIOS/UEFI基础——变量
- BIOS/UEFI基础——定时器
- BIOS/UEFI基础——DEBUG
- BIOS/UEFI基础——Device Path
- BIOS/UEFI基础——x86架构中断基础介绍
- BIOS/UEFI基础——第一条指令
- RxAndroid从零开始学之二(Observable的其它创建与订阅形式)
- myeclipse+mysql(Navicat)通过JDBC连接 详解+成功
- vs2012出现的几个常见的编译错误
- 递归实现数的全排列
- Cascade Adaboost样本更新
- BIOS/UEFI基础——写一个自己的shell命令
- 通向架构师的道路(第十一天)之Axis2 Web Service(二)
- Android开发-Volley-解析Json使用方法-2-完整Demo-AndroidStudio
- jetty 部署配置
- 如何把硬盘文件导入虚拟机
- log4net
- C++编程入门系列之十一(重载函数与函数模板)
- Spring中Bean的生命周期
- js 事件对象