UEFI开发与调试---edk2中的应用模块/库模块/驱动模块

Posted 毛毛虫的爹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UEFI开发与调试---edk2中的应用模块/库模块/驱动模块相关的知识,希望对你有一定的参考价值。

应用模块
应用模块包含标准应用程序模块,shell应用程序模块,以及main应用程序模块

标准应用程序模块
它是所有其他应用程序模块的基础,作为一个模块来说,同样由源文件和工程文件(.inf)组成。
它的特征如下:

(1) .inf中的ENTRY_POINT一般设置为UefiMain,这是一个约定俗称的名字,所以这个规则并不是一定的。 (2) 指定的ENTRY_POINT入口函数必须要在模块源文件中有对应的实现。 (3).inf中的MODULE_TYPE必须设置为UEFI_APPLICATION
例如:

[Defines]
INF_VERSION = 0x00010006
BASE_NAME = TestApp
FILE_GUID = 7C04A583-9E3E-4f1c-AD65-E05268D0B4D1
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain

shell应用程序模块
故名思意,这是一种方便在uefi shell环境中执行的应用程序模块,可以方便的处理shell传入的命令行参数。
它的特征如下:

(1) ENTRY_POINT必须设置为ShellCEntryLib (2) MODULE_TYPE必须设置为UEFI_APPLICATION (3) [Packages]中需要引用MdePkg和ShellPkg这两个包 (4) [LibraryClasses]中必须依赖ShellCEntryLib (5) 源文件中必须要定义函数EFIAPI ShellAppMain (IN UINTN Argc, IN CHAR16 **Argv)
例如:

[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Hello
FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib

VALID_ARCHITECTURES = IA32 X64 IPF

[Sources]
Hello.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
UefiLib
ShellCEntryLib
这类模块的运行都是从ShellCEntryLib开始,这个函数是在ShellCEntryLib中实现的,在其中会调用一个名为ShellAppMain的函数,这也就是为什么我们需要在源文件中必须实现ShellAppMain的原因。

main应用程序模块
熟悉C语言的应该都知道此函数,UEFI中也支持这种类型的应用程序模块,但是这种类型的模块需要依赖libc库。特征如下:

(1) ENTRY_POINT必须设置为ShellCEntryLib。
(2) MODULE_TYPE必须设置为UEFI_APPLICATION
(3) [Packages]中除了引用MdePkg和ShellPkg这两个包之外,还有StdLib包
(4) [LibraryClasses]中必须依赖ShellCEntryLib,LibC和LibStdio库
(5) 源文件中必须要定义main函数,和普通的C语言编程定义的格式一样。

库模块
一个大型工程中肯定缺少不了库,库作为一个公用模块,能够极大的复用代码,提高开发效率,UEFI中同样支持库模块,它的特征如下:

(1) MODULE_TYPE必须设置为BASE

(2) 必须要定义LIBRARY_CLASS为库名

(3) 不要设置入口函数ENTRY_POINT

驱动模块
驱动分为两种类型,一种为UEFI驱动,另一种为DXE驱动。UEFI驱动是符合UEFI驱动模型的一种模块,框架定义了如何驱动硬件以及如何提供服务(Protocol的绑定)。而DXE驱动主要是用于实现一些特殊功能的模块,简化驱动的开发,比如我们想仅仅提供一种服务,而不驱动硬件,那么可以采用DXE驱动的形式来简化此功能的实现。在UEFI中,驱动模块和应用模块都运行在同一个地址空间,不像Linux分为应用空间和内核空间,它们最大的区别是:应用程序只在运行时存在于内存在,而驱动是常驻内存的。所以对于一个服务来说,我们需要它常驻内存就必须通过驱动的方式来安装。

UEFI驱动和DXE驱动的最大区别是UEFI驱动需要按照UEFI定义的框架来实现一个驱动,而DXE驱动没有这个限制,更加自由,比如我们仅仅想提供一个服务,那么只需要在DXE驱动的ENTRY_POINT中去实现Procotol即可,而如果要通过UEFI驱动实现,当然是可以的,只是会稍微复杂一些。

它的特征如下:

(1) 它也有ENTRY_POINT入口函数,并且在驱动load时执行此入口函数,该函数需要在源文件中定义

(2) MODULE_TYPE被设置为UEFI_DRIVER或者DXE_DRIVER

(3) [LibraryClasses]块中必须要包含UefiDriverEntryPoint

Protocol
Protocol在UEFI是一个很重要的概念,它可以认为是一个服务,一个service和client之间的接口,通过上文,我们已经了解到,服务是需要常驻内存的,那么一般Protocol是实现在UEFI驱动模块和DXE驱动模块中的。当驱动模块作为Protocol的服务提供者加载以后,那么应用程序就可以作为客户端来使用此服务了。BootService提供了InstallProtocolInterface和OpenProtocol相关的一些操作。

以上是关于UEFI开发与调试---edk2中的应用模块/库模块/驱动模块的主要内容,如果未能解决你的问题,请参考以下文章

UEFI 原理与编程 1 : UEFI开发环境EDK2搭建

Windows7下UEFI开发EDK2环境搭建(VS2013+UDK2015+IASL+patch+Openssl)

Windows7下UEFI开发EDK2环境搭建(VS2013+UDK2015+IASL+patch+Openssl)

Windows7下UEFI开发EDK2环境搭建(VS2013+UDK2015+IASL+patch+Openssl)

EDK2开发环境搭建

国际主流固件接口组织UEFI全面支持LoongArch,龙架构已完成上游TianoCore EDK2代码合并...