ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【UEFI实战】SlimBootloader定制化

2021-11-27 17:02:55  阅读:238  来源: 互联网

标签:PlatformId CFG CfgData SlimBootloader yaml UEFI 定制 include DATA


综述

SBL的一个特性是Customizable,它分为构建前和构建后的定制化。

SBL有两种配置数据,分别是内部配置数据和外部配置数据。内部配置数据是代码写死的默认数据,当获取不到外部数据的时候就使用这个默认数据;外部配置数据通过预定义文件和配置工具生成。

SBL中的预定义文件和配置工具包括:

  • YAML文件:它定义配置;
  • DLT(delta,表示的其实是变量数据)文件:Override数据,用来覆盖YAML文件中的配置;
  • 配置操作工具:通常是Python脚本。

YAML文件

YAML文件中包含了内存、Silicon、GPIO、启动策略、安全配置等等。

YAML文件通常包含在特定单板目录下,比如ApolloLake平台:

在这里插入图片描述

还有一些通用的YAML文件在Platform\CommonBoardPkg\CfgData目录中:

在这里插入图片描述

其中平台需要的配置文件入口是CfgDataDef.yaml,其它的配置文件都作为它的子文件包含在CfgDataDef.yaml中。比如Platform\ApollolakeBoardPkg\CfgData\CfgDataDef.yaml:

## @file
#
#  Slim Bootloader CFGDATA Default File.
#
#  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

variable:
  COND_GPIO_SKIP                 : ($GPIO_CFG_DATA.$(1)_Half0.GpioSkip == 0)
  COND_GPIO_PID_ENABLE           : ($PID_GPIO_CFG_DATA.$(1).Enable==1) and ($PLATFORMID_CFG_DATA.PlatformId==0)
  COND_PCIE_RP_PWR_PIN_SKIP      : ($PCIE_RP_CFG_DATA.PcieRpPower$(1).Skip == 0)
  COND_PCIE_RP_RST_PIN_SKIP      : ($PCIE_RP_CFG_DATA.PcieRpReset$(1).Skip == 0)
  COND_PCIE_RP_EN                : ($PCIE_RP_CFG_DATA.PcieRpFeatures$(1).En == 1)
  COND_PCIE_RP_CLK_REQ_SUP       : (($PCIE_RP_CFG_DATA.PcieRpFeatures$(1).ClkReqSup == 1) and ($PCIE_RP_CFG_DATA.PcieRpFeatures$(1).En == 1))
  COND_HDA_EN                    : ($HDA_CFG_DATA.HdaEnable == 1)
  COND_HDA_DSP_EN                : (($HDA_CFG_DATA.HdaEnable == 1) and ($HDA_CFG_DATA.DspEnable == 1))

template:

  - !include Template_CfgData.yaml

configs:
  - $ACTION      :
      page         : PLT::"Platform", MEM::"Memory Settings", SIL::"Silicon Settings", GEN::"General Settings", GIO::"Gpio Settings", OS::"OS Boot Options"
  - Signature    :
      length       : 0x04
      value        : {'CFGD'}
  - HeaderLength :
      length       : 0x01
      value        : 0x10
  - Reserved     :
      length       : 0x03
      value        : {0,0,0}
  - UsedLength   :
      length       : 0x04
      value        : _LENGTH_
  - TotalLength  :
      length       : 0x04
      value        : 0x2000

  - !include Platform/CommonBoardPkg/CfgData/CfgData_Platform.yaml

  - $ACTION      :
      page         : IOCUART:PLT:"IOC Uart Settings"
  - $ACTION      :
      page         : IOCUART
  - IOC_UART_CFG_DATA :
    - !expand { CFGHDR_TMPL : [ IOC_UART_CFG_DATA, 0x120, 0, 0 ] }
    - DeviceIndex  :
        name         : Device Index
        type         : Combo
        option       : 0:UART0, 1:UART1, 2:UART2, 3:UART3, 0xF:Disable
        help         : >
                       UART device index for IOC interface (0..3 or Disable)
        length       : 0x01
        value        : 0xF
    - BaudRate     :
        name         : Baud Rate
        type         : Combo
        option       : 0:9600, 1:19200, 2:38400, 3:57600, 4:115200, 5:921600, 6:1.5M
        help         : >
                       UART Baud Rate
        length       : 0x01
        value        : 0
    - Retries      :
        name         : Retries
        type         : EditNum, HEX, (0x00,0xFF)
        help         : >
                       specify retry count
        length       : 0x01
        value        : 0
    - TimeoutInitial :
        name         : TimeoutInitial
        type         : EditNum, HEX, (0x00,0xFF)
        help         : >
                       initial/setup time-out (in milliseconds)
        length       : 0x01
        value        : 0
    - TimeoutXmit  :
        name         : TimeoutXmit
        type         : EditNum, HEX, (0x00,0xFF)
        help         : >
                       transmission time-out
        length       : 0x01
        value        : 0
    - Rsvd         :
        length       : 0x03
        value        : 0

  - $ACTION      :
      page         : PSEL:PLT:"Payload Selection GPIO"
  - $ACTION      :
      page         : PSEL
  - PLATFORM_CFG_DATA :
    - !expand { CFGHDR_TMPL : [ PLATFORM_CFG_DATA, 0x280, 0, 0 ] }
    - PayloadSelGpio :
      - $STRUCT      :
          name         : GPIO pin for switching payload
          struct       : PAYLOAD_SEL_GPIO_PIN
          length       : 0x04
          value        : 0x000000c5
      - PadInfo      :
          name         : Pin Number
          type         : Combo
          option       : !include CfgData_GpioPinOption.yaml
          condition    : ($PLATFORM_CFG_DATA.PayloadSelGpio.Enable > 0)
          help         : >
                         Specify GPIO Pin Number
          length       : 24b
      - Rsvd1        :
          name         : Reserved
          type         : Reserved
          length       : 7b
      - Enable       :
          name         : Payload Selection Pin Enable
          type         : Combo
          option       : $EN_DIS
          help         : >
                         Enable/Disable this pin for payload selection.
          order        : 0000.0000
          length       : 1b

  - !include CfgData_Memory.yaml
  - !include CfgData_Silicon.yaml
  - !include CfgData_Usb.yaml
  - !include CfgData_Gpio.yaml
  - !include Platform/CommonBoardPkg/CfgData/CfgData_Common.yaml
  - !include CfgData_BootOption.yaml
  - !include CfgData_PidGpioPins.yaml
  - !include CfgData_PcieRp.yaml
  - !include CfgData_GpuConfig.yaml
  - !include CfgData_Features.yaml
  - !include CfgData_DeviceEnable.yaml
  - !include CfgData_Hda.yaml
  - !include CfgData_CapsuleInformation.yaml

可以看到包含很多的include命令,指定了内存、Silicon、USB、GPIO等等YAML文件。

DLT文件

DLT文件中的数据是用来覆盖YAML文件中的配置的。

DLT文件包含一个PlatformId,比如Platform\ApollolakeBoardPkg\CfgData\CfgData_Ext_Up2.dlt中:

#
# Delta configuration values for platform ID 0x000E
#
PLATFORMID_CFG_DATA.PlatformId           | 0x000E

一个平台中的DLT文件可以有多个,每个都对应一个PlatformId,并最终和一个特定的单板匹配。如果PlatformId等于0,表示对于所有的单板都适用,相当于改了YAML文件本身。这些DLT文件对应到BoardConfig.py中:

self._CFGDATA_EXT_FILE = ['CfgData_Ext_Gpmrb.dlt', 'CfgData_Ext_Up2.dlt','CfgData_Ext_OxbHill.dlt','CfgData_Ext_MB3.dlt','CfgData_Ext_JuniperHill.dlt']

如果需要增加单板,通常不会直接修改YAML文件,而是增加DLT文件并修改配置来覆盖原有配置,并将DLT文件增加到上述的列表中。

顺便再说明下PlatformId,Intel的CRB单板中指定了若干个GPIO管脚,通过硬件配置死的方式来指定特定单板,这样代码中就可以通过读取GPIO的值来确定PlatformId。对应ApolloLake平台,相关的代码可以在Platform\ApollolakeBoardPkg\Library\Stage1BBoardInitLib\Stage1BBoardInitLib.c中看到:

/**
  Detect board and configure PlatformID.

  @retval  EFI_SUCCESS     Configuration data was loaded successfully.
  @retval  Others          Failed to get configuration data blob.
**/
EFI_STATUS
EFIAPI
PlatformIdInitialize (
  IN  VOID
  )
{
  UINT16     PlatformId;

  PlatformId = (UINT16)GetBoardIdFromGpioPins ();

  if (PlatformId != 0xFF) {
    PlatformId += 0x10; // Customer board identified, assign Platform Ids from 16 to 31
  } else {
    PlatformId = (UINT16)GetEmbeddedBoardId ();
    //Platform ID from GPIOs are read as 0 for Juniper hills due to GPIO pins
    //on the board reduced from 4 to 3 (hardware change) hence translating here
    //in the code.
    if (PlatformId == 0){
        DEBUG ((DEBUG_INFO, "GPIO returned platformID 0 translating to 8(JNH)\n"));
        PlatformId = 0x8;
    }
    if ((PlatformId != PLATFORM_ID_OXH) && (PlatformId != PLATFORM_ID_LFH) && (PlatformId != PLATFORM_ID_JNH)) {
      PlatformId = (UINT16)GetIVIBoardId ();
      if (PlatformId != PLATFORM_ID_GPMRB) {
        DEBUG ((DEBUG_ERROR, "BOARD NOT SUPPORTED: 0x%04X\n", PlatformId));
        CpuDeadLoop ();
      }
    }
  }

  SetPlatformId (PlatformId);
  return EFI_SUCCESS;
}

配置工具

配置工具处理YAML和DLT文件的方式大致就是下面这个样子(注意二进制本身同时可以作为输入和输出):

在这里插入图片描述

所以本节就介绍配置工具,它位于BootloaderCorePkg/Tools目录下。最重要的是ConfigEditor.py,它是一个图形工具,打开之后如下所示:

在这里插入图片描述

点击“File”,第一次只能选择“Open Config YAML file…“:

在这里插入图片描述

这里可以选择前面提到的CfgDataDef.yaml,即基础配置文件。在这之后就可以选择“Load Config Changes from Delta File”,这样新加入的DLT文件会覆盖原本的显示,之后可以继续修改,并最终保存修改之后的数据,这样的数据可以是只包含修改部分的DLT文件,也可以是覆盖所有配置的DLT文件,或者直接生成二进制文件。

除了ConfigEditor.py,还有配置工具是用来将YAML文件转换成头文件Platform\XXXPkg\Include\ConfigDataStruct.h的,它会被包含到SBL代码中,通过代码来最终获取配置并使用。

最终配置工具的使用流程就像如下图所示的一样:

在这里插入图片描述

总的来说,SBL的配置就是YAML文件定义基础配置,DLT文件根据实际单板修改配置,最终生成二进制配置文件,这个二进制配置文件会被放到SBL二进制中供后续获取。在SBL代码中,会判断当前的PlatformId,并加载需要的二进制配置文件,来完成最终的配置。

最后,即使生成了SBL二进制,也还是可以通过工具修改其参数,这就是构建后自定义。

标签:PlatformId,CFG,CfgData,SlimBootloader,yaml,UEFI,定制,include,DATA
来源: https://blog.csdn.net/jiangwei0512/article/details/121579739

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有