UEFI中的edk2编译流程_edk2代码走读

为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。

本份面试集锦涵盖了

  • 174 道运维工程师面试题
  • 128道k8s面试题
  • 108道shell脚本面试题
  • 200道Linux面试题
  • 51道docker面试题
  • 35道Jenkis面试题
  • 78道MongoDB面试题
  • 17道ansible面试题
  • 60道dubbo面试题
  • 53道kafka面试
  • 18道mysql面试题
  • 40道nginx面试题
  • 77道redis面试题
  • 28道zookeeper

总计 1000+ 道面试题, 内容 又全含金量又高

  • 174道运维工程师面试题

1、什么是运维?

2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

3、现在给你三百台服务器,你怎么对他们进行管理?

4、简述raid0 raid1raid5二种工作模式的工作原理及特点

5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

7、Tomcat和Resin有什么区别,工作中你怎么选择?

8、什么是中间件?什么是jdk?

9、讲述一下Tomcat8005、8009、8080三个端口的含义?

10、什么叫CDN?

11、什么叫网站灰度发布?

12、简述DNS进行域名解析的过程?

13、RabbitMQ是什么东西?

14、讲一下Keepalived的工作原理?

15、讲述一下LVS三种模式的工作过程?

16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

17、如何重置mysql root密码?

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

在UEFI(统一可扩展固件接口)中,“section”(节)是一个术语,通常指的是可执行二进制文件(例如.efi文件)中的逻辑分块或段。每个节包含了特定类型的数据或代码,用于实现特定的功能。这些节被组合在一起构成一个完整的可执行文件。

一个EFI可执行文件(例如.efi文件)通常包含多个节,每个节有其特定的功能和数据。以下是一些常见的EFI可执行文件中可能包含的节:

  1. 代码节(Code Section):这些节包含可执行代码,用于执行特定的任务。例如,一个EFI引导加载程序的代码节包含引导加载程序的实际执行代码。

  2. 数据节(Data Section):这些节包含各种数据,如全局变量、常量数据等。数据节可以存储用于在程序执行过程中读取或修改的数据。

  3. 引导信息节(Boot Information Section):这些节包含关于EFI映像的元数据和信息,如映像的版本、作者、创建日期等。这些信息通常不是必需的,但可以用于描述EFI映像的属性。

  4. 调试信息节(Debug Information Section):这些节包含用于调试的信息,例如源代码行号和变量名的映射。调试信息节对于开发人员在调试EFI映像时非常有用。

  5. 导出节(Export Section):这些节包含了EFI映像提供给其他EFI模块或应用程序使用的接口信息。这些接口可以被其他模块引用,以实现模块间的通信和交互。

这些节的组合构成了一个完整的EFI可执行文件。每个节都有其自己的特定用途,它们共同协作以实现EFI应用程序或驱动程序的功能。EFI标准规定了EFI可执行文件的格式和节的结构,以确保它们在UEFI环境中能够正确加载和执行。所以,“section” 是EFI可执行文件中的逻辑组成部分,用于实现不同的功能。

Section

Section有很多种类型,但是总的来说其实就两种:封装节(En)、叶子节(Ln),而一个固件文件中的Section分布可以如下图,可以既有封装节,也可以有叶子节,而封装节类似于父节,它可以包含作为子节的封装节与叶子节。

VTF

卷顶文件(VTF)是必须定位的文件,该文件的最后一个字节也是固件卷的最后一个字节。VTF的文件名GUID为EFI_FFS_VOLUME_TOP_FILE_GUID,固件文件系统驱动程序代码必须知道这个GUID,并根据需要插入一个pad文件,以保证在写入和更新操作时VTF正确地位于固件卷的顶部。文件长度和对齐要求必须与卷顶一致。否则,写错误,不修改固件卷。

FDF

FDF文件用于描述固件在flash中的布局和位置,这些固件是与UEFI兼容的二进制镜像,一般来说,生成固件的源码中只有一个FDF文件,其作用是规定把哪些包编入flash中,并确定编入的位置,FDF文件由[Defines]、[FD]、[FV]、[Capsule]、[VTF]、[Rule]、[OptionRom]组成。下面以edk2下的EmulatorPkg下的EmulatorPkg.fdf文件为例。

[FD]

定义:在FDF(Firmware Description File)中,[FD] 部分用于描述固件设备(Firmware Device)的参数和配置

参数:

  1. BaseAddress = 0x102000000|gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress:这里指定了 FD 的基地址。基地址是 FD 在内存中的起始物理地址。在这个示例中,基地址被设置为 0x102000000,并且还引用了一个 PCD(Platform Configuration Database)标记 gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress,该标记可能用于在不同的构建配置中动态设置基地址。
  2. Size = 0x005a0000|gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize:这是指定 FD 的大小。大小表示 FD 占用的字节数。在这个示例中,大小被设置为 0x005a0000,并且也引用了一个 PCD 标记 gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize,用于可能的动态配置。
  3. ErasePolarity = 1:这是关于擦除极性的设置,指定了在擦除闪存区域时设置或擦除位的方式。在这里,它被设置为 1。
  4. BlockSize = 0x10000:这是指定 FD 的块大小,块是闪存区域的基本擦除单元。在这个示例中,块大小被设置为 0x10000,表示每个块的大小为 64KB。
  5. NumBlocks = 0x5a:这是指定 FD 中块的数量。在这个示例中,块的数量被设置为 0x5a,表示 FD 中有 90 个块。
[FD.Fv_Recovery]
#
# In OS X PEIMs are really XIP, so we need to make this address match the malloced
# buffer for the FD (0x41000000). If this address does not match the FV will get
# relocated in place (works, but not a great idea).
#
BaseAddress   = 0x102000000|gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress   #The base address of the FLASH Device.
Size          = 0x005a0000|gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize  #The size in bytes of the FLASH Device
ErasePolarity = 1
BlockSize     = 0x10000
NumBlocks     = 0x5a

0x00000000|0x00580000
gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize
FV = FvRecovery

0x00580000|0x0000c000
gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
#NV_VARIABLE_STORE
DATA = {
  ## This is the EFI_FIRMWARE_VOLUME_HEADER
  # ZeroVector []
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
  #  { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
  # FvLength: 0x20000
  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
  # Signature "_FVH"       #Attributes
  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
  # HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
  0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
  # Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
  # Blockmap[1]: End
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  ## This is the VARIABLE_STORE_HEADER
!if $(SECURE_BOOT_ENABLE) == FALSE
  #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,
!else
  # 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,
!endif
  #Size: 0xc000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xBFB8
  # This can speed up the Variable Dispatch a bit.
  0xB8, 0xBF, 0x00, 0x00,
  #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

0x0058c000|0x00002000
#NV_EVENT_LOG
gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize

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
}

0x00590000|0x00010000
#NV_FTW_SPARE
gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
[FV]

定义:在FDF(Firmware Description File)中,[FV] 部分用于描述固件卷(Firmware Volume)的参数和配置。

参数:

  1. FvNameGuid = 6D99E806-3D38-42c2-A095-5F4300BFD7DC:这里指定了 FV 的名称或标识符,使用 GUID(全局唯一标识符)来唯一标识 FV。
  2. FvAlignment = 16:这是 FV 的对齐方式,它指定 FV 在内存中的对齐要求。在这个示例中,FV 被要求以 16 字节的边界对齐。
  3. ERASE_POLARITY = 1:这是擦除极性的设置,它通常用于描述如何在擦除闪存区域时设置或擦除位。在这里,它被设置为 1。
  4. MEMORY_MAPPED = TRUE:这指定了 FV 是否是内存映射型的。如果设置为 TRUE,表示 FV 是通过内存映射方式访问的。
  5. STICKY_WRITE = TRUE:这表示是否启用了“粘性写入”特性。粘性写入通常用于描述写入数据后是否会自动保留在闪存中。
  6. LOCK_CAP = TRUELOCK_STATUS = TRUE:这些参数描述了是否支持闪存区域的锁定功能以及锁定状态。如果 LOCK_CAP 设置为 TRUE,表示支持锁定;LOCK_STATUS 设置为 TRUE,则表示锁定状态已经处于启用状态。
  7. WRITE_DISABLED_CAP = TRUEWRITE_ENABLED_CAP = TRUEWRITE_STATUS = TRUEWRITE_LOCK_CAP = TRUEWRITE_LOCK_STATUS = TRUE:这些参数描述了闪存区域的写入功能,包括是否支持写入禁用和启用,以及写入状态和写入锁定的能力和状态。
  8. READ_DISABLED_CAP = TRUEREAD_ENABLED_CAP = TRUEREAD_STATUS = TRUEREAD_LOCK_CAP = TRUEREAD_LOCK_STATUS = TRUE:类似于写入功能,这些参数描述了闪存区域的读取功能,包括是否支持读取禁用和启用,以及读取状态和读取锁定的能力和状态。
[FV.FvRecovery]
FvNameGuid         = 6D99E806-3D38-42c2-A095-5F4300BFD7DC
FvAlignment        = 16         #FV alignment and FV attributes setting.
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

#
#  PEI Phase modules
#

#
#  PEI Apriori file example, more PEIM module added later.
#
APRIORI PEI {
  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
  INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
  }
APRIORI DXE {
  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
  INF  MdeModulePkg/Universal/Metronome/Metronome.inf
  }
INF  EmulatorPkg/Sec/Sec.inf
INF  MdeModulePkg/Core/Pei/PeiMain.inf
INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
INF  EmulatorPkg/BootModePei/BootModePei.inf
INF  EmulatorPkg/AutoScanPei/AutoScanPei.inf
INF  EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
INF  EmulatorPkg/FlashMapPei/FlashMapPei.inf
INF  EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf
INF  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
INF  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf

#
#  DXE Phase modules
#
INF  MdeModulePkg/Core/Dxe/DxeMain.inf
INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
INF  MdeModulePkg/Universal/Metronome/Metronome.inf
INF  EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf
INF  EmulatorPkg/ResetRuntimeDxe/Reset.inf
INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
INF  EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
INF  EmulatorPkg/EmuThunkDxe/EmuThunk.inf
INF  EmulatorPkg/CpuRuntimeDxe/Cpu.inf
INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
INF  EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
INF  EmulatorPkg/TimerDxe/Timer.inf
INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf

INF  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf

INF  EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
INF  EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
INF  EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
INF  EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
INF  EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf

INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
!if "XCODE5" not in $(TOOL_CHAIN_TAG)
INF  MdeModulePkg/Logo/LogoDxe.inf
!endif
INF  MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf
INF  RuleOverride = UI MdeModulePkg/Application/UiApp/UiApp.inf
INF  MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
INF  MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf

#
# Secure Boot Key Enroll
#
!if $(SECURE_BOOT_ENABLE) == TRUE
INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
!endif

#
# Network stack drivers
#
!if $(NETWORK_SUPPORT)
INF  EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
!endif
!include NetworkPkg/Network.fdf.inc

#
# EFI Redfish drivers
#
!include RedfishPkg/Redfish.fdf.inc

INF FatPkg/EnhancedFatDxe/Fat.inf

!if "XCODE5" not in $(TOOL_CHAIN_TAG)
INF  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
!endif
INF  ShellPkg/Application/Shell/Shell.inf

更详细的 【UEFI基础】FDF文件_uefi fdf 文件_jiangwei0512的博客-CSDN博客

Build实践

通过在edk2下直接执行build命令,观察终端打印的信息。

对打印信息进行截取并分析,可以观察到和前面提到的Build过程大致吻合,对应了之前的Pre-build阶段和Build阶段,最终生成了一个uefi应用程序(.efi文件)。

"gcc-ar" cr /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/BaseLib.lib  @/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/object_files.lst
"gcc" -MMD -MF /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/AutoGen.obj.deps -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -c -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/./AutoGen.obj -I/home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main -I/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG -I/home/luying/uefi_workspace/edk2/MdePkg -I/home/luying/uefi_workspace/edk2/MdePkg/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/UnitTest/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/Mock/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Library/MipiSysTLib/mipisyst/library/include -I/home/luying/uefi_workspace/edk2/MdePkg/Include/X64 -I/home/luying/uefi_workspace/edk2/MdeModulePkg -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Include -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Test/Mock/Include /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/AutoGen.c
"gcc" -MMD -MF /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.obj.deps -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -c -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/./Uefi_Main_ly.obj -I/home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main -I/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG -I/home/luying/uefi_workspace/edk2/MdePkg -I/home/luying/uefi_workspace/edk2/MdePkg/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/UnitTest/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/Mock/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Library/MipiSysTLib/mipisyst/library/include -I/home/luying/uefi_workspace/edk2/MdePkg/Include/X64 -I/home/luying/uefi_workspace/edk2/MdeModulePkg -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Include -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Test/Mock/Include /home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly.c
rm -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.lib
"gcc-ar" cr /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.lib  @/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/object_files.lst
"gcc" -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 -Wl,--entry,_ModuleEntryPoint -u _ModuleEntryPoint -Wl,-Map,/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.map,--whole-archive -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -flto -Os -Wl,--start-group,@/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/static_library_files.lst,--end-group -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 -Wl,--script=/home/luying/uefi_workspace/edk2/BaseTools/Scripts/GccBase.lds -Wno-error
"objcopy"  /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll
cp -p -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.debug
"objcopy" --strip-unneeded -R .eh_frame /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll
"objcopy" --add-gnu-debuglink="/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.debug" /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll
cp -p -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.debug /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/Uefi_Main_ly.debug
"GenFw" -e UEFI_APPLICATION -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.efi /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll
cp -p -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.efi /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG
cp -p -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.efi /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/Uefi_Main_ly.efi
cp -p -f /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/*.map /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT
#这个命令的作用是使用 gcc-ar 工具创建一个名为 BaseLib.lib 的静态库文件,
#该库文件将包含列表中 object_files.lst 中列出的目标文件。
#静态库文件通常用于将多个目标文件打包到一个单独的库中,
#以便在链接时将它们链接到应用程序中。
"gcc-ar" cr /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/BaseLib.lib  @/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/MdePkg/Library/BaseLib/BaseLib/OUTPUT/object_files.lst
#将AutoGen.c编译为AutoGen.obj
"gcc" -MMD -MF /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/AutoGen.obj.deps -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -c -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/./AutoGen.obj -I/home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main -I/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG -I/home/luying/uefi_workspace/edk2/MdePkg -I/home/luying/uefi_workspace/edk2/MdePkg/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/UnitTest/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/Mock/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Library/MipiSysTLib/mipisyst/library/include -I/home/luying/uefi_workspace/edk2/MdePkg/Include/X64 -I/home/luying/uefi_workspace/edk2/MdeModulePkg -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Include -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Test/Mock/Include /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/AutoGen.c
#将Uefi_Main.c编译为Uefi_Main.obj
"gcc" -MMD -MF /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.obj.deps -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -c -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/./Uefi_Main_ly.obj -I/home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main -I/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG -I/home/luying/uefi_workspace/edk2/MdePkg -I/home/luying/uefi_workspace/edk2/MdePkg/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/UnitTest/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Test/Mock/Include -I/home/luying/uefi_workspace/edk2/MdePkg/Library/MipiSysTLib/mipisyst/library/include -I/home/luying/uefi_workspace/edk2/MdePkg/Include/X64 -I/home/luying/uefi_workspace/edk2/MdeModulePkg -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Include -I/home/luying/uefi_workspace/edk2/MdeModulePkg/Test/Mock/Include /home/luying/uefi_workspace/edk2/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly.c
#生成静态链接库
"gcc-ar" cr /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.lib  @/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/object_files.lst
#生成动态链接库
"gcc" -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll -nostdlib -Wl,-n,-q,--gc-sections -z common-page-size=0x40 -Wl,--entry,_ModuleEntryPoint -u _ModuleEntryPoint -Wl,-Map,/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.map,--whole-archive -Wl,-melf_x86_64,--oformat=elf64-x86-64,-pie -flto -Os -Wl,--start-group,@/home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/static_library_files.lst,--end-group -g -Os -fshort-wchar -fno-builtin -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -include AutoGen.h -fno-common -ffunction-sections -fdata-sections -DSTRING_ARRAY_NAME=Uefi_Main_lyStrings -m64 -fno-stack-protector "-DEFIAPI=__attribute__((ms_abi))" -maccumulate-outgoing-args -mno-red-zone -Wno-address -mcmodel=small -fpie -fno-asynchronous-unwind-tables -Wno-address -fno-omit-frame-pointer -flto -DUSING_LTO -nostdinc -nostdlib -DUEFI_C_SOURCE -Wl,--defsym=PECOFF_HEADER_SIZE=0x228 -Wl,--script=/home/luying/uefi_workspace/edk2/BaseTools/Scripts/GccBase.lds -Wno-error
#利用GenFw生成efi文件
"GenFw" -e UEFI_APPLICATION -o /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/OUTPUT/Uefi_Main_ly.efi /home/luying/uefi_workspace/edk2/Build/lywhPkg/DEBUG_GCC5/X64/lywhPkg/Applications/Uefi_Main/Uefi_Main_ly/DEBUG/Uefi_Main_ly.dll

Build源码

通常UEFI的编译包括以下三个步骤:

make -C BaseTools
. edksetup.sh
build -t CompilerName -A Arch -p PkgName 

1、其中make -C BaseTools编译BaseTools下的工具包

2、而edksetup.sh是准备工作的核心,主要做的工作有设定工作目录,设定环境变量,设定工作目录和环境变量以及文件运行的入口,获取运行参数并按需执行。

3、build,开始编译

根据build打印在终端的信息去查找,发现来自于build.py文件,整个实现流程如下

针对其中build类的注释可以看到该类实现build的流程

1、从工作区路径下的Conf文件内的target.txt与tools_def.txt加载配置项

2、解析dsc文件

3、解析FDF文件

4、建立build数据库,解析其他文件例如module和package

5、生成AutoGen文件、依赖文件、makefile文件

6、唤起build命令

## The class implementing the EDK2 build process
#
#   The build process includes:
#       1. Load configuration from target.txt and tools_def.txt in $(WORKSPACE)/Conf
#       2. Parse DSC file of active platform
#       3. Parse FDF file if any
#       4. Establish build database, including parse all other files (module, package)
#       5. Create AutoGen files (C code file, depex file, makefile) if necessary
#       6. Call build command
#
class Build():
    def __init__(self, Target, WorkspaceDir, BuildOptions,log_q):
    def StartAutoGen(self,mqueue, DataPipe,SkipAutoGen,PcdMaList,cqueue):
    def GetToolChainAndFamilyFromDsc (self, File):
    def LoadConfiguration(self):
    def InitBuild(self):
    def InitPreBuild(self):
    def InitPostBuild(self):
    def PassCommandOption(self, BuildTarget, TargetArch, ToolChain, PlatformFile, Target):
    def LaunchPrebuild(self):
    def LaunchPostbuild(self):
    def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand=None, PcdMaList=None):
    def _Build(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False):
    def _RebaseModule (self, MapBuffer, BaseAddress, ModuleList, AddrIsOffset = True, ModeIsSmm = False):
    def _CollectFvMapBuffer (self, MapBuffer, Wa, ModuleList):
    def _CollectModuleMapBuffer (self, MapBuffer, ModuleList):
    def _SaveMapFile (self, MapBuffer, Wa):
    def _BuildPlatform(self):
    def _BuildModule(self):
    def _GenFfsCmd(self,ArchList):
    def VerifyAutoGenFiles(self):
    def SetupMakeSetting(self,Wa):
    def PerformAutoGen(self,BuildTarget,ToolChain):
    def _MultiThreadBuildPlatform(self):
    def GetFreeSizeThreshold(self):
    def CheckFreeSizeThreshold(self, Threshold=None, FvDir=None):
    def CreateGuidedSectionToolsFile(self,Wa):
    def GetRealPathOfTool (self, tool):
    def Launch(self):
    def CreateAsBuiltInf(self):
    def GenDestCache(self):
    def GenLocalPreMakeCache(self):
    def Relinquish(self):

Build源码下的构建平台整体执行流程如下,若构建模块,则_BuildPlatform改为_BuildModule且不需要调用_Buildpa.

Main()->MyBuild->Build->__init__->...                                  #让MyBuild=Build来实例化一个Build类,对Build类进行初始化,设定及检验用于build的环境,包括加载target.txt中的编译器,dsc文件中的描述等,用于生成最终的编译规则.
->MyBuild.Launch->_BuildPlatform->WorkspaceAutoGen->PlatformAutoGen    #调用Build类下的Launch函数启动,随后调用_BuildPlatform通过解析FDF文件和INF文件,生成相应的C代码(宏变量)和Makefile(编译规则)
->_BuildPa->_GenFfsCmd                                                 #在_BuildPlatform函数内调用编译_BuildPa模块
->_CollectModuleMapBuffer                                              #根据PCD修改EFI的内存分布,并获取modules的内存分布,用于重定位modules,链接生成最终的FD文件
->_Build                                                               #编译模块
->_CollectFvMapBuffer                                                  #获取重定位FV的信息

__init__

它用于初始化一个名为 \_Build 的类的实例。以下是代码中的主要初始化步骤和属性设置:

  1. 初始化工作目录和构建目标等基本属性:
       - WorkspaceDir:设置工作目录,通常是项目的根目录。
       - Target:设置构建目标。
       - PlatformFile:设置平台文件。
       - ModuleFile:设置模块文件。
       - ArchList:设置目标架构列表。
       - ToolChainList:设置工具链列表。
       - BuildTargetList:设置构建目标列表。
       - Fdf:设置 Flash 文件系统描述文件。
       - FdList:设置 ROM 映像列表。
       - FvList:设置 FV 映像列表。
       - CapList:设置能力名(Capability)列表。
       - SilentMode:设置是否启用静默模式。
       - ThreadNumber:设置线程数量。
       - SkipAutoGen:设置是否跳过自动生成。
       - Reparse:设置是否重新解析。
       - SkuId:设置 SKU ID。
       - ConfDirectory:设置配置目录。
       - SpawnMode:设置是否启用 Spawn 模式。
       - BuildReport:设置构建报告。
       - AutoGenTime:初始化自动生成时间。
       - MakeTime:初始化 Make 时间。
       - GenFdsTime:初始化生成 FDS 时间。
       - MakeFileName:初始化 Make 文件名。
       - UniFlag:设置构建标志。
       - BuildModules:初始化构建模块列表。
       - HashSkipModules:初始化哈希跳过模块列表。
       - Db\_Flag:初始化 BuildDB 标志。
       - LaunchPrebuildFlag:初始化启动预构建标志。
       - PlatformBuildPath:设置平台构建路径。
       - log\_q:初始化日志队列。

  2. 设置全局构建选项和标志:
       - 根据构建选项,设置全局构建选项,如 gIgnoreSourcegUseHashCachegBinCacheDestgBinCacheSourcegEnableGenfdsMultiThreadgDisableIncludePathCheck 等。

  3. 验证构建选项:
       - 检查是否启用二进制缓存,并根据情况检查是否使用哈希缓存,同时检查二进制源缓存与二进制目标缓存的组合是否合法。

  4. 设置二进制缓存路径:
       - 根据全局构建选项设置二进制缓存的源路径(gBinCacheSource)和目标路径(gBinCacheDest)。

  5. 初始化构建数据库(BuildDB)。

  6. 初始化其他属性:
       - Platform:初始化平台对象为 None
       - ToolChainFamily:初始化工具链家族为 None
       - LoadFixAddress:初始化加载固定地址为 0
       - BuildModules:初始化构建模块列表为空。
       - HashSkipModules:初始化哈希跳过模块列表为空。
       - Db\_Flag:初始化构建数据库标志为 False
       - LaunchPrebuildFlag:初始化启动预构建标志为 False
       - PlatformBuildPath:设置平台构建路径。
       - log\_q:设置日志队列。

  7. 初始化构建进度器(Progressor)以便在构建过程中显示进度信息。

  8. 打印构建环境和配置信息。

  9. 初始化预构建(Prebuild)和后构建(Postbuild)。

  10. 如果启用了预构建,执行预构建操作。

  11. 初始化构建过程。

  12. 初始化各种缓存和状态信息。

最终,\_\_init\_\_ 函数对类的各种属性进行了初始化,准备了构建过程所需的环境和配置信息。这些属性将在后续的构建过程中使用。

def __init__(self, Target, WorkspaceDir, BuildOptions,log_q):
        self.WorkspaceDir   = WorkspaceDir
        self.Target         = Target
        self.PlatformFile   = BuildOptions.PlatformFile
        self.ModuleFile     = BuildOptions.ModuleFile
        self.ArchList       = BuildOptions.TargetArch
        self.ToolChainList  = BuildOptions.ToolChain
        self.BuildTargetList= BuildOptions.BuildTarget
        self.Fdf            = BuildOptions.FdfFile
        self.FdList         = BuildOptions.RomImage
        self.FvList         = BuildOptions.FvImage
        self.CapList        = BuildOptions.CapName
        self.SilentMode     = BuildOptions.SilentMode
        self.ThreadNumber   = 1
        self.SkipAutoGen    = BuildOptions.SkipAutoGen
        self.Reparse        = BuildOptions.Reparse
        self.SkuId          = BuildOptions.SkuId
        if self.SkuId:
            GlobalData.gSKUID_CMD = self.SkuId
        self.ConfDirectory = BuildOptions.ConfDirectory
        self.SpawnMode      = True
        self.BuildReport    = BuildReport(BuildOptions.ReportFile, BuildOptions.ReportType)
        self.AutoGenTime    = 0
        self.MakeTime       = 0
        self.GenFdsTime     = 0
        self.MakeFileName   = ""
        TargetObj = TargetTxtDict()
        ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"),"Conf")))
        self.TargetTxt = TargetObj.Target
        self.ToolDef = ToolDefObj.ToolDef
        GlobalData.BuildOptionPcd     = BuildOptions.OptionPcd if BuildOptions.OptionPcd else []
        #Set global flag for build mode
        GlobalData.gIgnoreSource = BuildOptions.IgnoreSources
        GlobalData.gUseHashCache = BuildOptions.UseHashCache
        GlobalData.gBinCacheDest   = BuildOptions.BinCacheDest
        GlobalData.gBinCacheSource = BuildOptions.BinCacheSource
        GlobalData.gEnableGenfdsMultiThread = not BuildOptions.NoGenfdsMultiThread
        GlobalData.gDisableIncludePathCheck = BuildOptions.DisableIncludePathCheck

        if GlobalData.gBinCacheDest and not GlobalData.gUseHashCache:
            EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination must be used together with --hash.")

        if GlobalData.gBinCacheSource and not GlobalData.gUseHashCache:
            EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-source must be used together with --hash.")

        if GlobalData.gBinCacheDest and GlobalData.gBinCacheSource:
            EdkLogger.error("build", OPTION_NOT_SUPPORTED, ExtraData="--binary-destination can not be used together with --binary-source.")

        if GlobalData.gBinCacheSource:
            BinCacheSource = os.path.normpath(GlobalData.gBinCacheSource)
            if not os.path.isabs(BinCacheSource):
                BinCacheSource = mws.join(self.WorkspaceDir, BinCacheSource)
            GlobalData.gBinCacheSource = BinCacheSource
        else:
            if GlobalData.gBinCacheSource is not None:
                EdkLogger.error("build", OPTION_VALUE_INVALID, ExtraData="Invalid value of option --binary-source.")

        if GlobalData.gBinCacheDest:
            BinCacheDest = os.path.normpath(GlobalData.gBinCacheDest)
            if not os.path.isabs(BinCacheDest):
                BinCacheDest = mws.join(self.WorkspaceDir, BinCacheDest)
            GlobalData.gBinCacheDest = BinCacheDest
        else:
            if GlobalData.gBinCacheDest is not None:
                EdkLogger.error("build", OPTION_VALUE_INVALID, ExtraData="Invalid value of option --binary-destination.")

        GlobalData.gDatabasePath = os.path.normpath(os.path.join(GlobalData.gConfDirectory, GlobalData.gDatabasePath))
        if not os.path.exists(os.path.join(GlobalData.gConfDirectory, '.cache')):
            os.makedirs(os.path.join(GlobalData.gConfDirectory, '.cache'))
        self.Db = BuildDB
        self.BuildDatabase = self.Db.BuildObject
        self.Platform = None
        self.ToolChainFamily = None
        self.LoadFixAddress = 0
        self.UniFlag        = BuildOptions.Flag
        self.BuildModules = []
        self.HashSkipModules = []
        self.Db_Flag = False
        self.LaunchPrebuildFlag = False
        self.PlatformBuildPath = os.path.join(GlobalData.gConfDirectory, '.cache', '.PlatformBuild')
        if BuildOptions.CommandLength:
            GlobalData.gCommandMaxLength = BuildOptions.CommandLength

        # print dot character during doing some time-consuming work
        self.Progress = Utils.Progressor()
        # print current build environment and configuration
        EdkLogger.quiet("%-16s = %s" % ("WORKSPACE", os.environ["WORKSPACE"]))
        if "PACKAGES_PATH" in os.environ:
            # WORKSPACE env has been converted before. Print the same path style with WORKSPACE env.
            EdkLogger.quiet("%-16s = %s" % ("PACKAGES_PATH", os.path.normcase(os.path.normpath(os.environ["PACKAGES_PATH"]))))
        EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_PATH", os.environ["EDK_TOOLS_PATH"]))
        if "EDK_TOOLS_BIN" in os.environ:
            # Print the same path style with WORKSPACE env.
            EdkLogger.quiet("%-16s = %s" % ("EDK_TOOLS_BIN", os.path.normcase(os.path.normpath(os.environ["EDK_TOOLS_BIN"]))))
        EdkLogger.quiet("%-16s = %s" % ("CONF_PATH", GlobalData.gConfDirectory))
        if "PYTHON3_ENABLE" in os.environ:
            PYTHON3_ENABLE = os.environ["PYTHON3_ENABLE"]
            if PYTHON3_ENABLE != "TRUE":
                PYTHON3_ENABLE = "FALSE"
            EdkLogger.quiet("%-16s = %s" % ("PYTHON3_ENABLE", PYTHON3_ENABLE))
        if "PYTHON_COMMAND" in os.environ:
            EdkLogger.quiet("%-16s = %s" % ("PYTHON_COMMAND", os.environ["PYTHON_COMMAND"]))
        self.InitPreBuild()
        self.InitPostBuild()
        if self.Prebuild:
            EdkLogger.quiet("%-16s = %s" % ("PREBUILD", self.Prebuild))
        if self.Postbuild:
            EdkLogger.quiet("%-16s = %s" % ("POSTBUILD", self.Postbuild))
        if self.Prebuild:
            self.LaunchPrebuild()
            TargetObj = TargetTxtDict()
            ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
            self.TargetTxt = TargetObj.Target
            self.ToolDef = ToolDefObj.ToolDef
        if not (self.LaunchPrebuildFlag and os.path.exists(self.PlatformBuildPath)):
            self.InitBuild()

        self.AutoGenMgr = None
        EdkLogger.info("")
        os.chdir(self.WorkspaceDir)
        self.log_q = log_q
        GlobalData.file_lock =  mp.Lock()
        # Init cache data for local only
        GlobalData.gPackageHashFile = dict()
        GlobalData.gModulePreMakeCacheStatus = dict()
        GlobalData.gModuleMakeCacheStatus = dict()
        GlobalData.gHashChainStatus = dict()
        GlobalData.gCMakeHashFile = dict()
        GlobalData.gModuleHashFile = dict()
        GlobalData.gFileHashDict = dict()
        GlobalData.gModuleAllCacheStatus = set()
        GlobalData.gModuleCacheHit = set()

_BuildPlatform

它用于构建平台(Platform)的过程。以下是该函数的主要功能和作用:

  1. 清空平台构建文件:
       - 函数首先清空平台构建文件(PlatformBuildPath)内容,以防止手动编辑。

  2. 遍历构建目标(BuildTarget)列表:
       - 函数会遍历构建目标列表,针对每个构建目标执行构建操作。这通常包括不同工具链(ToolChain)的构建。

  3. 设置全局定义(GlobalDefines):
       - 函数会根据当前的构建目标、工具链等信息设置全局定义,以便在后续构建过程中使用。

  4. 创建 WorkspaceAutoGen 对象:
       - 通过创建 WorkspaceAutoGen 对象,函数获取了构建平台的相关信息,包括构建目标、工具链、架构等。
       - 函数会生成构建平台所需的 Makefile。

  5. 处理多线程 FFS 构建命令:
       - 如果启用了多线程 FFS 构建(gEnableGenfdsMultiThread 为真)且存在 Flash 文件系统描述文件(FDF),函数会生成 FFS 构建命令(CmdListDict)。

  6. 遍历支持的架构:
       - 函数遍历平台支持的架构(ArchList)。
       - 对于每个架构,函数创建 PlatformAutoGen 对象(Pa)以获取平台信息。
       - 函数遍历平台上的模块(Module)并创建 ModuleAutoGen 对象(Ma)用于代码生成和 Makefile 生成。
       - 如果模块具有 PCD 驱动程序(PcdIsDriver 为真),则将其添加到 PcdMaList 中。

  7. 执行 \_BuildPa 函数:
       - 函数调用 \_BuildPa 函数来执行构建平台的操作,包括生成代码、生成 Makefile 等。
       - 向 \_BuildPa 函数传递了构建目标、Pa 对象和 FFS 构建命令(CmdListDict)。

  8. 创建 MAP 文件:
       - 如果构建目标是 """all""fds",函数会为每个架构创建 MAP 文件。
       - 在创建 MAP 文件之前,会检查是否需要重新定位模块的内存地址。
       - 如果存在 FDF 文件,函数会重新构建 Flash 文件系统(FDS)并创建 MAP 文件。

  9. 创建 GUID 信息工具文件:
       - 函数调用 CreateGuidedSectionToolsFile 来创建 GUID 信息工具文件。

总的来说,\_BuildPlatform 函数是用于构建平台的核心函数,它处理了平台的多线程构建、代码生成、FFS 构建、MAP 文件生成等多个关键步骤。它在整个构建系统中起到了重要作用,确保了平台的正确构建和生成。

def _BuildPlatform(self):
        SaveFileOnChange(self.PlatformBuildPath, '# DO NOT EDIT \n# FILE auto-generated\n', False)
        for BuildTarget in self.BuildTargetList:
            GlobalData.gGlobalDefines['TARGET'] = BuildTarget
            index = 0
            for ToolChain in self.ToolChainList:
                GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
                GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
                GlobalData.gGlobalDefines['FAMILY'] = self.ToolChainFamily[index]
                index += 1
                Wa = WorkspaceAutoGen(
                        self.WorkspaceDir,
                        self.PlatformFile,
                        BuildTarget,
                        ToolChain,
                        self.ArchList,
                        self.BuildDatabase,
                        self.TargetTxt,
                        self.ToolDef,
                        self.Fdf,
                        self.FdList,
                        self.FvList,
                        self.CapList,
                        self.SkuId,
                        self.UniFlag,
                        self.Progress
                        )
                self.Fdf = Wa.FdfFile
                self.LoadFixAddress = Wa.Platform.LoadFixAddress
                self.BuildReport.AddPlatformReport(Wa)
                self.Progress.Stop("done!")

                # Add ffs build to makefile
                CmdListDict = {}
                if GlobalData.gEnableGenfdsMultiThread and self.Fdf:
                    CmdListDict = self._GenFfsCmd(Wa.ArchList)

                for Arch in Wa.ArchList:
                    PcdMaList    = []
                    GlobalData.gGlobalDefines['ARCH'] = Arch
                    Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch)
                    for Module in Pa.Platform.Modules:
                        # Get ModuleAutoGen object to generate C code file and makefile
                        Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile,Pa.DataPipe)
                        if Ma is None:
                            continue
                        if Ma.PcdIsDriver:
                            Ma.PlatformInfo = Pa
                            Ma.Workspace = Wa
                            PcdMaList.append(Ma)
                        self.BuildModules.append(Ma)
                    Pa.DataPipe.DataContainer = {"FfsCommand":CmdListDict}
                    Pa.DataPipe.DataContainer = {"Workspace_timestamp": Wa._SrcTimeStamp}
                    self._BuildPa(self.Target, Pa, FfsCommand=CmdListDict,PcdMaList=PcdMaList)

                # Create MAP file when Load Fix Address is enabled.
                if self.Target in ["", "all", "fds"]:
                    for Arch in Wa.ArchList:
                        GlobalData.gGlobalDefines['ARCH'] = Arch
                        #
                        # Check whether the set fix address is above 4G for 32bit image.
                        #
                        if (Arch == 'IA32' or Arch == 'ARM') and self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress >= 0x100000000:
                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platform with IA32 or ARM arch modules")
                    #
                    # Get Module List
                    #
                    ModuleList = {}
                    for Pa in Wa.AutoGenObjectList:
                        for Ma in Pa.ModuleAutoGenList:
                            if Ma is None:
                                continue
                            if not Ma.IsLibrary:
                                ModuleList[Ma.Guid.upper()] = Ma

                    MapBuffer = []
                    if self.LoadFixAddress != 0:
                        #
                        # Rebase module to the preferred memory address before GenFds
                        #
                        self._CollectModuleMapBuffer(MapBuffer, ModuleList)
                    if self.Fdf:
                        #
                        # create FDS again for the updated EFI image
                        #
                        self._Build("fds", Wa)
                        #
                        # Create MAP file for all platform FVs after GenFds.
                        #
                        self._CollectFvMapBuffer(MapBuffer, Wa, ModuleList)
                    #
                    # Save MAP buffer into MAP file.
                    #
                    self._SaveMapFile (MapBuffer, Wa)
                self.CreateGuidedSectionToolsFile(Wa)

_BuildModule

它用于构建模块(modules),其中包括多个步骤和逻辑。以下是该函数的主要功能和作用:

  1. 遍历构建目标(BuildTarget)列表:
       - 函数首先遍历构建目标列表,针对每个构建目标执行构建操作。这通常包括不同架构(Arch)和工具链(ToolChain)的不同构建目标。

  2. 设置全局定义(GlobalDefines):
       - 函数会根据当前的构建目标、工具链等信息设置全局定义,以便在后续构建过程中使用。

  3. 创建 WorkspaceAutoGen 对象:
       - 通过创建 WorkspaceAutoGen 对象,函数获取了构建平台(Platform)的相关信息,包括构建目标、工具链、架构等。
       - 函数会生成构建平台所需的 Makefile。

  4. 处理 FFS 构建命令:
       - 如果启用了多线程 FFS 构建(gEnableGenfdsMultiThread 为真)且存在 Flash 文件系统描述文件(FDF),函数会生成 FFS 构建命令(CmdListDict)。

  5. 处理多线程构建和自动代码生成:
       - 函数使用多线程构建模块(Ma),每个模块都代表一个 EDK II 模块。
       - 对于每个模块,函数检查是否需要自动生成代码文件和 Makefile,然后执行构建操作。
       - 如果目标是 ‘genc’ 或 ‘genmake’,则仅生成代码文件或 Makefile 并立即返回。

  6. 处理缓存操作:
       - 如果启用了缓存操作,函数会根据缓存类型执行相应的缓存生成或更新操作。

  7. 构建报告生成:
       - 函数会生成构建报告,其中包括构建模块的详细信息。

  8. 创建 MAP 文件:
       - 如果目标是 ‘fds’(生成 Flash 文件系统),函数会执行 Flash 文件系统生成操作。
       - 在这个过程中,会检查内存地址的设置,然后生成 Flash 文件系统(FDS)和 MAP 文件。

总的来说,\_BuildModule 函数是用于构建模块的核心函数,它处理了模块的多线程构建、代码生成、缓存操作、构建报告生成等多个关键步骤。它在整个构建系统中起到了重要作用,确保了模块的正确构建和生成。

def _BuildModule(self):
        for BuildTarget in self.BuildTargetList:
            GlobalData.gGlobalDefines['TARGET'] = BuildTarget
            index = 0
            for ToolChain in self.ToolChainList:
                WorkspaceAutoGenTime = time.time()
                GlobalData.gGlobalDefines['TOOLCHAIN'] = ToolChain
                GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = ToolChain
                GlobalData.gGlobalDefines['FAMILY'] = self.ToolChainFamily[index]
                index += 1
                #
                # module build needs platform build information, so get platform
                # AutoGen first
                #
                Wa = WorkspaceAutoGen(
                        self.WorkspaceDir,
                        self.PlatformFile,
                        BuildTarget,
                        ToolChain,
                        self.ArchList,
                        self.BuildDatabase,
                        self.TargetTxt,
                        self.ToolDef,
                        self.Fdf,
                        self.FdList,
                        self.FvList,
                        self.CapList,
                        self.SkuId,
                        self.UniFlag,
                        self.Progress,
                        self.ModuleFile
                        )
                self.Fdf = Wa.FdfFile
                self.LoadFixAddress = Wa.Platform.LoadFixAddress
                Wa.CreateMakeFile(False)
                # Add ffs build to makefile
                CmdListDict = None
                if GlobalData.gEnableGenfdsMultiThread and self.Fdf:
                    CmdListDict = self._GenFfsCmd(Wa.ArchList)

                GlobalData.file_lock = mp.Lock()
                GlobalData.FfsCmd = CmdListDict

                self.Progress.Stop("done!")
                MaList = []
                ExitFlag = threading.Event()
                ExitFlag.clear()
                self.AutoGenTime += int(round((time.time() - WorkspaceAutoGenTime)))
                for Arch in Wa.ArchList:
                    AutoGenStart = time.time()
                    GlobalData.gGlobalDefines['ARCH'] = Arch
                    Pa = PlatformAutoGen(Wa, self.PlatformFile, BuildTarget, ToolChain, Arch)
                    for Module in Pa.Platform.Modules:
                        if self.ModuleFile.Dir == Module.Dir and self.ModuleFile.Name == Module.Name:
                            Ma = ModuleAutoGen(Wa, Module, BuildTarget, ToolChain, Arch, self.PlatformFile,Pa.DataPipe)
                            if Ma is None:
                                continue
                            if Ma.PcdIsDriver:
                                Ma.PlatformInfo = Pa
                                Ma.Workspace = Wa
                            MaList.append(Ma)

                            if GlobalData.gUseHashCache and not GlobalData.gBinCacheDest and self.Target in [None, "", "all"]:
                                if Ma.CanSkipbyPreMakeCache():
                                    continue
                                else:
                                    self.PreMakeCacheMiss.add(Ma)

                            # Not to auto-gen for targets 'clean', 'cleanlib', 'cleanall', 'run', 'fds'
                            if self.Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
                                # for target which must generate AutoGen code and makefile
                                if not self.SkipAutoGen or self.Target == 'genc':
                                    self.Progress.Start("Generating code")
                                    Ma.CreateCodeFile(True)
                                    self.Progress.Stop("done!")
                                if self.Target == "genc":
                                    return True
                                if not self.SkipAutoGen or self.Target == 'genmake':
                                    self.Progress.Start("Generating makefile")
                                    if CmdListDict and self.Fdf and (Module.Path, Arch) in CmdListDict:
                                        Ma.CreateMakeFile(True, CmdListDict[Module.Path, Arch])
                                        del CmdListDict[Module.Path, Arch]
                                    else:
                                        Ma.CreateMakeFile(True)
                                    self.Progress.Stop("done!")
                                if self.Target == "genmake":
                                    return True

                                if GlobalData.gBinCacheSource and self.Target in [None, "", "all"]:
                                    if Ma.CanSkipbyMakeCache():
                                        continue
                                    else:
                                        self.MakeCacheMiss.add(Ma)

                            self.BuildModules.append(Ma)
                    self.AutoGenTime += int(round((time.time() - AutoGenStart)))
                    MakeStart = time.time()
                    for Ma in self.BuildModules:
                        if not Ma.IsBinaryModule:
                            Bt = BuildTask.New(ModuleMakeUnit(Ma, Pa.BuildCommand,self.Target))
                        # Break build if any build thread has error
                        if BuildTask.HasError():
                            # we need a full version of makefile for platform
                            ExitFlag.set()
                            BuildTask.WaitForComplete()
                            Pa.CreateMakeFile(False)
                            EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)
                        # Start task scheduler
                        if not BuildTask.IsOnGoing():
                            BuildTask.StartScheduler(self.ThreadNumber, ExitFlag)

                    # in case there's an interruption. we need a full version of makefile for platform
                    Pa.CreateMakeFile(False)
                    if BuildTask.HasError():
                        EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)
                    self.MakeTime += int(round((time.time() - MakeStart)))

                MakeContiue = time.time()
                ExitFlag.set()
                BuildTask.WaitForComplete()
                self.CreateAsBuiltInf()
                if GlobalData.gBinCacheDest:
                    self.GenDestCache()
                elif GlobalData.gUseHashCache and not GlobalData.gBinCacheSource:
                    # Only for --hash
                    # Update PreMakeCacheChain files
                    self.GenLocalPreMakeCache()
                self.BuildModules = []
                self.MakeTime += int(round((time.time() - MakeContiue)))
                if BuildTask.HasError():
                    EdkLogger.error("build", BUILD_ERROR, "Failed to build module", ExtraData=GlobalData.gBuildingModule)

                self.BuildReport.AddPlatformReport(Wa, MaList)
                if MaList == []:
                    EdkLogger.error(
                                'build',
                                BUILD_ERROR,
                                "Module for [%s] is not a component of active platform."\
                                " Please make sure that the ARCH and inf file path are"\
                                " given in the same as in [%s]" % \
                                    (', '.join(Wa.ArchList), self.PlatformFile),
                                ExtraData=self.ModuleFile
                                )
                # Create MAP file when Load Fix Address is enabled.
                if self.Target == "fds" and self.Fdf:
                    for Arch in Wa.ArchList:
                        #
                        # Check whether the set fix address is above 4G for 32bit image.
                        #
                        if (Arch == 'IA32' or Arch == 'ARM') and self.LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self.LoadFixAddress >= 0x100000000:
                            EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS can't be set to larger than or equal to 4G for the platorm with IA32 or ARM arch modules")
                    #
                    # Get Module List
                    #
                    ModuleList = {}
                    for Pa in Wa.AutoGenObjectList:
                        for Ma in Pa.ModuleAutoGenList:
                            if Ma is None:
                                continue
                            if not Ma.IsLibrary:
                                ModuleList[Ma.Guid.upper()] = Ma

                    MapBuffer = []
                    if self.LoadFixAddress != 0:
                        #
                        # Rebase module to the preferred memory address before GenFds
                        #
                        self._CollectModuleMapBuffer(MapBuffer, ModuleList)
                    #
                    # create FDS again for the updated EFI image
                    #
                    GenFdsStart = time.time()
                    self._Build("fds", Wa)
                    self.GenFdsTime += int(round((time.time() - GenFdsStart)))
                    #
                    # Create MAP file for all platform FVs after GenFds.
                    #
                    self._CollectFvMapBuffer(MapBuffer, Wa, ModuleList)
                    #
                    # Save MAP buffer into MAP file.
                    #
                    self._SaveMapFile (MapBuffer, Wa)

_BuildPa

这个 \_BuildPa 函数是 edk2 的构建系统中的一个重要函数,它负责根据指定的目标(Target)执行不同的构建操作。以下是这个函数的主要功能和作用:

  1. 构建模块、库和平台:
       - \_BuildPa 函数可以用于构建不同级别的组件,包括模块、库和平台。
       - 根据传入的 Target 参数,可以选择构建模块、库、平台或执行清理操作(clean)。

  2. 多线程构建:
       - 函数内部使用了多线程来并行构建不同的模块或库,以提高构建效率。
       - 对于模块、库的构建,它会将构建任务放入队列,并使用多线程执行。

  3. 构建命令的生成和执行:
       - 函数会根据配置文件中的设置生成构建命令(BuildCommand)。
       - 对于模块、库的构建,它会执行相应的构建命令。
       - 对于平台级别的构建,它会生成 Makefile 和代码文件。

  4. 清理操作:
       - 函数支持清理操作,包括清理模块、库、平台以及全部清理(cleanall)。

  5. 其他功能:
       - 函数还包括了一些额外的功能,如生成缓存、更新数据管道、创建AsBuiltInf等。

总的来说,\_BuildPa 函数是构建系统的核心部分之一,用于管理和执行不同构建操作,以确保正确构建模块、库和平台。根据传入的目标,它可以执行不同级别的构建或清理操作,并支持多线程构建以提高效率。此外,它还负责生成构建命令和相应的文件。这个函数的设计是为了让构建系统更加灵活和可扩展。

def _BuildPa(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False, FfsCommand=None, PcdMaList=None):
        if AutoGenObject is None:
            return False
        if FfsCommand is None:
            FfsCommand = {}
        # skip file generation for cleanxxx targets, run and fds target
        if Target not in ['clean', 'cleanlib', 'cleanall', 'run', 'fds']:
            # for target which must generate AutoGen code and makefile
            mqueue = mp.Queue()
            for m in AutoGenObject.GetAllModuleInfo:
                mqueue.put(m)
            mqueue.put((None,None,None,None,None,None,None))
            AutoGenObject.DataPipe.DataContainer = {"CommandTarget": self.Target}
            AutoGenObject.DataPipe.DataContainer = {"Workspace_timestamp": AutoGenObject.Workspace._SrcTimeStamp}
            AutoGenObject.CreateLibModuelDirs()
            AutoGenObject.DataPipe.DataContainer = {"LibraryBuildDirectoryList":AutoGenObject.LibraryBuildDirectoryList}
            AutoGenObject.DataPipe.DataContainer = {"ModuleBuildDirectoryList":AutoGenObject.ModuleBuildDirectoryList}
            AutoGenObject.DataPipe.DataContainer = {"FdsCommandDict": AutoGenObject.Workspace.GenFdsCommandDict}
            self.Progress.Start("Generating makefile and code")
            data_pipe_file = os.path.join(AutoGenObject.BuildDir, "GlobalVar_%s_%s.bin" % (str(AutoGenObject.Guid),AutoGenObject.Arch))
            AutoGenObject.DataPipe.dump(data_pipe_file)
            cqueue = mp.Queue()
            autogen_rt,errorcode = self.StartAutoGen(mqueue, AutoGenObject.DataPipe, self.SkipAutoGen, PcdMaList, cqueue)
            AutoGenIdFile = os.path.join(GlobalData.gConfDirectory,".AutoGenIdFile.txt")
            with open(AutoGenIdFile,"w") as fw:
                fw.write("Arch=%s\n" % "|".join((AutoGenObject.Workspace.ArchList)))
                fw.write("BuildDir=%s\n" % AutoGenObject.Workspace.BuildDir)
                fw.write("PlatformGuid=%s\n" % str(AutoGenObject.Guid))
            self.Progress.Stop("done!")
            if not autogen_rt:
                self.AutoGenMgr.TerminateWorkers()
                self.AutoGenMgr.join(1)
                raise FatalError(errorcode)
            AutoGenObject.CreateCodeFile(False)
            AutoGenObject.CreateMakeFile(False)
        else:
            # always recreate top/platform makefile when clean, just in case of inconsistency
            AutoGenObject.CreateCodeFile(True)
            AutoGenObject.CreateMakeFile(True)

        if EdkLogger.GetLevel() == EdkLogger.QUIET:
            EdkLogger.quiet("Building ... %s" % repr(AutoGenObject))

        BuildCommand = AutoGenObject.BuildCommand
        if BuildCommand is None or len(BuildCommand) == 0:
            EdkLogger.error("build", OPTION_MISSING,
                            "No build command found for this module. "
                            "Please check your setting of %s_%s_%s_MAKE_PATH in Conf/tools_def.txt file." %
                                (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
                            ExtraData=str(AutoGenObject))

        # run
        if Target == 'run':


**先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里**

**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/7e1f9b5447e3fdfb3899f7ebfd24df79.png)
![img](https://img-blog.csdnimg.cn/img_convert/c14c58d736b03f2d3838dd0ad068c6b9.png)
![img](https://img-blog.csdnimg.cn/img_convert/4db63707bbb55ca23edefd7986cc8f65.png)
![img](https://img-blog.csdnimg.cn/img_convert/909846d160a626de155d921cf8b43fed.png)
![img](https://img-blog.csdnimg.cn/img_convert/ab6432b2666358bdcd341cf125481ca4.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

() == EdkLogger.QUIET:
            EdkLogger.quiet("Building ... %s" % repr(AutoGenObject))

        BuildCommand = AutoGenObject.BuildCommand
        if BuildCommand is None or len(BuildCommand) == 0:
            EdkLogger.error("build", OPTION_MISSING,
                            "No build command found for this module. "
                            "Please check your setting of %s_%s_%s_MAKE_PATH in Conf/tools_def.txt file." %
                                (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
                            ExtraData=str(AutoGenObject))

        # run
        if Target == 'run':


**先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里**

**深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
[外链图片转存中...(img-myhyTNwF-1715888688059)]
[外链图片转存中...(img-z9AWw5wQ-1715888688060)]
[外链图片转存中...(img-WocAJw5c-1715888688060)]
[外链图片转存中...(img-wiFRxzPC-1715888688060)]
[外链图片转存中...(img-1WvKWmyf-1715888688060)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译生成 OVMF 是指通过 ed2k 来获得 OVMF 源代码,并将其编译成可执行文件的过程。 首先,我们需要通过 ed2k 下载 OVMF 的源代码。ed2k 是一种文件传输协议,可以在网络上找到对应的资源。我们可以使用 ed2k 客户端软件来下载 OVMF。打开 ed2k 客户端,粘贴 OVMF 的 ed2k 链接,然后开始下载。 下载完成后,我们需要解压缩 OVMF 的源代码。可以使用压缩软件(如 WinRAR)将下载的文件解压缩到一个目录。 接下来,我们需要打开命令行终端,并进入到解压缩后的 OVMF 源代码目录。 在命令行输入编译命令来生成 OVMF。具体的编译命令可能因操作系统和编译器而不同。常见的编译命令包括 make、gcc、cmake 等。我们可以查阅 OVMF 的文档或官方网站来获取准确的编译命令。 根据编译命令的要求,执行相应的编译命令,等待编译过程完成。编译过程可能需要一定的时间,取决于计算机性能和源代码的复杂度。 一旦编译完成,我们可以在指定的目录找到生成的 OVMF 可执行文件。该文件就是编译生成的 OVMF。 最后,我们可以将生成的 OVMF 可执行文件用于相应的应用,如虚拟机管理器(例如 QEMU、VirtualBox)来运行 UEFI 镜像。 总结来说,编译生成 OVMF 需要下载 OVMF 源代码,解压缩,进入命令行终端,执行编译命令,等待编译完成,并获取生成的 OVMF 可执行文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值