UEFI inf

news/2025/1/14 22:13:34/文章来源:https://www.cnblogs.com/linhaostudy/p/18671828

inf文件介绍

inf是属于UEFI的标准应用程序工程模块的工程文件,每个程序工程模块,由工程文件和源文件组成。源文件就是c/asm这些程序文件,工程文件就是inf文件。inf文件相当于Makefile文件一样,是对源文件去做整合编译成模块文件的工程文件,用于让edk2编译工具去自动编译模块。

inf文件组成

inf工程文件分为很多个块,每个块以 [块名] 开头,这个 [块名] 必须独立一行。其中一些块是inf必须要有的,还有一些不是必须的。

1、[Defines]块:

属性定义语法:
属性名 = 属性值

[Defines]INF_VERSION                    = 0x00010005    //必须 ,INF标准的版本号。edsk2的build会检查这个值而去解释.inf文件,最新的版本号是0x00010016,通常设置成0x00010015就行BASE_NAME                      = DxeCore    //必须,模块名字字符串,不能包含空格。它通常也是输出文件的名字,生成文件DxeMain.efiMODULE_UNI_FILE                = DxeCore.uni    //非必须 ,字符串资源文件FILE_GUID                      = D6A2CB7F-6A18-4e2f-B43B-9920A733700A    //必须, 8-4-4-4-4-12格式的唯一GUID,用于生成固件,MODULE_TYPE                    = DXE_CORE    //必须 ,定义模块的模块类型。SEC、PEIM、DXE_DEIVER等VERSION_STRING                 = 1.0    //必须, 模块的版本号字符串ENTRY_POINT                    = DxeMain    //必须,模块的入口函数

2、[Sources]块:

此块下的每一行表示一个文件,文件使用相对路径

[Sources]    //一般情况下不指定特定编译项时,使用这个即可,适用于任何体系结构Test.c[Sources.IA32]    //编译32位模块时(build命令选项中指定了-a IA32选项),包含这个和Sources中的Test.cCpu32.c[Sources.X64]    //编译64位模块时,包含这个和Sources中的Test.cCpu64.c[Sources]
TimerWin.c | MSFT    //指定编译器有效
TimerLinux.c | GCC    //指定编译器有效

3、[Packages]块:

此块下面列出了模块所引用到的所有包的声明文件dec文件。如果在Sources块内列出了源文件,在此块下必须列出MdePkg/MePkg.dec,并放在此块的首行

4、[LibraryClasses]块:

此块内列出了模块所要链接的所有库模块(使用了库的库函数就要列出来)。库定义在包的dsc文件中

5、[BuildOptions]块:

1、语法:

[BuildOptions]
[编译器家族] : [$ (Target)]*[Tool_CHAIN_TAG]*[$ (Arch)]_[CC | DLINK]_FLAGS [= |==]选项

2、编译器家族可以是MSFT(Visual Studio编译器家族)、INTEL(Intel编译器家族)、GCC(Gcc编译器家族)和 RVCT(ARM编译器家族)中的一个

Target是DEBUG、RELEASE和中的一个,是通配符

TOOL_CHAIN_TAG是编译器的名字,编译器定义在Conf/tools_def.txt文件中,*表示对指定编译器家族内的所有编译器都有效

Arch是体系结构,可以是IA32、X64、IPF、EBC或ARM,*是通配符

CC表示编译选项,DLINK表示链接选项

=表示选项附加到默认选项后面,==表示仅使用所定义的选项,不用默认选项。它们后面是编译选项或连接选项

[BuildOptions]# Enable STDARG for variable arguments*_*_*_CC_FLAGS = -DHAVE_STDARG_H# Override MSFT build option to remove /Oi and /GLMSFT:*_*_*_CC_FLAGS          = /GL-INTEL:*_*_*_CC_FLAGS         = /Oi-# Oniguruma: potentially uninitialized local variable usedMSFT:*_*_*_CC_FLAGS = /wd4701 /wd4703# Oniguruma: intrinsic function not declaredMSFT:*_*_*_CC_FLAGS = /wd4164# Oniguruma: old style declaration in st.cMSFT:*_*_*_CC_FLAGS = /wd4131# Oniguruma: 'type cast' : truncation from 'OnigUChar *' to 'unsigned int'MSFT:*_*_*_CC_FLAGS = /wd4305 /wd4306# Oniguruma: nameless union declared in regparse.hMSFT:*_*_*_CC_FLAGS = /wd4201# Oniguruma: 'type cast' : "int" to "OnigUChar", function pointer to "void *"MSFT:*_*_*_CC_FLAGS = /wd4244 /wd4054# Oniguruma: previous local declarationMSFT:*_*_*_CC_FLAGS = /wd4456# Oniguruma: signed and unsigned mismatch/castMSFT:*_*_*_CC_FLAGS = /wd4018 /wd4245 /wd4389# Oniguruma: tag_end in parse_callout_of_nameGCC:*_*_*_CC_FLAGS = -Wno-error=maybe-uninitialized# Oniguruma: implicit conversion from 'UINTN' (aka 'unsigned long long') to 'long'GCC:*_CLANG9_*_CC_FLAGS = -Wno-error=constant-conversion# Not add -Wno-error=maybe-uninitialized option for XCODE# XCODE doesn't know this optionXCODE:*_*_*_CC_FLAGS =

inf文件编译运行

源文件,inf工程文件完成,想要编译运行这个模块,需要将inf工程文件添加到dsc的[Components]部分,然后就可以使用build工具编译

模块应用程序是如何被编译成.efi文件的:

1、.c源码文件先被编译成目标文件.obj

2、连接器将目标文件*.obj和其他的库连接成*.dll

3、GenFw工具将*.dll转化成*.efi

这些过程都由build命令自动完成

标准应用程序加载过程(efi文件加载)

1、将efi文件加载到内存

efi模块文件————gBS ->LoadImage()将efi文件加载到内存中生成image对象————gBS->StartImage(Image)启动Image对象

gBS 指向启动服务表 global Boot Servers

gST 指向系统表 global System Table

gRT 指向运行时服务表 global Running Time

gImageHandle 指向正在执行的驱动或应用程序

EFI_STATUS
LoadDriver(IN CONST CHAR16   *FileName,IN CONST BOOLEAN  Connect)
{EFI_HANDLE                    LoadedDriverHandle;EFI_STATUS                    Status;EFI_DEVICE_PATH_PROTOCOL      *FilePath;EFI_LOADED_IMAGE_PROTOCOL     *LoadedDriverImage;LoadedDriverImage   = NULL;FilePath            = NULL;LoadedDriverHandle  = NULL;Status              = EFI_SUCCESS;*************************************//// Use LoadImage to get it into memory//Status = gBS->LoadImage(FALSE,gImageHandle,FilePath,NULL,0,&LoadedDriverHandle);**********************************************//// Make sure it is a driver image//Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *) &LoadedDriverImage);*************************************************/** 找出可执行的程序镜像Image的入口函数并执行找到的入口函数, gBS->StartImage是个函数指针,实际指向CoreStartImage函数*/Status = gBS->StartImage(LoadedDriverHandle, NULL, NULL);if (EFI_ERROR(Status)) {ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);} else {ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);}}
**********************************************************return (Status);
}

2、进入镜像image的入口函数

CoreStartImage的主要作用是调用镜像的入口函数,在这里面SetIump/LongJumps是为应用程序提供了一种错误处理机制。gBS->StartImage的核心是EntryPoint函数,它就是这个应用程序的入口函数,就是_ModuleEntryPoint函数,进入到这里,代码执行的控制权才转交给我们的应用程序efi

EFI_STATUS
EFIAPI
CoreStartImage (IN EFI_HANDLE  ImageHandle,OUT UINTN      *ExitDataSize,OUT CHAR16     **ExitData  OPTIONAL)
{EFI_STATUS                    Status;LOADED_IMAGE_PRIVATE_DATA     *Image;LOADED_IMAGE_PRIVATE_DATA     *LastImage;UINT64                        HandleDatabaseKey;UINTN                         SetJumpFlag;EFI_HANDLE                    Handle;**************************************************************//// Set long jump for Exit() support// JumpContext must be aligned on a CPU specific boundary.// Overallocate the buffer and force the required alignment//Image->JumpBuffer = AllocatePool (sizeof (BASE_LIBRARY_JUMP_BUFFER) + BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);if (Image->JumpBuffer == NULL) {//// Image may be unloaded after return with failure,// then ImageHandle may be invalid, so use NULL handle to record perf log.//PERF_START_IMAGE_END (NULL);//// Pop the current start image context//mCurrentImage = LastImage;return EFI_OUT_OF_RESOURCES;}Image->JumpContext = ALIGN_POINTER (Image->JumpBuffer, BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT);SetJumpFlag = SetJump (Image->JumpContext);//// The initial call to SetJump() must always return 0.// Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().//if (SetJumpFlag == 0) {RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));//// Call the image's entry point 核心//Image->Started = TRUE;Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);******************************************************************//// UEFI Specification - StartImage() - EFI 1.10 Extension// To maintain compatibility with UEFI drivers that are written to the EFI// 1.02 Specification, StartImage() must monitor the handle database before// and after each image is started. If any handles are created or modified// when an image is started, then EFI_BOOT_SERVICES.ConnectController() must// be called with the Recursive parameter set to TRUE for each of the newly// created or modified handles before StartImage() returns.//**********************************************************************//// Save the Status because Image will get destroyed if it is unloaded.//Status = Image->Status;**************************************************************************//// Done//PERF_START_IMAGE_END (Handle);return Status;
}

_ModuleEntryPoint函数:

EFI_STATUS
EFIAPI
_ModuleEntryPoint (IN EFI_PEI_FILE_HANDLE       FileHandle,IN CONST EFI_PEI_SERVICES    **PeiServices)
{if (_gPeimRevision != 0) {//// Make sure that the PEI spec revision of the platform is >= PEI spec revision of the driver//ASSERT ((*PeiServices)->Hdr.Revision >= _gPeimRevision);}//// Call constructor for all libraries//ProcessLibraryConstructorList (FileHandle, PeiServices);//// Call the driver entry point//return ProcessModuleEntryPointList (FileHandle, PeiServices);
}

3、进入模块的入口函数

在_ModuleEntryPoint中,调用了ProcessModuleEntryPointList ,然后在build过程中,会解析inf文件,生成AutoGen.c文件,里面查看

ProcessModuleEntryPointList ,它调用了应用程序工程模块的真正入口函数,就是inf文件中指定的那个入口函数

EFI_STATUS
EFIAPI
ProcessModuleEntryPointList (IN       EFI_PEI_FILE_HANDLE  FileHandle,IN CONST EFI_PEI_SERVICES     **PeiServices){return PcdPeimInit (FileHandle, PeiServices);
}

标准应用程序工程模块入口函数调用过程:

efi——LoadImage——StartImage——_ModuleEntryPoint——ProcessModuleEntryPointList ——inf中指定的入口函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/869281.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nodecanvas插件的黑魔法:一行代码避免拖拽节点的意外脱离

简介 在nodecanvas造轮子的过程,遇到了鼠标拖拽太快,节点经常会脱离控制的情况。但是nodecanvas却不会有这个问题。 一番折腾发现是nodecanvas调用了GUI.DragWindow(),而我觉得这个函数没啥用给删除了的原因。。 GUI.DragWindow()在MouseDown事件触发时,会调用GrabMouseCon…

windows server2016搭建AD域服务器

windows server2016搭建AD域服务器@目录一、背景二、搭建AD域服务器步骤三、生成可供java程序使用的keystore文件四、导出某用户的keytab文件五、主机配置hosts文件六、主机确认是否能ping通本人其他相关文章链接 一、背景 亲测可用,之前搜索了很多博客,啥样的都有,就是不介绍…

07 异常

什么是异常 异常就像是生活中遇到的意外情况。在程序运行过程中,可能会出现一些意想不到的问题,比如要打开的文件不存在、网络连接突然中断、除数为零等,这些就是异常。当异常发生时,如果不处理,程序可能会崩溃或出现错误结果,所以需要我们去处理这些异常,让程序能更稳健…

MySQL基础 数据库表的增删改

Mysql 数加科技整理 一、原理定义概念 定义数据库(Database)是按照数据结构来组织、存储和管理数据的建立在计算机存储设备上的仓库。 数据库是长期储存在计算机内、有组织的、可共享的数据集合。分类: ​ 非结构化数据: ​ 数据相对来讲没有固定的特点,这种数据非常不便于…

加入我们|申请成为亚马逊云科技 Community Builder,共建云端社区!

亚马逊云科技 Community Builder 项目为开发者社区中的技术爱好者和新兴思想领袖提供技术资源、学习和交流机会,帮助开发者探索、分享技术相关知识,并与亚马逊云科技产品团队、技术专家和更多开发者社区成员建立紧密联系。亚马逊云科技开发者社区为开发者们提供全球的开发技术…

[ARC070E] NarrowRectangles

前言 模拟赛 \(\rm{T4}\) , 不会比较正常, 仅仅只是记录做法 然后就是还有每日一练 思路 首先是朴素的 \(\rm{dp}\) 令 \(f_{i, j}\) 表示考虑到第 \(i\) 行, 其中这一行的左端点位置为 \(j\) 的最优花费 容易写出转移 \[f_{i, j} \gets \min_{k \in [j - len_{i - 1}, j + len…

PDF Automation文档页面自动化工具

PDF Automation是我用VB6开发的一个PDF文档页面自动化工具。电脑必须安装了Adobe Acrobat才能使用该工具。软件的主要功能包括:文档的拆分 文档的合并 页面的删除 页面的移动 页面的插入等。 软件界面正中央的区域是文档列表,也就是多个PDF文档,最右侧是页面列表,显示当前所…

not_the_same_3dsctf_2016 1

打开ida能看到栈溢出,返回地址填到get_secret函数里面,可以看到get_secret函数是直接读取了flag的,现在就需要把它输出即可。 输出我们可以利用代码里面的printf,因为printf从缓冲区打印出东西需要满足条件,比如有换行符或缓冲区已满或程序正常退出。 这里我们用exit让程序…

JS-35 数组方法_reverse()

reverse方法用于颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组 var a =[a,b,c]; a.reverse()//["c","b","a"];

FastGPT及大模型API(Docker)私有化部署指南

本文提供了FastGPT及其相关大模型API的Docker私有化部署指南,旨在简化部署流程并降低设备配置要求。文章重点介绍了优化后的部署配置、推荐使用的部署容器以及部署步骤,确保用户能够在不影响FastGPT功能的前提下,以高效的资源利用实现快速部署。1. **部署优化**:本文首先指…

LCT

1 概述 首先我们需要知道一类问题,在这类问题中我们需要维护一个森林,支持加边和删边操作,然后要求维护树上的一些信息。这类问题称为动态树问题。 而 LCT,即 Link-Cut Tree,就是用于解决动态树问题的一种数据结构。 学习 LCT 之前需要对 Splay 这种平衡树有一定了解,当然…

git整体使用流程

一、场景说明本地有文件 想在github创建一个远程仓库 在本地修改,同时同步到远端二、流程设置用户名和邮箱目的:标识每次提交者的身份 设置全局用户名:git config --global user.name "Your Name" 设置全局邮箱:git config --global user.email "your.email…