【UEFI基础】FDF文件

综述

FDF的全称是Flash Description File。

它是构成BIOS二进制的描述符,即FDF文件描述了BIOS二进制的组成结构。

本文的目的就是介绍FDF文件内部的组成以及它们是如何完成对BIOS二进制的描述。

下面首先来看下BIOS二进制的大致结构:

上述的结构中有几个需要说明关键字,一个是FD(Flash Device binary image),它就是上述的整个大的镜像;一个是FV(Firmware Volumes),它是FD的组成模块,每一个模块有一个特定的功能,比如FVMAIN通常包含的是DXE、BDS阶段的代码,它通常是被压缩过得,FV Recovery包含SEC和PEI阶段的代码,等等;还有一个FFS(Firmware File System),它是FV内部的一个结构,用来表示各个Firmware的组成。

同时FD和FV也是FDF文件中的关键字,后面会继续介绍。

下面是FD创建的一个示意图:

本文主要参考自《edk-ii-fdf-specification.pdf》(以下简称参考文档)。

它可以在EDK II Specifications · tianocore/tianocore.github.io Wiki · GitHub下载到。

本文中使用到的代码示例来自vUDK2017: https://github.com/tianocore/edk2.git Tag vUDK2017.

最后需要注意的一点是,这里只描述编译生成的BIOS二进制,而不是真正可以放到主板上的二进制(它还要保护ME等其它的二进制)。

语法

本节介绍FDF文件的大致语法。

基本语法

先简单介绍一些FDF中使用到的基本语法:

1. 注释使用#;

2. 赋值使用SET,而使用=表示的是TOKEN,是一种特殊的类似与常量的值;

3. 可以使用整型,布尔值,EFI_GUID等值;

4. $()获取DEFINE语句定义的宏的值;

基本语句

SET语句:对PCD进行赋值,如下所示:

SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress            = $(FLASH_AREA_BASE_ADDRESS)
SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize                   = $(FLASH_AREA_SIZE)

DEFINE语句:定义一个宏,如下所示:

DEFINE DEBUG_ENABLE_OUTPUT      = FALSE       # Set to TRUE to enable debug output
DEFINE DEBUG_PRINT_ERROR_LEVEL  = 0x80000040  # Flags to control amount of debug output
DEFINE DEBUG_PROPERTY_MASK      = 0

定义的宏可以通过$()来访问。注意DSC文件中也会使用DEFINE语句,且定义的宏可以在FDF文件中访问。

!if语句:判断语句,为TRUE时才包含其内部的组件,其语法如下:

!if $(MACRO)
或者
!if $(MACRO) == "Literal String"
或者
!if $(MACROALPHA) == $(MACROBETA)
或者
!if $(MACRONUM) == 数字
或者
!if $(MACROBOOL) == 布尔值

注意需要与!endif语句一起使用,中间也可以有!else语句。下面是例子:

!if $(SECURE_BOOT_ENABLE)
  # Signature: gEfiAuthenticatedVariableGuid = { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 } }
  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
!else
  #  Signature: gEfiVariableGuid = { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
  0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
  0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
!endif

其它类似的还有!ifdef语句和!ifndef语句

以上是比较通用的语句,还有一些需要在特定的Section中使用的语句将在之后介绍。

Section

Section的大致格式如下:

[oo.xx.zz]

上述的代码描述中,oo是必选的,而xx、zz等需要根据oo的值来确定是否存在以及具体是什么。

Section是FDF文件中最重要的组件,因为它们将FDF文件分成了若干个部分,各个部分由不同的内容构成,最终组成整个FD。

下面就介绍这些常用的Section关键字。

[Defines]

这部分Section是可选的,里面放置到的东西一般用来放宏定义和变量,下面是一个例子:

[Defines]

DEFINE BLOCK_SIZE        = 0x1000
DEFINE FW_BASE_ADDRESS   = 0xFFF00000
DEFINE FW_SIZE           = 0x00100000

SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress     = $(FW_BASE_ADDRESS)
SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize    = $(FW_SIZE)
SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize = $(BLOCK_SIZE)

[FD]

关于FD这种Section关键字在之前也已经提到,它表示了一个完整的BIOS镜像。

一个FDF文件里面可以有多个FD。

[FD]关键字中的FD之后还可以接一个后缀,格式如下:

[FD.FdUiName]

这里的FdUiName表示FD的名称,可以是随意的值。

当FDF文件中只存在一个[FD] Section的时候,这个FdUiName是可选的,如果不选,则使用定义在[Defines]中的PLATFORM_NAME作为名称。

[FD]中包含若干个TOKEN,它们是几个有特殊意义的变量,如下所示:

BaseAddress:表示FD的基址,它是设备开机之后BIOS被加载到系统中的位置;

Size:表示FD的大小,单位是字节;

ErasePolarity:表示的是用1还是0擦Flash,目前基本上都是1;

BlockSize:表示Flash中一个Block的大小,一般就是4K,64K等;

NumBlocks:表示Flash中Block的个数,通常就是Size除以BlockSize;

[FD]中另外包含的一个重要的内容是FD的布局,它的结构如下:

Offset|Size
[TokenSpaceGuidCName.PcdOffsetCName | TokenSpaceGuidCName.PcdSizeCName] ?
[RegionType] ?

该定义在FD中开辟了一段空间,用来放置某些内容,比如FV之类的。

OffsetSize是这段空间的对于整个FD的偏移和大小;

Pcd是可选的,其实就是初始化了PCD来表示这段空间偏移和大小供后续使用,并不是必须的,它更像是C语言中的宏,你只需要设置一次,就可以在FDF文件的各处使用;

RegionType表示这段空间的类型,可以是FV、DATA、FILE、INF和CAPSULE等内容,也不是必须的,如果没用定义则表示这段空间不能去动它,它是有其它用处的,会有其它的机制(比如非易失日志)用到;

下面是一个例子:

[FD.OVMF_CODE]
BaseAddress   = $(CODE_BASE_ADDRESS)
Size          = $(CODE_SIZE)
ErasePolarity = 1
BlockSize     = $(BLOCK_SIZE)
NumBlocks     = $(CODE_BLOCKS)

0x00000000|$(FVMAIN_SIZE)
FV = FVMAIN_COMPACT

$(FVMAIN_SIZE)|$(SECFV_SIZE)
FV = SECFV

################################################################################

[FD.MEMFD]
BaseAddress   = $(MEMFD_BASE_ADDRESS)
Size          = 0xB00000
ErasePolarity = 1
BlockSize     = 0x10000
NumBlocks     = 0xB0

0x000000|0x006000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize

0x006000|0x001000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize

上面的例子中使用了FV这个RegionType,这里再详细说明下所有的RegionType:

FV:使用的格式如下:

FV = UiFvName

这里的UiFvName是在[FV]这个Section中定义的。

DATA:使用的格式如下:

DATA = {xx}

xx可以是16进制的字节数组,下面是一个例子:

0x0058e000|0x00002000
gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
#NV_FTW_WORKING
DATA = {
  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =
  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
  0xE2, 0x33, 0xF2, 0x03, 0xFE, 0xFF, 0xFF, 0xFF,
  # WriteQueueSize: UINT64
  0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

xx还可以是一个!include语句,用来包含外部的数据,下面是一个例子:

0x0CA000 | 0x002000
gEfiMyTokenSpaceGuid.PcdFlashNvStorageBase | gEfiMyTokenSpaceGuid.PcdFlashNvStorageSiz
e
DATA = {
  !include NvStoreInit.txt
}

FILE:它指向一个二进制文件,生成FD的之后这个二进制文件就会被包含进来,使用格式如下:

FILE = $(FILE_DIR)/Filename.bin

下面是一个例子:

0x00000000|0x00000200
FILE = BeagleBoardPkg/ConfigurationHeader.bin

CAPSULE:使用的格式如下:

CAPSULE = UiCapsuleName

其中的UiCapsuleName是[Capsule] Section的名称。

INF:[FD]中还可以直接包含INF文件,格式如下:

INF [Options] PathAndInfFileName

INF定义在该处并不是完整的,它的类型还需要在其它地方定义。

关于直接放在[FD]中的INF的意义目前不是很清楚。

这里的Options会在[FV]章节介绍。

除了上述的内容,[FD]中也是可以包含DEFINE和SET设置的宏和变量。

[FV]

FV的主要作用就是包含组件和模块,它的格式如下:

[FV.UiFvName]

UiFvName是自定义的名称,在FD中会用到,它在文件中必须是唯一的。

FV是可以嵌套的,FV中也可以通过UiFvName来包含另外一个FV。

下面介绍[FV] Section中包含的内容:

[FV]的最开始是几个TOKEN,如下是一个例子:

[FV.STAGE1A]
  BlockSize          = $(FLASH_BLOCK_SIZE)
  FvAlignment        = 16
  ERASE_POLARITY     = 1
  MEMORY_MAPPED      = TRUE
  STICKY_WRITE       = TRUE
  LOCK_CAP           = TRUE
  LOCK_STATUS        = TRUE
  WRITE_DISABLED_CAP = TRUE
  WRITE_ENABLED_CAP  = TRUE
  WRITE_STATUS       = TRUE
  WRITE_LOCK_CAP     = TRUE
  WRITE_LOCK_STATUS  = TRUE
  READ_DISABLED_CAP  = TRUE
  READ_ENABLED_CAP   = TRUE
  READ_STATUS        = TRUE
  READ_LOCK_CAP      = TRUE
  READ_LOCK_STATUS   = TRUE

其次[FV]中也可以使用DEFINE和SET来定义宏和变量。

再其次,对于并非实际使用到Flash上的BIOS,还需要设置BLOCK_SIZE和NUM_BLOCKS,这些这边不关注。

然后介绍[FV] Section中最基本的元素INF语句,其格式如下:

INF [Options] PathAndInfFileName

其中PathAndInfFileName就是一个普通的inf文件,Options是可选项,主要有以下的一些:

RuleOverride = RuleName

表示当前INF的RULE,关于RULE,之后会在[Rule] Section中说明,RuleName是该Seciton的名称。每一个[FV]中的inf都有一个默认的RULE,这里就是覆盖默认的RULE,而使用这里提供的RULE。

USE = ARCH

表示该INF对应的架构,这个用的不多。

VERSION = "String"

该选项会在FFS中创建一个EFI_SECTION_VERSION Section。

UI = "String"

与VERSION类似,会创建一个EFI_SECTION_USER_INTERFACE Section。

与INF相关的一个元素是APRIORI语句,它指定了INF的执行顺序,下面是一个例子:

APRIORI DXE {
  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
!if $(SMM_REQUIRE) == FALSE
  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
!endif
}

[FV]中可以直接包含文件,使用的是FILE语句,格式如下:

FILE Type = $(NAMED_GUID) [Options] FileName
或者
FILE Type = $(NAMED_GUID) [Options] {
SECTION SECTION_TYPE = FileName
SECTION SECTION_TYPE = FileName
}

文件有很多的类型(Type),之类介绍常用的:

RAW:普通的二进制;

FREEFORM:有EDK支持的分区的二进制;

FV_IMAGE:这就这里介绍的[FV];

DRIVER:包含一个DXE阶段的驱动;

等等。

NAMED_GUID是表示这个文件的唯一的标记,我们可以在代码中通过这个GUID获取文件。

Options有如下可用的值:Fixed、Alignment和Checksum等,这里不一一介绍。

下面是FILE语句的例子:

FILE FREEFORM    = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
  SECTION RAW = MdeModulePkg/Logo/Logo.bmp
}
FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
  SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI
}

从上述的例子中可以看到FILE语句下还可以包含SECTION语句,它表示了对指定文件的封装,关于SECTION语句的格式已经在前面介绍过,但是并完全,SECTION语句有很多不同的格式,这里不一一介绍,可以参考《edk-ii-fdf-specification.pdf》。

[Capsule]

CAPSULE是一个可选的Section,它的作用不太好描述,这里直接贴上参考文档上的说明:

[Capsule]的格式如下:

[Capsule.UiCapsuleName]

其中的UiCapsuleName可以是任意的名称。

[Capsule]最开始包含的是几个TOKEN:

CAPSULE_GUID:用来标记这个CAPSULE;

CAPSULE_FLAGS:目前有三个Flag,分别是PersistAcrossReset、InitiateReset和PopulateSystemTable,具体的意义参考文档上没有说明。

[Capsule]里面也可以有SET语句,INF语句和FILE语句,与之前的语法一致。

[Rule]

这个Section用来描述FFS文件的构成,FFS文件就是通过INF文件编译得到,然后组成二进制,而组成如何的二进制,就是通过[Rule]来构成的。[Rule]的格式如下:

[Rule.ARCH.MODULE_TYPE.TEMPLATE_NAME]

下面是几个例子:


[Rule.Common.SEC]
  FILE SEC = $(NAMED_GUID) {
    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
    UI       STRING ="$(MODULE_NAME)" Optional
    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
  }

[Rule.Common.PEI_CORE]
  FILE PEI_CORE = $(NAMED_GUID) {
    PE32     PE32   Align=Auto    $(INF_OUTPUT)/$(MODULE_NAME).efi
    UI       STRING ="$(MODULE_NAME)" Optional
    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
  }

[Rule.Common.PEIM]
  FILE PEIM = $(NAMED_GUID) {
     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
     PE32      PE32   Align=Auto         $(INF_OUTPUT)/$(MODULE_NAME).efi
     UI       STRING="$(MODULE_NAME)" Optional
     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
  }

其内部是一个FILE语句,它跟之前在FV中使用的FILE语句结构是一样的。

此外还有[VTF]、[OptionRom]等Section,因为用的不多,这里不再介绍。

随着国家十四五新战略规划的推出,众多国内企业都参与到国产芯片替代浪潮中来,可以预测未来越多的国产芯片会被设计、生产和使用在我们日常所使用的电子产品中,国产芯片拥有巨大的市场前景。 目前国产芯片采用的体系架构主要有X86、ARM、MIPS、RISC V、PowerPC、Alpha等。我们知道电子产品正常工作必须要有操作系统和各种应用软件,没有操作系统和应用软件的芯片就是一堆废铁,而大多数人并不知道的是没有系统固件来加载操作系统的电脑亦是一堆废铁, UEFI就是由UEFI行业协会提出和维护一种行业标准的系统固件,它支持目前市面上的大多数芯片体系结构和操作系统,随着标准的不断演进相信越来越多的体系结构的芯片和操作系统会被支持。 笔者从事BIOS开发已有十余年的时间,见证了Legacy BIOS辉煌与隐退,也有幸了参与了新世纪初系统固件从Legacy BIOS往UEFI BIOS的迁移的全过程。科技行业风起云涌新技术新架构日新月异,每每回望不禁感慨我辈可谓是“眼见着他起高楼,眼见着他宴宾客”的那一波BIOS人。曾经系统固件江湖还是Legacy BIOS的天下,BIOS人使用汇编语言编码、通过中断来与操作系统沟通。自UEFI框架被广泛使以来开我们的发环境从纯汇编变成了99%的C语言加1%的汇编语言的模式,开发效率大大的加强了。 虽然UEFI框架大大加快了开发效率,但是由于系统固件开发属于比较偏门和专业的领域,学习和入门门槛比较高,现有的BIOS工程师又分布在大大小小的各个公司内部缺乏有效沟通和交流,同时BIOS源码又属于敏感和机密数据受到各种NDA限制,市面上对UEFI框架介绍的资料少之又少,因此笔者从2000左右开始就陆续以Cstyle_0x007为ID在https://blog.csdn.net/CStyle_0x007发布一系列博文,现已有数十篇原创文章。刚开始的想法是把博文当作工作笔记方便自己随时查阅,后来慢慢发展成了与业内外感兴趣的朋友的沟通交流的平台。 随手写的博文难免有错误与纰漏为了避免误导大众,准备把博文重新整理在纠正谬误同时也会补充一些新的内容,尽量做到所写的每句话都是无误的,也欢迎有兴趣的朋友踊跃提出意见和建议。组建了微信公众号,目的在于方便有兴趣的朋友一起交流,名字初步定为“固件C字营”,其中“固件”泛指一切固化的软件,这里主要指UEFI BIOS系统固件,“C”泛指“China“,我们可以把这里当作大家沟通交流的营地,我们会不定时发布一些行业资讯、工作、学习心得,感兴趣扫描下面二维码就可以加入,也可以发邮件到CstyleFirmWareCamp@outlook.com投稿分享你的想法。 本文取名《UEFI内核的导读》这里的UEFI专指“UEFI BIOS”,全文专注于对UEFI内核的梳理与分享,同时兼顾对X86系统固件生态中常用的工程技术的介绍,主要包含以下内容:UEFI启动流程以及各个阶段主要完成的任务及参考的实现方式导读UEFI及PI规范中的常见Protocol的实现与使用技巧UEFI固件生态中常见外设、总线、行业标准的协议内容及使用方法 雄关漫道真如铁,而今迈步从头越,系统固件雄起之路道阻且长,相信我们的BIOS人一定可以为国产芯片的起飞助力、为系统固件团队的壮大贡献自己的一份微薄之力,为每一个不畏艰难、不惧寂寞坚守在工作岗位的BIOS人加油,好样的。
<think>好的,我现在要帮助用户了解UEFI开发环境中DEC、DSC、FDF文件的作用。首先,我需要回忆一下这些文件的基本功能和它们之间的关系。根据用户提供的引用内容,特别是引用[1]、[2]、[3],这些文件分别有不同的用途。 DEC文件(模块声明文件)应该是用来定义包(Package)的,包含模块所需的库、头文件路径和宏定义。我记得引用[1]提到DEC文件中的[Defines]块可以定义宏,供其他文件使用。比如,DEFINE和EDK_GLOBAL的宏可以在DSC和FDF文件中通过$(宏变量名)调用。所以DEC的作用是集中管理包的元数据和依赖关系,方便其他文件引用。 接下来是DSC文件(平台描述文件),根据引用[1]和[3],DSC文件用于配置整个平台的编译参数,包括模块列表、库依赖、编译选项等。它可能类似于项目的配置文件,指定哪些模块需要被编译,以及编译时的参数设置。例如,在DSC文件中可以定义不同的组件,并引用DEC文件中定义的宏变量。 然后是FDF文件(固件设备描述文件),根据引用[2]和[3],FDF文件描述固件在Flash中的布局,包含FD(固件设备)、FV(固件卷)和Option ROM的组成。FDF文件定义了镜像的具体内容和结构,比如各个模块在Flash中的位置,如何分区等。例如,引用[2]提到FDF文件中的fd基址、大小等信息,以及包含的组件和模块。 我需要确认这些文件之间的协作关系。DEC提供包级别的定义,DSC配置整个平台的编译选项和模块,而FDF则处理最终的固件布局和生成。用户可能想知道它们各自的具体职责,以及如何协同工作来构建UEFI固件。 用户可能还想了解这些文件在实际开发中的使用场景。例如,当添加一个新驱动时,需要在DEC中声明头文件路径,在DSC中添加模块,并在FDF中指定其位置。这样整个构建过程才能正确包含和定位该驱动。 另外,需要注意用户提供的引用中提到的宏变量使用方式,如$(宏变量名),这在DEC、DSC、FDF文件中都可能出现,但定义的位置不同。例如,DEC中定义的宏可以在DSC和FDF中使用,而DSC中定义的宏可能仅限于该文件或相关文件。 需要确保回答结构清晰,分点说明每个文件的作用,并举例说明它们的实际应用。同时,根据用户要求生成相关问题,可能需要围绕文件关系、实际配置步骤、常见问题等方面提问。 最后,检查是否符合系统级指令:使用中文,正确使用行内公式格式(虽然当前内容可能较少涉及数学公式,但如果有变量或路径名,可能需要用$包裹),独立公式不需要,引用标注正确,生成相关问题等。</think>### UEFI开发环境中DEC/DSC/FDF文件的作用及关系 #### 1. **DEC文件(模块声明文件)** - **作用**:定义**包(Package)**的元数据,包括: - 包名称、GUID、版本等基本信息 - 公开的头文件路径(`[Includes]`块) - 依赖的其他包(`[Packages]`块) - 可全局使用的宏变量(`[Defines]`块)[^1] - **示例**: ```conf [Defines] DEC_SPECIFICATION = 0x0001001C PACKAGE_NAME = MyPackage PACKAGE_GUID = 12345678-1234-5678-1234-567812345678 [Includes] Include # 声明头文件目录 ``` - **意义**:为模块提供**可复用性支持**,其他模块通过引用DEC文件访问其资源。 #### 2. **DSC文件(平台描述文件)** - **作用**:描述**整个平台的编译配置**,包括: - 目标处理器架构(如`X64`、`IA32`) - 需要编译的模块列表(`[Components]`块) - 库依赖关系(`[LibraryClasses]`块) - 编译选项(`[BuildOptions]`块) - 引用DEC文件中定义的宏(如`$(MY_MACRO)`)[^1] - **示例**: ```conf [Components] MyPackage/DriverA.inf # 指定需要编译的模块 [LibraryClasses] UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf ``` - **意义**:作为**构建系统的入口文件**,指导如何编译平台固件。 #### 3. **FDF文件(固件设备描述文件)** - **作用**:定义**固件镜像的物理布局**,包括: - 固件设备(`FD`)的基地址和大小 - 固件卷(`FV`)的分区结构(如`FV_MAIN`存放UEFI驱动) - 模块在Flash中的具体位置(通过`INF`语句指定)[^2][^3] - **示例**: ```conf [FD.MyFirmware] BaseAddress = 0x00000000 # Flash基址 Size = 0x00200000 # 2MB大小 [FV.FV_MAIN] INF MyPackage/DriverA.inf # 将DriverA放入此分区 ``` - **意义**:控制固件的**存储布局**,确保各组件在Flash中正确部署。 #### 4. **协作关系** - **DEC → DSC**:DSC通过`!include MyPackage.dec`引用DEC文件中的宏和头文件。 - **DSC → FDF**:FDF通过`INF`语句调用DSC中定义的模块路径。 - **宏变量传递**:DEC中定义的宏可在DSC/FDF中通过`$(MACRO)`使用[^1]。 #### 5. **实际应用场景** - **添加新驱动**: 1. 在DEC文件中声明驱动头文件路径 2. 在DSC的`[Components]`添加驱动INF文件 3. 在FDF的对应FV分区中插入驱动二进制
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值