UEFI与inf文件

背景

学习高通UEFI中的LCD显示框架,看到有些博客对inf文件进行了介绍,因此整理了这方面的一些入门知识。

参考:

inf文件的构成

Defines

INF_VERSION:Inf版本号,用于编译时解释inf文件,通常设置为0x00010005,INF_VERSION版本号便于EDKII系统升级。

BASE_NAME:用于设置编译输出的文件名称,根据文件功能设置,不能包含空格。它通常也是输出文件名字。

FILE_GUID:文件的全局唯一标识符,格式:8-4-4-4-12,用于生成固件。例如: 4ea97c46-7491-4dfd-b442-747010f3ce5f

可以通过 http://www.guidgen.com/获得GUID。

VERSION_STRING:文件版本字符串,用于标注文件的版本号

MODUL_TYPE:用于标识模块的类型、应用工程文件设置为:UEF工_APPLICATION

定义模块的模块类型,可以是SEC/PEI_CORE/PEIM/DXE_CORE/DXE_SAL_DRIVER/DXE_SMM_DRIVER/UEFI_DRIVER/DXE_DRIVER/DXE_RUNTIME_DRIVER/UEFI_APPLICATION/BASE中的一个。对于标准应用程序工程模块来说,为UEFI_APPLICATION类。

ENTRY POINT:模块的入口函数

Sources

列出文件内所有的源文件和资源文件

Packages

列出文件使用的包的描述文件,即.dec文件,如果source块内包含了源文件,必须将MdePkg/MdePkg.dec放在首行

LibraryClasses

列出文件内所使用的库文件,应用工程文件必须包含UefiApplicationEntryPoint,驱动文件必须包含UEFIDriverEntryPoint

Protocols

列出文件内使用的Protocol的GUID

BuildOptions

编译配置。

  • = 表示选项附加到默认选项后面。
  • == 表示仅使用所定义的选项,弃用默认选项。

附录

初识UEFI

按惯例,首先让我们用HelloWorld跟UEFI打个招呼吧

标准application

/*main.c */
#include <Uefi.h>
EFI_STATUS
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
SystemTable -> ConOut-> OutputString(SystemTable -> ConOut, L"HelloWorld\n");
return EFI_SUCCESS;
}

有以下几点需要注意:

1、 头文件, 所有的UEFI程序都有#include <Uefi.h>

2、 main函数, UEFI 基本Application的main函数是UefiMain

3、 main函数的返回值类型 EFI_STATUS。 在UEFI中基本上所有的返回值类型都是EFI_STATUS。它本质上是UINTN。

4、 main函数的参数。.efi 文件加载到内存后称为Image, ImageHandle 用来描述、访问、控制此Image。 第二个参数是SystemTable,它是我们的程序同UEFI内核打交道的桥梁,通过它我们可以使用UEFI提供的各种服务,如Boot Services和 Runtime Services。 SystemTable是UEFI内核中的一个全局结构体。

5、 输出是通过EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL的OutputString服务完成的。 服务(函数)的第一个参数是This指针,指向Protocol本身。 OutputString()的第二个参数是Unicode字符串。

对应的inf文件

要想编译main.c,我们还需要.inf文件, 在main.c所在的目录下编辑main.inf文件

##

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = main #输出文件的名字为 main.efi
FILE_GUID = 6987936E-ED34-ffdb-AE97-1FA5E4ED2117
MODULE_TYPE = UEFI_APPLICATION #模块类型: UEFI_DRIVER, DXE_DRIVER, DXE_RUNTIME_DRIVER,UEFI_APPLICATION,BASE,等
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain #入口函数 #
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
# # 源文件
[Sources]
main.c # .dec里面定义 include的路径
[Packages]
MdePkg/MdePkg.dec #要链接的库
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib [Protocols]
[FeaturePcd]
[Pcd.common]
[Guids] #编译选项, = 表示选项附加到默认选项后面。 == 表示仅使用所定义的选项,弃用默认选项。
[BuildOptions]
#MSFT:*_*_*_CC_FLAGS == /nologo /c /WX /GS- /W4 /Gs32768 /D UNICODE /O1ib2 /GL /EHs-c- /GR- /GF /Gy /Zi /Gm /D EFI_SPECIFICATION_VERSION=0x0002000A /D TIANO_RELEASE_VERSION=0x00080006 /FAs /Oi-
#MSFT:*_*_*_CC_FLAGS = /wd4804
#MSFT:Debug_*_IA32_CC_FLAGS =
#MSFT:Debug_*_X64_CC_FLAGS =
#MSFT:Release_*_IA32_CC_FLAGS =
#MSFT:Release_*_IA32_CC_FLAGS =
#MSFT:Release_*_IA32_DLINK_FLAGS =
#GCC:Release_*_IA32_CC_FLAGS =

然后将 main.inf 添加到 Nt32Pkg.dsc 或UnixPkg.dsc 的[Components]部分,

例如添加下面一行(example目录在EDK2下)example/main/main.inf

然后就可以使用BaseTools下的build进行编译了。

Windows下执行:

edksetup.bat
build -p Nt32Pkg\t32Pkg.dsc -a IA32

Linux 执行

source ./edksetup.sh BaseTools
build -p UnixPkg/UnixPkg.dsc -a IA32

其他类型的inf文件

(1) 可以看出标准的application处理命令行参数不方便,UEFI提供了帮我们处理命令行参数的入口函数ShellCEntryLib。 我们要实现INTN ShellAppMain(UINTN Argc, CHAR16** Argv) 作为(开发者视角的)入口函数。

/*Main.c */
#include <Uefi.h>
INTN
EFIAPI
ShellAppMain (
IN UINTN Argc,
IN CHAR16 **Argv
)
{
gST -> ConOut-> OutputString(gST -> ConOut, L"HelloWorld\n");
return 0;
}

inf文件。 我们需要连接ShellCEntryLib 库。

[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Main
FILE_GUID = 4ea97c46-7491-4dfd-b442-747010f3ce5f
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib #
# VALID_ARCHITECTURES = IA32 X64 IPF
# [Sources]
Main.c [Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec [LibraryClasses]
ShellCEntryLib
UefiLib [BuildOptions]

(2)使用main函数的application。如果你想像C一样使用main函数,那么你需要用到LibC。 LibC 中提供了ShellAppMain函数,我们要提供int main(int Argc, char** Argv)供其调用。

/*Main.c */
#include <Uefi.h>
int
EFIAPI
main (
IN int Argc,
IN char **Argv
)
{
gST -> ConOut-> OutputString(gST -> ConOut, L"HelloWorld\n");
return 0;
}

真正的入口函数是ShellCEntryLib, 调用过程为 ShellCEntryLib -> ShellAppMain -> main.

inf 文件: 我们需要连接ShellCEntryLib 和LibC库。

[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Main
FILE_GUID = 4ea97c46-7491-4dfd-b442-747010f3ce5f
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib #
# VALID_ARCHITECTURES = IA32 X64 IPF
# [Sources]
Main.c [Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec [LibraryClasses]
LibC
ShellCEntryLib
UefiLib [BuildOptions]
MSFT:*_*_IA32_CC_FLAGS = /Oi-

还要再说明一点,如果你的程序中用到了printf(...)等等标准C的库函数,那么一定要使用此种类型的application。 因为ShellCEntryLib 函数中会调用ShellAppMain(...), StdLib的ShellAppMain(...) 会对stdlib 进行初始化。 然后才可以调用stdlib的函数。 (当然,如果你已经清楚地了解了入口函数的处理流程,你也可以手工调用StdLib的ShellAppMain进行出事后).

(3)Lib 模块的inf文件。开发大型工程的时候我们会用到lib。

例如我们要开发视频解码程序,会用到zlib库

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = zlib
FILE_GUID = 348aaa62-BFBD-4882-9ECE-C80BBbbbb736
VERSION_STRING = 1.0
MODULE_TYPE = BASE #Base 表示此模块编译为library
LIBRARY_CLASS = zlib #
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
# [Sources]
adler32.c
crc32.c
deflate.c
infback.c
inffast.c
inflate.c
inftrees.c
trees.c
zutil.c
compress.c
uncompr.c
gzclose.c
gzlib.c
gzread.c
gzwrite.c [Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
StdLib/StdLib.dec [LibraryClasses]
MemoryAllocationLib
BaseLib
UefiBootServicesTableLib
BaseMemoryLib
UefiLib
UefiRuntimeServicesTableLib [Protocols] [FeaturePcd] [Pcd] [Guids] [BuildOptions]
GCC:*_*_IA32_CC_FLAGS = -D__UEFI__ -DLARGEFILE64_SOURCE=1 -w

然后将 zlib|zlib-1.2.6/zlib.inf # zlib-1.2.6 在EKD2的根目录下放到.dsc 文件 [LibraryClasses]中。

需要链接zlib的时候,在.inf文件的[LibraryClasses]中添加 zlib即可。

(4)driver模块的inf文件。例如DiskIo的inf(MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf)

[Defines]
INF_VERSION = 0x00010005
BASE_NAME = DiskIoDxe
FILE_GUID = 6B38F7B4-AD98-40e9-9093-ACA2B5A253C4
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeDiskIo #
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
# DRIVER_BINDING = gDiskIoDriverBinding
# COMPONENT_NAME = gDiskIoComponentName
# COMPONENT_NAME2 = gDiskIoComponentName2
# [Sources]
ComponentName.c
DiskIo.h
DiskIo.c [Packages]
MdePkg/MdePkg.dec [LibraryClasses]
UefiBootServicesTableLib
MemoryAllocationLib
BaseMemoryLib
BaseLib
UefiLib
UefiDriverEntryPoint
DebugLib [Protocols]
gEfiDiskIoProtocolGuid ## BY_START
gEfiBlockIoProtocolGuid ## TO_START

现在我们已经扫除了编译UEFI应用的所有障碍。

UEFI与inf文件的更多相关文章

  1. Autorun.inf文件(2):改变硬盘分区图标

    改变F盘图标. 原理:在f盘下新建一个Autorun.inf文件,文件内容是 [AutoRun]icon=favicon.ico准备名为favicon.ico图标文件,将其放在工程目录里,设计程序将它 ...

  2. 关于Autorun.inf文件

    配置Autorun.inf文件可以使双击磁盘时,自动运行某一应用程序.但是现在只支持CD或者DVD媒体了(以前硬盘也可以) 关于Autorun.inf的组成部分可以参考https://msdn.mic ...

  3. ATL开发 ActiveX控件的 inf文件模板

    ATL开发 ActiveX控件的 inf文件模板    

  4. Inno setup 安装*.inf文件_示例

    nno setup 调用*.Inf文件的条目区段名称_示例 首先自己编写一个INF文件来供 Inno setup 进行测试: ;复制以下代码到记事本然后另存为123.inf .然后把123.inf文件 ...

  5. 【转】从INF文件认识驱动

    在工控机安装xp操作系统时,由于工控机的集成显卡驱动只支持win7,之前没接触过windows驱动相关内容,折腾了半天.下载的驱动是exe的,双击安装就提示安装失败(未签名) 上图是网上随便找的,现象 ...

  6. INF文件

    百度百科:http://baike.baidu.com/view/637107.htm?fr=ala0_1_1 INF简介 INF是Device INFormation File的英文缩写,是Micr ...

  7. windows driver inf文件

    原来修改了inf文件会导致签名过的驱动包哈希值不正确了啊.现在才知道. = = http://www.chiphell.com/thread-827956-1-1.html

  8. INF文件详解

    安装信息(Setup Information)文件是Windows系统支持的一种安装信息存放文件,一般以INF作为扩展名,因此也叫INF文件.安装信息INF文件与Windows内建的安装服务引擎(AP ...

  9. 安装程序不能验证Update.inf文件的完整性,请确定加密服务正在此计算机上执行

    近期安装Microsoft .NET Framework 4(独立安装程序)时,提示"安装程序不能验证Update.inf文件的完整性,请确定加密服务正在此计算机上执行" 没法放狗 ...

  10. Windows驱动 INF文件

    参考一:百度百科 参考二:INF文件的节 参考三:wikipedia 参考四:MSDN: INF File INF文件的节 INF文件是一个文本文件,由许多按层次结构排列的节组成,他们以方括号中的节名 ...

随机推荐

  1. LVGL学习资料

    一.资料整理 官网:https://lvgl.io/ 使用手册: 官方的使用手册是英文版的,百问网将其翻译成中文版的文档.地址如下: 官方使用文档:https://docs.lvgl.io/maste ...

  2. Quartus prime 的安装步骤:

  3. 混合开发中,app内嵌h5页面时,安卓ios遇到的一些兼容问题及解决方法

    1.input[type=checkbox]在ios端样式显示异常,黑色背景或边框,安卓正常 解决: input[type=checkbox]:checked{ background-color: t ...

  4. 微软开源 MS-DOS「GitHub 热点速览」

    上周又是被「大模型」霸榜的一周,各种 AI.LLM.ChatGPT.Sora.RAG 的开源项目在 GitHub 上"争相斗艳".这不 Meta 刚开源 Llama 3 没几天,苹 ...

  5. 【2023最新B站评论爬虫】用python爬取上千条哔哩哔哩评论

    目录 一.爬取目标 二.展示爬取结果 三.爬虫代码 四.同步视频 五.附完整源码 您好,我是@马哥python说,一枚10年程序猿. 一.爬取目标 之前,我分享过一些B站的爬虫: [Python爬虫案 ...

  6. linux系统共享文件夹到局域网

    python3 -m http.server https://blog.csdn.net/a772304419/article/details/113338103 Debian下配置Samba服务器 ...

  7. JavaScript实现全选选项框的功能和鼠标划入出现下拉框的功能--JavaScript实例集锦(初学)

    有一些论坛,文章后台编辑都会出现选择框的操作. 1.实现选项框全选和取消全选的功能: 代码实现: <!DOCTYPE html> <html> <head> < ...

  8. 关于sql server导出csv格式文件的身份证号乱码问题处理办法

    1.使用SQL Server数据库经常会遇到导出大量数据的情况,例如导出40万条数据,虽然EXCL支持可以放入百万的数据,但是使用数据库复制,粘贴到EXCL表格时,数据库会提示溢出的情况,如下图所示: ...

  9. 远程控制软件 Teamviewer、Splashtop、向日葵哪个好用

    ​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) 好用的远程控制软件,我一般只推荐这三个经典品牌: Teamviewer.Splashtop.向日葵. Teamviewer 来自德国,妥妥 ...

  10. Unity新的MeshData API学习

    在新版本的Unity中提供了MeshDataArray和MeshData等多个API,使Mesh数据操作支持多线程:以更好的支持DOTS. API文档:https://docs.unity3d.com ...