How to Write a simple UEFI EDKII Application:如何编写一个UEFI简单的应用程序[5]
2015-07 北京海淀区 张俊浩
本篇博文《How to Write a simple UEFI EDK II Application:如何编写一个UEFI简单的应用程序[5]》是基于之前的UEFI博文在之前的EDKII开发环境搭建、配置/编译EDKII工程、运行EDKII模拟器的基础上,也即在熟悉EDKII的编译流程后,学习在EDKII环境下编程。
参看TianoCore官网(http://www.tianocore.org官网上Getting Started for Developers->Further Help-> Getting Started Writing Simple Application)和《UEFI原理与编程》第三章UEFI工程模块文件。本篇博文框架:
5. How to Write a simple UEFI EDKII Application:Getting Started Writing Simple Application (写一个简单UEFI应用程序例程)
->5.0 EDKII Project Introduction
->5.1 Setup build shell environment:Run the edksetup
->5.2 Modify Conf Files:Edit the file conf/target.txt
->5.3 Create a project:MyHelloWorld
->5.3.1 Create a new directory.
->5.3.2 Create MyHelloWorld.c file in the project directory
->5.3.3 Create MyHelloWorld.inf file in the project directory
->5.4 Build your UEFI Application
->5.5 Run your UEFI Application
->5.5.1 Run Nt32 and UEFI Application
->5.5.2 Run Emulator and UEFI Application
5.0 EDKII Project Introduction
在EDKII根目录下,有很多*Pkg命名的文件夹,每一个这样的文件夹成为一个包。当然,这样说很不准确,准确的说“包”是一组平台及平台描述文件(.dsc文件,EDKII Platform Description File)、包声明文件(.dec文件,EDKII Declaration File)组成的集合。
在Linux编程下,除了编写源代码之外,还要编写Makefile文件。在Windows下VS(Visual Studio)通常要建立源文件和工程文件。在EDKII环境下,EDKII工程模块由源文件(C或其源他文件)和工程文件(INF文件)。INF文件与VS的工程文件Linux的Makefile文件功能相同,用于自动化编译源代码。包相当于VS中的项目,des文件相当于VS中的sln文件;模块相当于VS项目中的工程,INF文件相当于VS工程中的proj文件。
一个简单的UEFI标准应用程序工程模块包含一个C程序源文件以及一个工程文件。接下来以简单UEFI EDKII应用程序MyHelloWorld 为例学习UEFI标准应用程序工程的框架和编写流程。
5.1 Setup build shell environment:Run the edksetup
Run edksetup script from the command line prompt at the Work Space directory
Windows Comand Prompt:
C:\edk2> edksetup.bat --nt32
Linux like:
bash$ . edksetup.sh BaseTools
5.2 Modify Conf Files
本步骤可以参考之前博文中配置EDKII项目流程
5.2.1 Set Build Target Information:配置target.txt文件
配置前模块配置为相应平台的模拟器。
Windows:
ACTIVE_PLATFORM should look like this in Conf\target.txt:
ACTIVE_PLATFORM = Nt32Pkg/Nt32Pkg.dsc
Conf\target.txt其他配置采用之前的默认配置。
Linux:
ACTIVE_PLATFORM should look like this in Conf\target.txt:
ACTIVE_PLATFORM = EmulatorPkg/EmulatorPkg.dsc
Conf\target.txt其他配置采用之前的默认配置。
5.2.2 Check/Modify tools_def Information:检查tools_def.txt确保编译器路径正确
之前的博客中环境EDKII项目编译器路径已经做了检查。
5.3 Create a project
5.3.1 Create a new directory.(创建工作目录)
Can be a directory anywhere within the Work Space Directory
本工程工作目录路径设置为:
Windows:
D:\edk2> md MyHelloWorld
Linux:
linux@ubuntu:~$ mkdir ~/src/edk2/MyHelloWorld
5.3.2 Create MyHelloWorld.c file in the project directory
参看下一篇博文《UEFI简单的应用程序模块MyHelloWorld:C源文件//INF工程文件源码/简析[6]》。
5.3.3 Create MyHelloWorld.inf file in the project directory
参看下一篇博文《UEFI简单的应用程序模块MyHelloWorld:C源文件//INF工程文件源码/简析[6]》。
5.4 Build your UEFI Application
源文件和工程文件都已经编写完成,下面编译和运行这个标准应用程序工程模块。需要将MyHelloWorld.inf添加到Nt32Pkg.dsc或EmulatorPkg.dsc的[Components]部分,如下
[Components]
MyHelloWorld/MyHelloWorld.inf
[注:路径相对于EDKII根目录]
具体模拟器配置编译流程参看上一篇博文《Build/Launch EDKII emulator in Windows and Linux:编译/运行Windows和Linux环境下EDKII模拟器[4]》。
Windows下Nt32编译采用:
D:\edk2> build
如果模拟器Nt32之前编译过,可以只编译MyHelloWorld模块:
D:\edk2> build -m MyHelloWorld\MyHelloWorld.inf
Linux下Emulator编译采用EmulatorPkg/build.sh脚本的方式:
linux@ubuntu:~/src/edk2$ ./EmulatorPkg/build.sh -a IA32
这样生成的MyHelloWorld.efi会存放在edk2/Build/Emulator32/DEBUG_GCC46/IA32路径下。
通过“./EmulatorPkg/build.sh -a IA32 run”是将edk2/Build/Emulator32/DEBUG_GCC46/IA32/映射为文件系统fsnt0。
如果模拟器Emulator之前编译过,可以只编译MyHelloWorld模块:
linux@ubuntu:~/src/edk2$ ./EmulatorPkg/build.sh -m MyHelloWorld/MyHelloWorld.inf
[注:通过 ./EmulatorPkg/build.sh -a IA32编译的模块最终生成的.efi放在:
edk2/Build/Emulator32/DEBUG_GCC46/IA32路径下;
通过build -a IA32编译的模块最终生成的.efi放在:
edk2/Build/Emulator/DEBUG_GCC46/IA32。两者目录不同]
5.5 Run your UEFI Application
5.5.1 Run Nt32 and UEFI Application
D:\edk2> build run
或者在build命令行指定平台:[不过-a/-p平台架构和目标平台我们在target.txt中配置,作为build默认选项参数]
D:\edk2> build -a IA32 -p Nt32Pkg/Nt32Pkg.dsc run
或者是执行edk2\Build\NT32IA32\DEBUG_VS2013x86\IA32\SecMain.exe可执行文件;
模拟器最终会进入UEFI Shell,EDKII默认将目录:
edk2\Build\NT32IA32\DEBUG_VS2013x86\IA32\映射为文件系统FS0,在shell中执行命令(FS0:/fs0:,大小写均可)
Shell> fs0:
Shell将会打开FS0分区并将当前目录切换到FS0分区的根目录,可执行我们编写的UEFI应用程序模块MyHelloWorld.efi,向屏幕终端打印输出字符串“Hello World from Junhao by EDKII!”。
FS0:\> MyHelloWorld.efi
5.5.2 Run Emulator and UEFI Application
通过运行EmulatorPkg下的脚本
$ EmulatorPkg/build.sh -a IA32 run
模拟器最终会进入UEFI Shell,EDKII默认将目录:
edk2/Build/Emulator32/DEBUG_GCC46/IA32/映射为文件系统fsnt0,在shell中执行命令(FSNT0:/fsnt0:,大小写均可)
Shell> fsnt0:
Shell将会打开
fsnt0分区并将当前目录切换到
fsnt0分区的根目录,可执行我们编写的
UEFI应用程序模块
MyHelloWorld
.efi,向屏幕终端打印输出字符串“Hello World from Junhao by EDKII!”。
fsnt0:\> MyHelloWorld.efi