EDK II Module Writers Guide上

2023-11-11

一、EDK2简介

1.EDK2工作流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OSvqK5DA-1654853377936)(2.EDK2.assets/image-20220228100211960.png)]

二、EDK2 Packages

1.Packages介绍

EDK2 Packages是一个容器,其中包含一组模块模块的相关定义。每个Package是一个EDK2单元。

整个Project的源代码可以被分割成不同的Pkg。这样的设计不仅可以降低耦合性,还有利于分发和复用

1.1.EDK2 Packages

​ 每个Package中包含一个DEC文件,该文件用来组织Package中的一系列Module。EDK2提供了一些兼容UEFI和PI的包(如MdePkg、MdeModulePkg等)。

MdeModulePkg包中有一组符合UEFI和PI规范的跨平台驱动程序。在开发新的UEFI和PI驱动时可以用来参考。

1.2.DEC文件

DEC文件用来定义每个Package中的公共接口公共头文件GUIDPCDs

  • DEC文件主要包括以下部分:

(1)[Defines]

​ 定义PKG的名字PKG的GUID

(2)[Includes]

​ 列出公共头文件所处目录的根目录

(3)[LibraryClasses]

​ 列出在Include\Library下的每个Library Class头文件

(4)[Guids]

​ 给Include\Guid下的Guid赋值

(5)[Ppis]

​ 给Include\Ppi下的Ppi赋Guid值

(6)[Protocols]

​ 给Include\Protocol下的Protocol赋Guid值

(7)PCDs

​ 相关类型的PCD声明:FeatureFlag, FixedAtBuild, PatchableInModule, Dynamic, and DynamicEx。Dynamic类型的PCD在第四章:附录章节还有补充说明。

  • 若一个PCD支持多种类型,则需要在全部类型中全部声明
  • DEC文件写法示例:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TUAKfBVX-1654853377938)(2.EDK2.assets/image-20220124150947941.png)]
1.3.DSC文件

编译时使用到的文件,所有模块均可加入来进行Package编译验证

DSC文件主要包括以下部分:

(1)[Defines]

​ 设置Build的相关信息,如build输出目录build目的Guidbuild arch

(2)[LibraryClasses]

​ 对每个LibraryClasses指定选择的Library实例

(3)PCD

​ 用于配置[Components]部分中各模块使用的PCD类型和PCD值。

  • 如果PCD的值与DEC中的默认值相同,且PCD类型没有具体要求,则将使用DEC中的默认值。

(4)[Components]

​ 列出所有将被编译的Module,如Drivers, Application, and Library Instances

  • Path是相对路径,相对于Package根目录

  • DSC文件写法示例:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DXWtvXcm-1654853377938)(2.EDK2.assets/image-20220124154051402.png)]

2.Packages管理

2.1.创建Package
2.1.1.创建要求

(1)将有意义的包名作为包目录名,并创建一个包目录,例如PackageNamePkg

(2)在包根目录下创建包DECDSC文件来描述这个包

(3)创建子目录来包含不同的源文件

3.EDK II Module

​ 一个EDKII Module包含源文件或者二进制文件,和一个Module定义文件(inf文件

3.1.Module组成

​ 对于一个典型的EDK II Module而言,Module是一个固件组件。Module在构建完成后,首先被放入FFS文件,然后放入FV Image。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDCi0wJV-1654853377939)(2.EDK2.assets/image-20220125165739372.png)]

​ Module可以以源代码EFI二进制格式发布,Module的内容可以是下列几种类型:

(1)Raw data binary

例如:$(WORKSPACE)\MdeModulePkg\Logo\Logo.inf ,这就是包含了一个logo bitmap的image

(2)可选的设备ROM驱动

(3)独立的UEFI驱动或者UEFI应用

(4)一个 .lib 形式的library instance

3.2.Module分类

​ EDK II给Module定义了许多不同的Module类型。定义这些Module类型主要是为了:

(1)区分不同类型模块的生命周期

​ 例如:PEIM在PEI阶段调度,DXE_DRIVER或uefi_driver在DXE阶段

(2)表示不同类型模块的二进制image

(3)为不同类型的模块指定合适的library instance

  • 主要的EDKII Module类型:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y2GYVp6c-1654853377940)(2.EDK2.assets/image-20220125180605090.png)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-midmdebu-1654853377941)(2.EDK2.assets/image-20220125181005327.png)]
3.3.Module创建

Driver ModuleLibrary Module创建步骤相仿:

(1)选择或者创建一个Package,来存放Module

(2)为该Module创建一个目录,并且放入一个inf文件

(3)在inf文件中添加Package dependencies

(4)在inf文件中添加PPI Protocol Guid等相关dependencies

(5)如果模块依赖PPI Protocol Guid,则需要加入项[depex]

(6)创建源文件,并且在inf中填入源文件的相对路径

3.4.增加Module目录

​ Module目录需要按照以下规则添加到合适的Package中:
在这里插入图片描述
在这里插入图片描述

3.5.INF文件写法

​ INF文件是对于所在Module说明文件,放在根目录中,其中:

(1)Module的基础信息有:名字、GUID、模块类型等

(2)Module所依赖的所有Packages路径根目录相对路径

  • 所有模块都依赖MdePkg,需要将其加入
  • 如果使用来自Intel框架规范的定义,则IntelFrameworkPkg也是必需
  • 如果使用到了其它Package中的内容,则需要添加其它Packeage的dec文件
    在这里插入图片描述
    (3)源文件或者二进制文件路径

(4)模块用到的系列接口,如Protocol、Ppi、GUID

(5)模块所需的所有pcdLibrary类的列表

(6)其它内容,例如不同类型Module需要的不同的依赖部分

  • App Module的inf文件:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-duSRsDW3-1654854017637)(2.EDK2.assets/image-20220128101242722.png)]

  • Library Module的inf文件
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-awGltyUp-1654854017637)(2.EDK2.assets/image-20220128101445257.png)]

3.6.添加Source文件

1.INF中的 [sources] 模块定义了Source文件的相关内容,相关规则如下:

(1)不同的体系结构Source文件,放在不同的模块下,例如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vawF0bXt-1654854017638)(2.EDK2.assets/image-20220128150434892.png)]

(2)使用的不同工具链需要标注,例如:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e3GKIuNN-1654854017638)(2.EDK2.assets/image-20220128150533142.png)]

  • 相关Tool Tag
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nHwXkH5-1654854017639)(2.EDK2.assets/image-20220128172800228.png)]
3.7.添加Library Class References

Library类(Class)将相关的宏定义结构定义函数声明进行了抽象;而Library实例(instance)将这些内容进行了实现

​ Library实例(Instance)根据不同Platform,和相同Platform的不同阶段,其具体实现会有所差异

3.7.1.在模块中使用Library类的步骤:

(1)在INF文件中,给包含Library Class的package添加Dependency

(2)在INF文件中,给Library Class添加dependency

(3)在代码头文件中,包含LibraryClass

  • 头文件的路径是相对路径相对于package DEC文件[include]中写的路径

  • 实例

#include <Library/OemHookStatusCodeLib.h>

在这里插入图片描述
在这里插入图片描述

3.8.添加PCD References

​ EDK II引入了PCD实现宏定义的效果。例如,对于“FeatureFlag”类型的PCD,如果PCD的值为TRUE,则会启用某些特性或功能。

​ EDK II提供了以下类型的PCD:
在这里插入图片描述
在这里插入图片描述

3.8.1.使用PCD的步骤

(1)在Module的INF文件中,为PcdLib添加Dependency

(2)在Module的INF文件中,给MdePkg添加dependency

  • MdePkg是必需的,因为MdePkg中的“PcdLib”Library Class,提供了PCD访问函数和宏

(3)在代码头文件中,添加==<Library/PcdLib.h>==

(4)使用PcdLib提供的接口进行PCD Value的操作

  • PCD操作函数:
    在这里插入图片描述
  • PCD添加与使用实例:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x10RK0AZ-1654854017644)(2.EDK2.assets/image-20220228144804505.png)]
3.9.添加Prorocol、PPI、GUID Reference

​ Protocol、PPI、Guid是UEFI中固件之间通信的接口

3.9.1.在模块中使用Protocol、PPI、Guid

(1)在INF文件中,对应类别([Protocol]、[Ppi]或[Guid])添加需要的Protocol
在这里插入图片描述

(2)相应头文件必须清楚包含在Source code的头中
在这里插入图片描述

  • 头文件中都是相对路径相对于package DEC文件[include]中写的路径
    在这里插入图片描述
3.10.为Module添加Dependency

​ Module的Dependency限定了关于驱动程序的Entry Point的条件

​ 通过它,可以确定PEIM和DXE模块的调度顺序。

​ 一个表达式由一个或多个Protocol、PPI或GUID和操作符组成,例如“AND”, “OR”, “TRUE”, “FALSE”, “NOT” 等。
表示gEfiSampleGuid 的值和gEfiSamplePpiGuid的值进行布尔和运算

  • 具体运算法则描述,参考Platform Initialization SpecificationDependency Expressions 章节
    Dependency Expression Grammar章节
3.11.Define Library Class

​ Library Instance总是与Library Class相关,Library Instance实现了Library Class中定义的所有接口。

因此,==Library Class名必须在Library Instance的INF文件的[definitions]==中说明。

  • 如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R7M9unMZ-1654854017646)(2.EDK2.assets/image-20220228171446571.png)]

UefiDriverEntryPoint 是Library Class的名字,这个名字由Library Instance所来。

DXE_DRIVER和DXE_RUNTIME_DRIVER是这个Library Instance所支持的类型。

3.12 Driver Module的额外步骤

PEIM或者DXE Driver需要在INF文件中的==[Defines]中标明函数Entry_Point==。不同的Module类型具有不同的Entry_Point

  • 示例图:
    在这里插入图片描述
3.13 常见Library Class

MdePkg中提供了许多Library Class,用来基于UEFI和PI开发固件组件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N02AM5Zu-1654854017647)(2.EDK2.assets/image-20220301111327730.png)]

3.14 使用HII的Module

​ DXE Module可以在BDS阶段中打印或更新,browser将使用到下列资源:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87PfrOB0-1654854017647)(2.EDK2.assets/image-20220301145831437.png)]

3.14.1 Forms

(1)VFR Resource File

VFR文件用来描述form(即格式)资源。VFR文件的用法和其它Source Code用法相似。

需要将其在Module的INF文件的[Sources]部分中列出

  • 用法示例:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3uSwV9DP-1654854017648)(2.EDK2.assets/image-20220301150433271.png)]

(2)打印VFR

​ 在Module编译时,vfr文件会由Vfr编译器编译为一个.vfr文件,并且作为全局数组变量插入到Module image的IFR二进制区域中。这个全局数组变量的名字是:Vfr文件名+Bin

  • 示例如下:

    Inventory.vfr in the MdeModulePkg\Universal\DriverSampleDxe driver

is compiled into the global array variable InventoryBin.

(3)将VFR全局数组变量加入HII数据库

​ 使用以下代码段:

//
// Create HII driver handle, paramter DriverHandle will hold the
// returned new handle.
// HiiLibCreateHiiDriverHandle defined in UefiHiiLib library class.
//
Status = HiiLibCreateHiiDriverHandle(&DriverHandle);
//
// Prepare HII package list, parameter InventoryBin is the VFR form data
// HiiLibPreparePackageList defined in UefiHiiLib library class
//
PackageList = HiiLibPreparePackageList (2,
										&mInventoryGuid,
										InventoryBin,
										DriverSampleStrings);
ASSERT (PackageList != NULL);
//
// Create package into HII database via EFI_HII_PROTOCOL->NewPackageList
//
Status = gHiiDatabase->NewPackageList (
		gHiiDatabase,
		PackageList,
		DriverHandle,
		&HiiHandle
		);
3.14.2 Unicode Strings

​ Unicode字符串被放到.uni文件中,并在Module的INF文件的[Sources]部分列出,和C文件一样。

  • 示例如图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U034gRzY-1654854017648)(2.EDK2.assets/image-20220301155341180.png)]

(1)打印Unicode String文件

​ uni文件中的内容会被编译工具解析和编译为一个二进制字符串包数组。这个二进制数组的名字为ModuleName+ “Strings”

  • 例如:MdeModulePkg\Universal\DriverSampleDxe 中的inventorystring.uni最终的二进制数组名将会是:

    extern UINT8 DriverSampleStrings[];
    

(2)将Strings array variable 添加进 HII Database

//
// Create HII driver handle, paramter DriverHandle will hold the
// returned new handle.
// HiiLibCreateHiiDriverHandle defined in UefiHiiLib library class.
//
Status = HiiLibCreateHiiDriverHandle(&DriverHandle);
//
// Prepare HII package list, parameter DriverSampleStrings is the
// strings binary data.
// HiiLibPreparePackageList defined in UefiHiiLib library class
//
PackageList = HiiLibPreparePackageList (2,
										&mFormSetGuid,
										DriverSampleStrings,
										VfrBin);
if (PackageList == NULL) {
	return EFI_OUT_OF_RESOURCES;
}
//
// Create package into HII database via EFI_HII_PROTOCOL->NewPackageList
//
Status = HiiDatabase->NewPackageList (
						HiiDatabase,
						PackageList,
						DriverHandle[0],
						&HiiHandle[0]);

4. Module的编译

​ 当Module Source Code完成以后,Module的INF文件会被加入到Platform的DSC文件里,Module将被编译到预期的二进制Image中

​ EDK2编译系统支持编译Library ImageEFI ImageOptionRom Image

4.1 将Module INF文件加入到Packeage DSC文件

​ 为了编译一个Module,会在DSC文件的[Components]部分,指定Module的INF文件(路径是Package目录开始的相对路径,到INF文件名字为止)

​ DSC的[Defines]部分会列出所有支持的体系。[Components]部分会详细列出Module的支持体系。

  • 示例:
    在这里插入图片描述
4.2. 为Module选择Library Instance(library instance不需要此步)

​ 对于Driver和Application来说,每个Library Class必须选中对应的Library Instance,并且链接到二进制EFI Image处。

​ Module INF文件的==[LibraryClasses] 部分列出了所有需要的Library Class==,这些Library Class都是Library Instance所产生的。

​ 对于不同的目的(例如对性能和大小的优化),Library Instance可以有不同的实现方式

​ 在初始开发中通常使用没有经过优化的Library Instance来降低开发风险。完成模块的基本功能后,可以进一步调整其大小和性能。

​ 在MdePkg中,为用户选择提供了许多可用的Library Instances,详细信息可以在其INF文件或MdePkg规范中找到。

  • 举例:

    ​ 在MdePkg中,对于LibraryClass:BaseMemory的Library Instance:BaseMemoryLibOptDxe的实现,采用了寄存器操作内存的方式,获得了更好的性能表现。

    ​ 另一个例子是,在MdePkg中,LibraryInstance:PeiIoLibCpuIo通过使用CpuIo PPI的服务来实现IO的LibraryClass,减少了代码大小。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agUs7O8o-1654854899183)(2.EDK2.assets/image-20220301182326045.png)]

4.3 对于PCD的配置

​ 对于使用到PCD的Module,需要提前在Package DSC文件中配置。配置完成的PCD会被应用到Module和其链接的Library Instance两处。

​ PCD会在Package的DEC文件中声明。当PCD的Value和DEC文件中的默认值一致时,这些PCD则不需要再DSC中再次赋值。

​ 在DSC中,PCD类型和值可以根据Platform要求进行配置。在DSC中,一个PCD的类型只允许是唯一的类型。如果DSC中没有对其进行指定,那么PCD的类型将和DEC中声明的类型保持一致。如果一个PCD支持多种PCD类型,那么其默认PCD类型是固定PCD类型。

4.3.1 PCD的类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CwKkJrhl-1654854899183)(2.EDK2.assets/image-20220302110907087.png)]

(1)Feature Flag PCD

​ 如果一个PCD被声明为PcdsFeatureFlag ,那么它只能是FeatureFlag PCD type或者BOOLEAN data type。如果Module需要使用本类PCD,则需要在INF的[FeaturePcd]中预先指定

  • 只有通过FeaturePcdGet接口才可以操作此种类型的PCD

  • 示意:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KDW25lSV-1654854899183)(2.EDK2.assets/image-20220302111759055.png)]

(2)Fixed PCD

​ 如果一个PCD的Value在整个编译期间都是固定的,那么它的类型应设置为PcdsFixedAtBuild

当Module使用此类PCD时,它可以选择归属在==Module INF的[FixedPcd]或者[PCD]==中。

​ 此外,操作本类型的PCD,需要使用FixedPcdGet或者PcdGet接口

(3)Patchable PCD

​ 如果一个PCD的Value在二进制Image中不固定(会被修改),它的类型应设置为PcdsPatchable 。在Module中使用此类PCD时,它可以分在==[FatchPcd]或者[PCD]==。

(4)Dynamic PCD

​ 如果PCD的Value在运行期间获得,那么它的类型应设置为Dynamic。如果一个Dynamic PCD是从Driver共享的PCD数据库取得Value,那么它的类型应该是PcdsDynamicDefault;如果一个Dynamic PCD和UEFI Variable相关,那么它的类型应该是PcdsDynamicHII

​ 当在Module中使用Dynamic PCD,那么INF的 [PCD]部分需要注明。

​ 此外,操作Dynamic PCD只有通过PcdGet、PcdSet两个接口

  • 示例图:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTMLTFpj-1654854899184)(2.EDK2.assets/image-20220302152221614.png)]
4.4 Build选项修改

​ Build Option为不同的工具链提供了不同的编译选项,来编译出Image。它们在==$(WORKSPACE)/Conf/tools_def.txt file==被定义。在这个文件中,列出了不同工具链常见的编译器选项。

  • 编译器选项(compiler option)主要被分成两大类(详细选项可见EDK II Build Specification ):

​ 编译选项(compile option)

​ 链接选项 (link option)

​ EDKII 编译系统提供了四种层次override机制来实现Compiler Options的定制。

影响范围从大到小,依次是:Tool_def.txt,DSC(最为推荐,只修改了DSC文件),INF。

​ 这些Options可以通过指定顺序实现互相覆盖。

4.4.1 修改Tool_def.txt

​ 直接对tool_def.txt 进行修改,将会影响workspace里的所有Modulesplatforms

4.4.2 修改INF文件

​ 在Module INF文件的**[BuildOptions]**中,添加额外的编译器选项(compiler option),将会对该Module生效,并且在任何DSC中都可被编译。

  • 不同编译工具可选的编译器选项(compiler option)并不相同

  • Module INF示例:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mZXLKKYY-1654854899184)(2.EDK2.assets/image-20220526102736141.png)]

4.4.3 修改DSC文件

​ 在DSC的 [BuildOptions]部分添加额外的编译器选项(compiler option),同一个DSC中描述的所有Module的编译器选项都会被影响。

  • DSC示例
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nVXtRJvM-1654854899184)(2.EDK2.assets/image-20220526111145628.png)]

​ 在DSC的==[Components]部分,为某个Module添加编译器选项(compiler option),则只对该Module==,且只在该DSC生效。

  • DSC [Components]示例
    ​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uCF4KR5W-1654854899185)(2.EDK2.assets/image-20220526111638404.png)]
4.5 Build Module Image

​ 在DSC文件的 [Components] 中所添加的描述

4.5.1 Build Package(-p)

​ 如果 [Components] 没有指明build module option,那么package DSC的[Components]所列出来的Module都会被编译。如果build module option有多个,只有最后一个会生效

  • 示例:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xdcruup5-1654854899186)(2.EDK2.assets/image-20220526140527420.png)]

4.5.2 Build Module(-m)

​ 如果一个指定Module需要build,则其必须首先在DSC的 [Components] 中列出。如果没有列出,DSC的所有Module都会被build。如果command line指定指令不止一次,只有最后一个会生效。

  • 示例:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQ6puUsn-1654854899187)(2.EDK2.assets/image-20220526153003934.png)]

4.5.3 Build Arch

​ 支持的ARCH Option有: IA32X64IPFEBC。如果在命令行中指定了不止一次,则每个ARCH会按顺序构建。

  • 示例:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4cnO9hWd-1654854899187)(2.EDK2.assets/image-20220526153247701.png)]

4.5.4 Build Target

​ 支持的Target有:DEBUGRELEASE。如果在命令行上指定多次,则按顺序构建每个Target。

  • 示例:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DObDR2S-1654854899188)(2.EDK2.assets/image-20220526153557072.png)]

4.5.5 Build Tool Tag Name

Tool Tag Name定义在Conf\Tools_def.txt文件中,表示编译器工具链。例如,MYTOOLS是Microsoft VS2005工具链的默认Tool Tag Name。

​ 如果在命令行上指定多次,则会按顺序使用每个工具链。

4.5.6 示例:Build Helloworld

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uqK3tPjY-1654854899188)(2.EDK2.assets/image-20220526163514930.png)]

​ 在build DEBUG文件夹中会创建以下文件:EFI ImageIntermediate FilesAutoGen.hAutoGen.cModule.map 文件

​ EDK II build工具根据所需的Module信息,为每个Module生成AutoGen.h和AutoGen.c文件。其中包括了依赖的pcdGuid值包含Module Entry Point相关的函数

​ 这些AutoGen函数在ModuleEntryPoint库实例中被引用。对于每个Module, Entry Point函数首先调用AutoGen Code,然后进入Module functions。

​ Module.Map是由compiler tool生成的,用于列出该Module中所有函数及其相对地址。它们可用于在运行时定位Module函数地址

  • AutoGen.c如图:

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Axebl0J-1654854899189)(2.EDK2.assets/image-20220526164349173.png)]

  • PcdDxe.map如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WXnpsYQX-1654854899189)(2.EDK2.assets/image-20220526165245436.png)]

4.6 Build EFI Option Rom Image

EFI Option Rom是一个标准的EFI image。EFI image可以通过上述build Module命令编译。与普通Module的不同在于: EFI Option Rom Image INF文件的 [Defines] 中会包含相关的PCI Option。当Module INF文件中设置了PCI Option。这个Module会被编译成EFI和Option Rom Images

​ 在build DEUBG文件下,会出现ModuleName.efiModuleName.rom

  • Option Rom INF示例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ywnOQ6qW-1654854899190)(2.EDK2.assets/image-20220527141245384.png)]

4.6.1 常见build Module报错

在这里插入图片描述
在这里插入图片描述

4.7 Debug Module

​ 在开始Debug Module之前,需要执行以下4个步骤

  • 指令:“Build –b DEBUG”

​ EDK II支持生成DEBUG/RELEASE目标。target.txt中的"BuildTarget"字段与" ToolChain "字段共同生效,以确定编译器tool-chain和build option的实际路径。开发人员可以直接打开

$(WORKSPACE)\Conf\ TARGET .txt并更改“TARGET = DEBUG”作为调试提示。开发人员也可以使用命令行来覆盖该值,例如在调试提示中使用“build -b DEBUG”。

  • 选择合适的DebugLib Library Instance

​ 对于DebugLib库类,MdePkg和IntelFrameworkModulePkg核心包提供了几个库实例。其中包括BaseDebugLibNullBaseDebugLibSerialPort UefiDebugLibConOut,

UefiDebugLibStdErr, PeiDxeDebugLibReportStatusCode。开发人员可以按实际要求在Package的DSC文件中,选择合适的DebugLib库实例。

  • 配置DebugLib使用的Pcds

​ DebugLib library class header定义了两个用于调试库配置的pcd。与debug ability相关的pcd包括PcdDebugPropertyMaskPcdDebugPrintErrorLevel。前者用于控制print/assert,并确定assert宏通过CpuDeadLoop还是通过BreakPoint实现的。对于后者,开发人员可以设置各种值来控制打印或过滤错误信息。

  • Change build option

​ 开发人员可以修改或重写module build option。例如,开发人员可以使用Microsoft 编译器的“/Od”选项来禁用编译器的优化,并避免无序指令。还可以使用Microsoft编译器的“/FAsc”选项来生成一个源代码和汇编(.cod)文件来帮助调试。

4.7.1 基本调试方法

​ 以下是三个基本的调试方法:

  • 使用DEBUG打印语句

​ 在EDK II项目中,有一组PCD,用于开启/关闭DEBUG。开发人员可以在开始调试时打开该功能。

  • CpuDeadLoop()

​ 开发人员可以使用API halt control flow,有助于快速定位问题。

  • Module的 Map file

​ EDK II为每个模块生成一个对应的FV Map文件

​ 开发人员可以根据已加载Module的基址Map File来计算函数的内存地址。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EDK II Module Writers Guide上 的相关文章

  • 应用层通过/sys/class/gpio文件操作gpio口

    1 内核gpio子系统介绍 应用层通过sysfs操作gpio的前提是内核中已经向gpio子系统注册了gpio资源 并且在 sys class 目录下可以看到gpio类 详细情况参考博客 2 6 35内核的gpio子系统详解 2 sys cl
  • OpenGL驱动质量的事实现状(精简翻译版)

    原文 http richg42 blogspot com 2014 05 the truth on opengl driver quality html 一 厂商A 为大多数开发者所使用 功能最全 测试得最好 几乎是事实上的标准驱动 其驱动
  • Linux·i2c驱动示例

    I2C 是很常用的一个串行通信接口 常用于连接各种外设 传感器等器件 一 Linux I2C 驱动框架 Linux 内核将 I2C 驱动分为两部分 I2C 总线驱动 I2C 总线驱动就是 SOC 的 I2C 控制器驱动 也叫做 I2C 适配
  • DDK(Driver Developer Kit)和WDK(Windows Driver Kit)的区别

    首先 先从基础的东西说起 开发WINDOWS下的驱动程序 需要一个专门的开发包 如 开发JAVA程序 我们可能需要一个JDK 开发WINDOWS应用程序 我们需要WINDOWS的SDK 现在开发WINDOWS下的驱动程序 我们需要一个DDK
  • 驱动开发 作业 day9 9/20

    基于platform实现 head h ifndef HEAD H define HEAD H 构建LED开关的功能码 不添加ioctl第三个参数 define LED ON IO l 1 define LED OFF IO l 0 end
  • FPGA学习记录:第28章 VGA显示器驱动设计与验证

    硬件平台 Cyclone IV E EP4CE10F17C8 开发平台 Quartus II 64 Bit Version 13 0 1 Build 232 06 12 2013 SP 1 SJ Full Version 开发板 野火征途p
  • 嵌入式Linux驱动开发(LCD屏幕专题)(四)

    单Buffer的缺点与改进方法 1 单Buffer的缺点 如果APP速度很慢 可以看到它在LCD上缓慢绘制图案 即使APP速度很高 LCD控制器不断从Framebuffer中读取数据来显示 而APP不断把数据写入Framebuffer 假设
  • Robot Framework 自动化测试详解

    一 Robot Framework 简介 1 界面自动化测试工具 界面自动化测试 即UI自动化测试 比较常见的工具有 QTP AutoIt Selenium等 像QTP经历了很多版本 最新的版本好像叫UFT了 对初学者来说 录制回放是相当容
  • Failed to execute /linuxrc. Attempting defaults... 解决方案

    今天想移植个根文件系统 使用的板子是友善之臂的S3C2440 这个很多书上都有介绍 难度倒也不是很大 按照手册一步步的来 移植完之后 烧写到flash里面 发现不能运行 怎么回事 检查了一遍 发现和教材上一样 难道教材有问题 在网上找了移植
  • micropython驱动ST7789v 2.4寸液晶显示中文

    一 ST7789v介绍 ST7789v是小尺寸液晶中常用的驱动芯片 作者手里的是网上买的一块2 4寸液晶模组 接口 为SPI接口 网上能找到这个芯片的micropython驱动 这不是本文的重点 本文的重点是如何利用这个驱动 并使用字库的方
  • fb设备驱动1:fb设备的显像原理和步骤

    lcd的显像原理 将DDR内存的一部分划分出来作为显存 显存与lcd显示屏幕之间做一个双向的映射 然后用户只需要将需要显示的内容放入显存之中 然后显存中的内容就会刷新到lcd的储存器中进行显示 显存 在内核之中申请一块内存作为显存 由于内核
  • 一个主设备号是如何支持多个次设备?

    1 主次设备号 参考博客 字符设备驱动详解 主次设备号 注册 卸载字符设备驱动 创建设备节点 地址映射 2 次设备号介绍 1 在老的驱动程序里是不需要次设备号的 在老版内核中注册驱动用register chrdev 函数 只需要传入主设备号
  • Linux I2C 驱动实验

    一 I2C 驱动 本章同样以 I MX6U ALPHA 开发板上的 AP3216C 这个三合一环境光传感器为例 通过 AP3216C 讲解一下如何编写 Linux 下的 I2C 设备驱动程序 Linux 的驱动分离与分层的思想 因此 Lin
  • inux字符驱动之read、write部分

    本期主题 linux字符驱动之read write部分 往期链接 linux设备驱动中的并发 linux设备驱动中的编译乱序和执行乱序 linux设备驱动之内核模块 linux字符驱动 linux字符驱动之ioctl部分 linux字符驱动
  • 使用 Microchip SAM9X60 OTP 存储板卡的MAC地址和序列号

    1 介绍 SAM9X60 处理器有部分OTP One Time Programming Aera 可用于存储user data 这样的话我们就可以将板卡 MAC Address和 SN 序列号写到固定的OTP User Area中 为什么要
  • OC5228 100V多功能LED恒流驱动器-高辉调光 65536:1 调光比

    同脚位拼对拼替代智芯HI7001 磁吸灯 舞台灯电源方案新贵 概述 OC5228 是一款外围电路简单的多功能平均电流型LED 恒流驱动器 适用于5 100V 电压范围的降压BUCK 大功率调光恒流LED 领域 芯片PWM 端口支持超小占空比
  • STM32 CAN通信理解(是半双工还是全双工?)

    STM32F429 CAN通信 CAN 是控制器局域网络 Controller Area Network 的简称 它是由研发和生产汽车电子产品著称的德国 BOSCH 公司开发的 并最终成为国际标准 ISO11519 是国际上应用最广泛的现场
  • linux应用程序直接return与exit的区别

    在Linux应用程序中 可以使用 return 语句直接从 main 函数返回 这将导致程序终止并返回给操作系统 然而 有时候使用 exit 函数比直接使用 return 语句更有优势 以下是一些原因 清理资源 exit 函数可以确保在程序
  • linux ARM64 处理器内存屏障

    一 内存类型 ARMv8架构将系统中所有的内存 按照它们的特性 划分成两种 即普通内存和设备内存 并且它们是互斥的 也就是说系统中的某段内存要么是普通内存 要么是设备内存 不能都是 1 普通内存 Normal Memory 普通内存的特性是
  • linux ARM64 处理器内存屏障

    一 内存类型 ARMv8架构将系统中所有的内存 按照它们的特性 划分成两种 即普通内存和设备内存 并且它们是互斥的 也就是说系统中的某段内存要么是普通内存 要么是设备内存 不能都是 1 普通内存 Normal Memory 普通内存的特性是

随机推荐

  • 第1章 创建一个html网页

    创建一个html网页 目录标题 1 1认识html 1 2html标签 1 3html文件的基本结构 1 4Chrome的开发者工具 1 5在记事本中编写HTML文件 1 6使用编辑器创建HTML文档 1 6 1下载Hbuilder X 1
  • 位运算符详细解析

    位运算符计算 先把十进制转为二进制 计算完在转回十进制 以下位转换和计算规则 进制和 进制的转换 进制转 进制 标数除以2 若能除尽 该位记做0 若除不尽 该位记做1 再对商继续除以2 以 此类推 直到商为0 然后把每 位的结果反序组合就是
  • ROS语音更改API

    1 准备工作 申请科大讯飞帐号 下载SDK 打开 讯飞官网 创建语音合成需求 下载sdk 其中有libs库 并记录相应的appid 用于后续文件使用 下载的sdk中内容如下 我们将用到libs库中的文件 还需要更改 asr tts 两个文件
  • 【Linux 驱动篇(三)】新字符设备驱动

    文章目录 一 新字符设备驱动原理 1 分配和释放设备号 2 新的字符设备注册方法 2 1 字符设备结构 2 2 cdev init 函数 2 3 cdev add 函数 2 4 cdev del 函数 二 自动创建设备节点 1 mdev 机
  • 从0开始学习JavaScript--初识JavaScript

    一 JavaScript简介 1 JavaScript的起源 avaScript最初由Netscape的Brendan Eich设计 最初将其脚本语言命名为LiveScript 后来Netscape在与Sun合作之后将其改名为JavaScr
  • chatgpt网页版替代方法

    从昨天网上开始一直开着的chatgpt网页突然打不开了 提示1020错误 尝试换了不同代理软件或者代理地点仍然无法解决 也搜了很多资料 比如删除cookie 重启浏览器 更换浏览器等均不起作用 至今仍无法解决 具体错误内容如下 Access
  • 输入yum命令报错:Loaded plugins: fastestmirror You need to be root to perform this command.

    解决方法 是提示要获取root权限 输入su 回车输入密码即可
  • 计算机网络-子网划分(子网地址、广播地址、子网掩码)

    子网划分 题目 办公室内有一台计算机 IP地址为192 45 165 243 子网掩码为255 255 255 224 则该机所在的网络属于哪类网络 其网络是否进行了子网划分 若划分 则分为几个网络 并写出每个子网号 改机的子网号和广播地址
  • LFU算法族:window-LFU

    LFU算法族相关文章目录汇总 LFU算法 LFU Aging算法 window LFU算法 本文 1 LFU算法的不足 LFU Least Frequently Used 是一种缓存淘汰算法 LFU算法是根据缓存的访问频率 去淘汰访问次数最
  • JS程序

    注 题目来源 力扣 给定一个字符串 s 找到 s 中最长的回文子串 你可以假设 s 的最大长度为 1000 示例 1 输入 babad 输出 bab 注意 aba 也是一个有效答案 解题思路 这个题目是直接拍脑袋想法 就是暴力求解 思路是这
  • c++ cin整数以,(逗号)分割读取

    1 某些场景整数流不是空格分割 如用逗号分割 例如 下面的输入 要求每行是一个数组 一共两行测试输入 1 2 3 4 5 6 7 8 下面的代码就可以很好的解决问题 vector
  • C# 系统应用之注册表使用详解

    在平时做项目时 我们有时会遇到注册表的操作 例如前面我们需要获取IE浏览器地址栏的信息 获取 我的电脑 地址栏输入的文件夹信息 USB最近使用信息等 注册表项是注册表的基本组织单位 它包含子表项和值条目 简言之 注册表项相当于注册表里的文件
  • 闭包函数的理解

    function fn return function s console log hello return function s1 console log world var s fn console log s var s1 s con
  • windows上安装openSSH服务

    在windows上cmd 然后ssh 主机用户 主机ip直接连到远程 很方便 如图 那么怎么配置呢 首先windows上需要安装openSSH 1 下载openSSH windows版 注 该版本是64位 链接 https pan baid
  • java casting意思_Java Casting方法,不知道要强制转换为什么

    我今天在玩Java 发现有些奇怪 考虑以下代码 String foo cast hi int bar cast 1 cast 方法在这里 public static lt T gt T cast Object value return T
  • tkinter 动态显示时间的方法

    问题描述 有些小伙伴在使用python做GUI界面的时候可能想添加这么一个小功能 就是在界面的某个角落动态的显示当前的时间 本文将介绍具体方法 方式一 使用组件的after方法 代码如下所示 import time import tkint
  • Vue3之watch和watchEffect实战总结

    watch和watchEffect都是vue3中的监听器 但是在写法和使用上是有区别的 主要是介绍一下watch和watchEffect的使用方法以及他们之间的区别 watch 的工作原理 侦听特定的数据源 并在回调函数中执行副作用 它默认
  • 高分辨率光学遥感影像舰船目标检测与识别算法研究(尹莹莹)

    论文阅读笔记 摘要 本文主要研究海陆背景下的光学遥感图像舰船目标检测与识别技术 重点研究了海陆分离 舰船目标疑似区域检测技术与疑似区域目标识别技术 海陆分离 采用了OTSU与形态学相结合的方法实现海路区域初步划分 再以孤立区域内像素的欧氏距
  • java中jdbc有哪几种形式呢?

    下文笔者讲述java中jdbc的形式简介说明 如下所示 JDBC驱动程序简介 JDBC驱动程序就是数据库厂商根据JDBC规范实现的JDBC实现类 JDBC驱动程序的类型 方式1 通过将JDBC的调用委托给其他编程接口来实现的 这种类型的驱动
  • EDK II Module Writers Guide上

    一 EDK2简介 1 EDK2工作流 二 EDK2 Packages 1 Packages介绍 EDK2 Packages是一个容器 其中包含一组模块及模块的相关定义 每个Package是一个EDK2单元 整个Project的源代码可以被分