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,如下圖所示。
在這裏插入圖片描述
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 <Uefi.h>
#include <Library/UefiLib.h>
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"。
在這裏插入圖片描述現在就可編譯EmulatorPkg工程包了,在cmd命令行裏面執行build命令或者通過visual stdio編譯EmulatorPkg工程。編譯完成後除了生成默認的WinHost.exe(虛擬機程序)和FV_RECOVERY.fd(UEFI固件)之外,也生成了我們添加的應用模塊TestoneApp.efi,如下圖所示。
在這裏插入圖片描述
通過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模塊文件位置,然後直接執行該模塊文件即可,如下圖所示。
在這裏插入圖片描述

四、調試應用

同樣通過visual studio軟件打開 $(edk2-base)\EmulatorPkg\Win\VS2017\Win.sln 工程文件,然後在visual studio工程中打開 $(edk2-base)\MdeModulePkg\Application\TestoneApp\TestoneApp.c 文件,在"Print(L"Hello, world!\r\n"); " 這一行代碼打上斷點,以調試模式編譯運行工程,即可調試該應用了。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章