2.UEFI-edk2 编写第一个应用

上一章把UEFI的编译开发和模拟器环境都搭建好了,这里开始写第一个应用。写之前先简单介绍下UEFI-edk2的源码目录结构,源码目录下主要有以下这些子目录:

目录名 说明
BaseTools 包含代码编译所需的二进制编译工具集和编译环境配置文件。
MdePkg 包含各个平台通用的基本的底层库函数、协议和工业标准。
MdeModulePkg 包含一系列各平台通用的模块,其中包括MdePkg中公共库的应用模块示例。
Conf 保存编译环境信息、编译目标路径以及编译器参数,工具将在该路径下产生3个配置文件。
EdkShellPkg、ShellPkg 提供一个平台通用的UEFIShell应用程序开发环境。
EdkFatBinPkg 包含针对不同CPU架构的原始FAT驱动。
EmulatorPkg 一个在Windows操作系统下可加载32/64位模拟器,提供UEFI运行环境的平台。
ArmPkg、ArmPlatformPkg 针对ARM平台的实现,与具体平台硬件相关。
NetWorkPkg、UefiCpuPkg 网络、CPU驱动参考实现。
DuetPkg 提供基于传统BIOS运行环境的支持库。
OptionRomPkg 提供针对不同CPU架构编译PCI兼容映像的示例。

每个以Pkg结尾的目录都是一个工程包,编译时可以通过"build -p *Pkg*Pkg.dsc"命令编译对应的工程包,比如编译模拟器的工程包就可以用"build -p EmulatorPkg\Emulator\Pkg.dsc"命令。
每个工程包可以通过更改配置 *Pkg*Pkg.inf 文件来引用其他工程包中的应用和库以及驱动模块,部分可生成UEFI启动固件的工程包可以通过更改配置 *Pkg*Pkg.fdf 文件来把自身或者其他工程包中的应用/库/驱动模块添加到目标UEFI固件中。

一、应用代码编写

写应用模块的话首先要新建一个模块目录,如前言的表格所述,我们这里要创建的是一个简单的测试程序,并不针对特定的平台,新建的应用模块放在MdeModulePkg\Application目录下还是比较合适一些。这个应用模块暂取名为TestoneApp,同时在这个目录下新建两个文件TestoneApp.c和TestoneApp.inf,如下图所示。
2.UEFI-edk2 编写第一个应用_第1张图片
TestoneApp.inf是模块的工程描述文件,有点类似Linux系统下的Makefile。TestoneApp.inf文件的内容如下:

[Defines]  
INF_VERSION                    = 0x00010005  
BASE_NAME                      = TestoneApp  
FILE_GUID                      = 12345678-ABCD-EF01-2345-123456789012  
MODULE_TYPE                    = UEFI_APPLICATION  
VERSION_STRING                 = 1.0  
ENTRY_POINT                    = UefiMain

[Sources]  
TestoneApp.c

[Packages]  
MdePkg/MdePkg.dec

[LibraryClasses]  
UefiApplicationEntryPoint  
UefiLib

TestoneApp.inf文件中有着一些定义块,各个定义块功能如下。

[Defines] : 用于定义模块的属性和一些自定义变量,BASE_NAME配置的是改应用编译后生成的EFI模块文件名,MODULE_TYPE指定了这是一个UEFI应用模块,ENTRY_POINT制定了该模块的入口函数名,FILE_GUID是模块的唯一编码,这个可以随便写,只要不与其他模块一样就行。
[Sources] : 
[Packages] : 列出本模块引用到的包的包声明文件。
[LibraryClasses] : 需要列出本模块使用到的库。

接着看TestoneApp.c源码文件,源码功能很简单,就是打印一个"Hello, world!"的字符串。注意字符串前面需要加L字母,表面该字符串是一Unicode的字符串。

#include 
#include 
EFI_STATUS EFIAPI UefiMain(    
	IN EFI_HANDLE        ImageHandle,    
	IN EFI_SYSTEM_TABLE  *SystemTable){    
	
	Print(L"Hello, world!\r\n");    
	return EFI_SUCCESS;
}

二、编译自定义应用

编译测试应用模块的话,把模块的配置文件路径添加到EmulatorPkg包的工程配置文件即可。打开EmulatorPkg\EmulatorPkg.dsc文件,在其[Components]块下面添加"MdeModulePkg/Application/TestoneApp/TestoneApp.inf"。
2.UEFI-edk2 编写第一个应用_第2张图片现在就可编译EmulatorPkg工程包了,在cmd命令行里面执行build命令或者通过visual stdio编译EmulatorPkg工程。编译完成后除了生成默认的WinHost.exe(虚拟机程序)和FV_RECOVERY.fd(UEFI固件)之外,也生成了我们添加的应用模块TestoneApp.efi,如下图所示。
2.UEFI-edk2 编写第一个应用_第3张图片
通过visual studio编译EmulatorPkg工程的时候,这里会遇到报"‘gbk’ codec can’t encode character ‘\u2cbf’ in position"错误的情况,因为TestoneApp.c文件中L"Hello, world!"字符串是Unicode编码,gdk解析不了,这个错误可以通过更改源码文件或者配置系统编码解决,我建议是将直接windows系统的默认编码改成UTF-8,这样方便代码在windows和Linux平台下迁移。

三、运行应用

启动模拟器,等到固件运行到UEFI shell后,通过ls命令可以查看生成的efi模块文件位置,然后直接执行该模块文件即可,如下图所示。
2.UEFI-edk2 编写第一个应用_第4张图片

四、调试应用

同样通过visual studio软件打开 $(edk2-base)\EmulatorPkg\Win\VS2017\Win.sln 工程文件,然后在visual studio工程中打开 $(edk2-base)\MdeModulePkg\Application\TestoneApp\TestoneApp.c 文件,在"Print(L"Hello, world!\r\n"); " 这一行代码打上断点,以调试模式编译运行工程,即可调试该应用了。
2.UEFI-edk2 编写第一个应用_第5张图片

你可能感兴趣的:(bios,&,driver)