相关参考
- EDK II Module Writer’s Guide : 官方模块编写指导
 - EDK II Module Information (INF) File Specification : 官方INF文件说明
 - UEFI原理与编程_戴正华 第3章
 
参考文章下载地址:
链接: https://pan.baidu.com/s/1LjrydEzCACG3ohpx7mMKKg 提取码: 4i3j 
模块和包
EDK下的模块(Module)和包(Package)
包
在EDKII目录下,有很多  xxxxPkg文件,每一个这种文件,称为一个Package。
包 由  一组模块及平台描述文件(dsc)和 包声明文件(dec)组成的集合。
模块(重点)
可执行文件,即 efi文件,像Linux驱动一样 可动态加载到 UEFI内核中。
包括 : 源码文件 .c  **  和 元数据文件 .inf    组成 ,挂到dsc中编译生成 .efi文件**


inf工程描述文件说明
参考:
- EDK II Module Information (INF) File Specification : 官方INF文件说明
 - UEFI原理与编程_戴正华 第3.1.2
 
小技巧:使用时 find下,然后从别人那边拷贝一个改改用就好

这里提供一个通用的inf文件,根据自己需要修改
[Defines]INF_VERSION = 0x00010006 # INF支持标准版本, find下看别人是多少,直接写。 格式可以参考BASE_NAME = UefiMain # 目标文件名,编译后在build下搜索 "BASE_NAME.efi" 就是目标文件FILE_GUID = f12a2e88-9f0b-4ae0-bb7c-c6557175f10c # GUID, 使用 uuidgen 命令生成一个就好MODULE_TYPE = UEFI_APPLICATION # !!!根据UEFI模块类型,填写不同字段VERSION_STRING = 0.1ENTRY_POINT = UefiMain_test # 入口函数名, 比如 main[Sources]main.c # 源文件列表[Packages]MdePkg/MdePkg.dec # 本模块引用到所有包的包声明文件[LibraryClasses] # 本模块要链接的库模块UefiApplicationEntryPoint # 库名称
当然,还有 Protocols, BuildOptions 模块,这里就不列举了
UEFI下应用开发
源码
(base) baiy@inno-MS-7B89:test01$ cat main.c#include <Uefi.h>EFI_STATUS EFIAPI testUefiMain (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){SystemTable->ConOut->OutputString(SystemTable->ConOut, L"HelloWorld\n");return EFI_SUCCESS;}
配置inf文件
inf文件相当于Linux下的Makefile
(base) baiy@inno-MS-7B89:test01$ cat main.inf[Defines]INF_VERSION = 0x00010006BASE_NAME = UefiMainFILE_GUID = f12a2e88-9f0b-4ae0-bb7c-c6557175f10cMODULE_TYPE = UEFI_APPLICATIONVERSION_STRING = 0.1ENTRY_POINT = testUefiMain[Sources]main.c[Packages]MdePkg/MdePkg.decOptionRomPkg/OptionRomPkg.dec[LibraryClasses]UefiApplicationEntryPoint
拷贝和执行
mount 将自己的app.disk 挂到目录上,然后将目标文件拷贝进去,运行时直接运行即可(驱动 需要 load xxx.efi, 应用直接运行就好)
root@inno-MS-7B89:edk2# find ./ -name "UefiMain.efi"./Build/OvmfX64/DEBUG_GCC5/X64/UefiMain.efi./Build/OvmfX64/DEBUG_GCC5/X64/test/stdapp_test/test01/main/DEBUG/UefiMain.efi./Build/OvmfX64/DEBUG_GCC5/X64/test/stdapp_test/test01/main/OUTPUT/UefiMain.efi

UEFI应用程序的加载
UEFI应用程序的编译
UEFI应用的加载
gBS关于Image的接口
EFI_BOOT_SERVICES *gBS = NULL; // BootServices中关于Image的描述:////// EFI Boot Services Table.///typedef struct {//// Image Services//EFI_IMAGE_LOAD LoadImage;EFI_IMAGE_START StartImage;EFI_EXIT Exit;EFI_IMAGE_UNLOAD UnloadImage;EFI_EXIT_BOOT_SERVICES ExitBootServices;}实现如下// DXE Core Module Variables//EFI_BOOT_SERVICES mBootServices = {(EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage(EFI_IMAGE_START) CoreStartImage, // StartImage(EFI_EXIT) CoreExit, // Exit(EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage(EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices};
Shell加载应用过程
我们应用程序运行 在Shell中
解析过程如下:
InternalShellExecuteDevicePathgBS->LoadImage // 将文件加载到内存,生成Image对象gBS->OpenProtocol // 获取命令行参数gBS->StartImage // 启动Image,调用CoreStartImageCoreStartImage// 设置退出时的位置Image->JumpBuffer = AllocatePool 设置Long jump,用于退出程序SetJumpFlag = SetJump (Image->JumpContext);// 跳转到程序中运行Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);_ModuleEntryPoint() // 入口 MdePkg\Library\UefiApplicationEntryPoint\ApplicationEntryPoint.c

_ModuleEntryPointProcessLibraryConstructorList // 所有库的构造函数ProcessModuleEntryPointList // 调用Image main的入口函数ProcessLibraryDestructorList // 所有库的析构函数
这三个函数,在build的时候,根据inf文件生成 Autogen.c和Autogen.h文件,这三个函数就是Autogen文件的一部分。
dsc,dec,fdt文件描述

dsc文件(Platform Description File)
dec文件(Package Declaration File) 包声明文件。
fdt文件 用于生成Image文件。
