目录
前言
在下面这篇文章中,笔者谈到了EDK II 的架构:
【EDK II】作为UEFI的实现,EDK II 的架构是什么样的-CSDN博客https://blog.csdn.net/qq_36914987/article/details/136612087?spm=1001.2014.3001.5501知道了EDK II的架构可以简单描述为Package、Module、PCD机制的形式。那么,本文就对Package做一个简单介绍。相信读了本文,读者应该会对Package有更深的了解。
Package
关于 EDK II 的 Package,需要了解以下知识点:
- 理解 Package 的概念、架构、配置。
- 如何添加、编写 Package?
- 如何编译 Package?
Package也就是包,什么是包?通常,EDK II 的包具备以下特点:
- 最小的发布单元(distribution),也就是说各个包之间相对独立,可以单独设计某一个包,比如EmulatorPkg。
- 包含零个或多个模块(modules)。
- 包含一个包声明文件(.dec),以及可能包含一个平台描述文件(.dsc)。
- 一个包里面的模块可能依赖于其它包。
通常,一个典型的Package包含以下内容:
Include # 包依赖的头文件
Library # 包依赖的库
Application1, Application2 # 模块
...
*.dec # 包声明文件
*.dsc # 包描述文件
*.uni # 以下文件的作用可先不作了解
*.yaml
*.inc
下面以 EDK II 中最基本的一个Package为例,来简单介绍Package的结构。
MdePkg,即 Module Development Environment Package,是 EDK II 提供的一个模块开发环境包,其它的包基本上需要依赖MdePkg。MdePkg的目录结构如下,包括Include、Library、Test 和一些配置文件。这里的Test也是一种Appliction,用于测试MdePkg。
关于 MdePkg中的*.inc\*.yaml\*.uni,本文暂不介绍,读者只需知道,这几个文件不是一个Package所必须的配置。后面有时间,笔者会将这部分内容补齐。
咱们重点来谈DEC和DSC文件。
DEC
DEC: Package Declaration File,定义了一个包的公开信息。DEC的结构采用 [Section]的方式进行定义,如下:
[Defines]
[Includes]
[LibraryClasses]
[Guids]
[Ppis]
[Protocols]
[Pcds]
[UserExtensions]
- [Defines]: 定义了DEC文档遵循的规范版本、包的名字,GUID(Globally Unique Identifier,一种128位的数字标识符 ),和其它属性。
- [Includes] : 包依赖的头文件路径,也可以指定特定架构所依赖的头文件路径。
- [LibraryClasses] : 为Include/Library 目录下的.h文件创建一个LibraeyClass变量,变量名和.h文件名相同。
- [Guids : 为Include/Guid目录下的每一个.h文件创建一个Guid。
- [Ppis] : 为Include/Ppi目录下的每一个.h文件创建一个Ppi Guid。
- [Protocols] :为Include/Protocol目录下的每一个.h文件创建一个Protocol Guid。
- Pcds : UEFI为了灵活的配置,引入了PCD机制。Pcd为平台配置数据库创建很多entry。每个entry都有一个类型(FeatureFlag、FixedAtBuild、PatchableInModule、Dynamic、DynamicEx)和值,方便进行平台的配置管理。
- [UserExtensions]: 用于开发者自行扩展的地方。
DSC
DSC: Platform Description File,描述编译该 Platform (也就是Package) 所依赖的一些定义和驱动,包括:
[Defines]
[LibraryClasses]
[Components]
[PcdFixedAtBuild,PcdXXX]
[BuildOptions]
- [Defines] : 定义平台的名字、GUID、版本、DSC文档遵循的规范版本、编译后的输出目录、编译支持的平台架构等等。
- [LibraryClasses] : 为平台编译所需的模块(.inf)创建映射,注意DEC里面的[LibraryClasses]映射的是.h文件。
- [PcdsXXX] : 确定全局或默认PCD的类型和值,比如类型是FeatureFlag的PCD,其值只能是TRUE/FALSE。
- [Components] : 包含一系列 EDK/ EDK II 模块。另外,也可指定IA32/X64架构的特定模块,即[Components.IA32, Components.X64]
[components] 里的.inf还可以嵌套LibraryClasses?
- BuildOptions : 定义模块特定的工具链flag,可以为空。
以上就是Package部分的讲解。
编译
那如何编译某个Package 呢?以EmulatorPkg为例,编译一个Package,大致需要以下几个步骤:
- 搭建EDK II 编译环境,这个可以参考:Getting Started with EDK II · tianocore/tianocore.github.io Wiki · GitHubhttps://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II
配置好后,命令行执行: edksetup.bat Rebuild, 便会设置整个EDK II 的编译环境。
- 配置Conf里面的target.txt, tool_def.txt
ACTIVE_PLATFORM = EmulatorPkg/EmulatorPkg.dsc ## 配置当前编译的有效平台,通过指定*.dsc文件实现(.dsc描述了具体某个平台的内容)
TARGET = DEBUG ## 模式,DEBUG/RELEASE
TARGET_ARCH = X64 ## 目标平台的架构,比如IA32,X64
TOOL_CHAIN_TAG = VS2019 ## 指定编译用到的编译器,比如VS2019
- build,这里可以带参数,覆盖掉target.txt的设置,若无参数,则默认使用target.txt中的配置。
build -p EmulatorPkg\EmulatorPkg.dsc -a X64 -D DEBUG
其中,-p 参数指定编译的有效平台,也就是package,-a参数用于指定目标平台的架构,-D参数用于选择DEBUG/RELEASE模式。
编译成功后,会在Build的对应子目录下生成相应的FD文件,也就是二进制文件。
以上就是 EDK II Package 的大致内容,主要对Package的结构、配置、编译进行了简要介绍,后面笔者会继续讲解Package里面某个Module的相关内容。比如
- 如何编写Module?
- Moduel里面的配置文件是什么?
- 如何只编译某个Package里面的指定Module?
好了,本文的分享就到这里,喜欢的朋友可以点赞关注,及时获取笔者最新的分享内容,谢谢~