UEFI开发与调试---edk2中的Package

在开始编写UEFI APP之前,我们需要先对UEFI包和模块的概念有个了解。

在edk2的根目录下,我们可以发现有很多*Pkg命令的目录,这些实际上都是各个不同的包,每个包中都是一组模块的集合,每个包中都有对应的描述文件(.dsc),声明文件(.dec)。当然如果这个包是用来生成固件Image或者Option Rom Image,那么这个包还需要包含一个.fdf文件(Flash Description File),此文件是用来生成固件Image,Option Rom Image或者可启动Image的。

包的编译过程包括:

  • build 命令利用.dsc和.dec以及一个或者多个.inf文件来编译Package

  • GenFW 命令用来生成固件,利用.dec和.fdf文件来生成一个目标Image

描述文件(.dsc)

.dsc文件用于编译Package,它包含了[Defines],[LibraryClasses],[Components]几个必须部分以及[PCD],[BuildOptions]等可选部分。

  • [Defines]
    定义用于描述该包的全局变量,它必须是dsc文件的第一个描述项目,必须定义的宏变量如下:

    [Defines]
    PLATFORM_NAME                  = Ovmf
    PLATFORM_GUID                  = 5a9e7754-d81b-49ea-85ad-69eaa7b1539b
    PLATFORM_VERSION               = 0.1
    DSC_SPECIFICATION              = 0x00010005
    SUPPORTED_ARCHITECTURES        = X64
    BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
    SKUID_IDENTIFIER               = DEFAULT

    当然也有可选择定义的宏,如下列出两个常用的:

    OUTPUT_DIRECTORY               = Build/OvmfX64
    FLASH_DEFINITION               = OvmfPkg/OvmfPkgX64.fdf
    ......
    
  • [LibraryClasses]
    该块中定义引用的Library,格式需要指定库的名字已经对应的.inf路径,这里定义的Library,可以被包中所有的Components所引用。

    [LibraryClasses]
    
    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
    
    TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
    
    PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
    
    BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
    
    BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
    
    SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
    

    如上所示,Library的定义需要name和.inf文件路径,并且中间以一个|符号分割开。也可以通过[LibraryClasses.$(ARCH).$(MODULE_TYPE)]来区分不同的Arch和Module Type。

  • [Components]
    列出本包中所有的模块组件,各个模块是通过指定对应的.inf文件来加入到包中的:

    [Components]
    OvmfPkg/ResetVector/ResetVector.inf
    
    
    # SEC Phase modules
    
    OvmfPkg/Sec/SecMain.inf {
     <LibraryClasses>
       NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
    }
    
    
    # PEI Phase modules
    
    MdeModulePkg/Core/Pei/PeiMain.inf
    MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
     <LibraryClasses>
       PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
    }
    MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf {
     <LibraryClasses>
       PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
    }

    如上所示,除了能够指定对应的模块inf文件,还可以通过{}来包含该模块的一些私有属性,比如在{}中定义的,这里的库是仅给父模块引用的,对包中其他的模块没有影响,而.dsc中定义的[LibraryClasses]块,则整个包中的模块都可以引用,如果模块私有引用了相同库名,但不同路径下的库,那么会覆盖公共区定义的引用。

  • [BuildOptions]
    定义编译选项,此处定义的编译选项对该包中的所有模块都有效,格式如下:

    [BuildOptions.$(Arch).$(CodeBase)]
    [编译器]:[$(Target)]_[Tool]_[$(Arch)]_[CC|DLINK]_FLAGS=
    

    实例:

    [BuildOptions]
    GCC:*_UNIXGCC_*_CC_FLAGS             = -DMDEPKG_NDEBUG
    GCC:RELEASE_*_*_CC_FLAGS             = -DMDEPKG_NDEBUG
    INTEL:RELEASE_*_*_CC_FLAGS           = /D MDEPKG_NDEBUG
    MSFT:RELEASE_*_*_CC_FLAGS            = /D MDEPKG_NDEBUG
    
  • PCD Section
    用于定义平台配置数据,其中定义的变量是可以直接被源程序通过接口获取到,其目的是在不改动.inf文件和源文件的情况下完成对平台的配置。这样就达到灵活配置平台选项,不用为了兼容不同平台而去修改代码,[PcdsFeatureFlag],[PcdsFixedAtBuild], [PcdsDynamicDefault]这三个都属于PCD Section的可选部分。

声明文件(.dec)

声明文件用来定义公开的数据和接口,供其他模块使用,包含必需块[Defines]以及可选块[Includes],[LibraryClasses],[Guids],[Protocols],[Ppis],[PCD]。.dec文件需要被调用模块.inf文件所包含。

  • [Defines]
    提供包的名字,版本号,GUID:

    [Defines]
    DEC_SPECIFICATION              = 0x00010005
    PACKAGE_NAME                   = OvmfPkg
    PACKAGE_GUID                   = 2daf5f34-50e5-4b9d-b8e3-5562334d87e5
    PACKAGE_VERSION                = 0.1
  • [Includes]
    头文件所在目录,起始于.dec所在目录的相对目录:

    [Includes]
    Include
    
  • [LibraryClasses]
    该包对外提供的库的集合,格式为:库名 | 头文件

    [LibraryClasses]
    LoadLinuxLib|Include/Library/LoadLinuxLib.h
  • [Guids]
    在Package/Include/Guid目录中有很多文件,每个文件内定义了一个或者多个GUID,例如OvmfPkg/Include/Guid/OvmfPlatformConfig.h头文件中:

    extern EFI_GUID gOvmfPlatformConfigGuid;

    可以看到这里仅仅是一个声明,那么它的定义就是在本块中完成的:

    [Guids]
    gOvmfPlatformConfigGuid      = {0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}
  • [Protocols]
    和Guids配置方法类似,在Package/Include/Protocols目录定义了Protocol的头文件,比如头文件/OvmfPkg/Include/Protocol/VirtioDevice.h:

    extern EFI_GUID gVirtioDeviceProtocolGuid;

    头文件仅仅是声明,定义在dec文件中:

    [Protocols]
    gVirtioDeviceProtocolGuid           = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}
  • [Ppis]
    定义源文件中用到的PPI(PEI模块之间通信的接口),语法类似Protocols。

  • [PCD]
    此块是对dsc文件中[PCD]块的补充。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值