网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
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. 设置全局构建选项和标志:
- 根据构建选项,设置全局构建选项,如 `gIgnoreSource`、`gUseHashCache`、`gBinCacheDest`、`gBinCacheSource`、`gEnableGenfdsMultiThread`、`gDisableIncludePathCheck` 等。
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':
return True
# Fetch the MakeFileName.
self.MakeFileName = AutoGenObject.MakeFileName
# build modules
if BuildModule:
BuildCommand = BuildCommand + [Target]
LaunchCommand(BuildCommand, AutoGenObject.MakeFileDir)
if GlobalData.gBinCacheDest:
self.GenDestCache()
elif GlobalData.gUseHashCache and not GlobalData.gBinCacheSource:
# Only for --hash
# Update PreMakeCacheChain files
self.GenLocalPreMakeCache()
self.BuildModules = []
return True
# build library
if Target == 'libraries':
DirList = []
for Lib in AutoGenObject.LibraryAutoGenList:
if not Lib.IsBinaryModule:
DirList.append((os.path.join(AutoGenObject.BuildDir, Lib.BuildDir),Lib))
for Lib, LibAutoGen in DirList:
NewBuildCommand = BuildCommand + ['-f', os.path.normpath(os.path.join(Lib, self.MakeFileName)), 'pbuild']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir,LibAutoGen)
return True
# build module
if Target == 'modules':
DirList = []
for Lib in AutoGenObject.LibraryAutoGenList:
if not Lib.IsBinaryModule:
DirList.append((os.path.join(AutoGenObject.BuildDir, Lib.BuildDir),Lib))
for Lib, LibAutoGen in DirList:
NewBuildCommand = BuildCommand + ['-f', os.path.normpath(os.path.join(Lib, self.MakeFileName)), 'pbuild']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir,LibAutoGen)
DirList = []
for ModuleAutoGen in AutoGenObject.ModuleAutoGenList:
if not ModuleAutoGen.IsBinaryModule:
DirList.append((os.path.join(AutoGenObject.BuildDir, ModuleAutoGen.BuildDir),ModuleAutoGen))
for Mod,ModAutoGen in DirList:
NewBuildCommand = BuildCommand + ['-f', os.path.normpath(os.path.join(Mod, self.MakeFileName)), 'pbuild']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir,ModAutoGen)
self.CreateAsBuiltInf()
if GlobalData.gBinCacheDest:
self.GenDestCache()
elif GlobalData.gUseHashCache and not GlobalData.gBinCacheSource:
# Only for --hash
# Update PreMakeCacheChain files
self.GenLocalPreMakeCache()
self.BuildModules = []
return True
# cleanlib
if Target == 'cleanlib':
for Lib in AutoGenObject.LibraryBuildDirectoryList:
LibMakefile = os.path.normpath(os.path.join(Lib, self.MakeFileName))
if os.path.exists(LibMakefile):
NewBuildCommand = BuildCommand + ['-f', LibMakefile, 'cleanall']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir)
return True
# clean
if Target == 'clean':
for Mod in AutoGenObject.ModuleBuildDirectoryList:
ModMakefile = os.path.normpath(os.path.join(Mod, self.MakeFileName))
if os.path.exists(ModMakefile):
NewBuildCommand = BuildCommand + ['-f', ModMakefile, 'cleanall']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir)
for Lib in AutoGenObject.LibraryBuildDirectoryList:
LibMakefile = os.path.normpath(os.path.join(Lib, self.MakeFileName))
if os.path.exists(LibMakefile):
NewBuildCommand = BuildCommand + ['-f', LibMakefile, 'cleanall']
LaunchCommand(NewBuildCommand, AutoGenObject.MakeFileDir)
return True
# cleanall
if Target == 'cleanall':
try:
#os.rmdir(AutoGenObject.BuildDir)
RemoveDirectory(AutoGenObject.BuildDir, True)
except WindowsError as X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
return True
### \_Build
这个 `\_Build` 函数是 edk2 构建系统中的另一个核心函数,它用于执行不同类型的构建操作,类似于 `\_BuildPa` 函数,但有一些不同之处。以下是这个函数的主要功能和作用:
1. 构建代码文件和 Makefile:
- 根据传入的 `Target` 参数,函数可以选择生成代码文件、Makefile 或执行清理操作。
- 对于需要生成代码文件和 Makefile 的目标(不包括清理目标),它会调用 `AutoGenObject` 的相应方法生成这些文件。
2. 清理操作:
- 函数支持清理操作,包括清理模块、库、平台和全部清理(cleanall)。
3. 构建命令的生成和执行:
- 函数会根据配置文件中的设置生成构建命令(BuildCommand)。
- 对于模块的构建,它会执行相应的构建命令。
4. genfds 操作:
- 如果 `Target` 是 'fds',函数会执行 `GenFdsApi` 来生成 Flash 文件系统(FDS)。
5. 运行操作:
- 如果 `Target` 是 'run',函数将直接返回 True,表示运行操作已完成。
6. 创建 AsBuiltInf 文件:
- 函数会调用 `CreateAsBuiltInf` 方法创建 AsBuiltInf 文件。
7. 缓存操作:
- 函数支持缓存操作,包括生成缓存、更新数据管道、生成本地缓存等。
总的来说,`\_Build` 函数是构建系统的核心之一,用于执行不同类型的构建和清理操作,包括生成代码文件、Makefile、Flash 文件系统(FDS)等。它根据传入的 `Target` 参数决定执行哪种操作,并根据配置文件生成相应的构建命令。这个函数的设计是为了使构建系统更加灵活,并且支持各种不同的构建和清理操作。
def _Build(self, Target, AutoGenObject, CreateDepsCodeFile=True, CreateDepsMakeFile=True, BuildModule=False):
if AutoGenObject is None:
return False
# 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
if not self.SkipAutoGen or Target == 'genc':
self.Progress.Start("Generating code")
AutoGenObject.CreateCodeFile(CreateDepsCodeFile)
self.Progress.Stop("done!")
if Target == "genc":
return True
if not self.SkipAutoGen or Target == 'genmake':
self.Progress.Start("Generating makefile")
AutoGenObject.CreateMakeFile(CreateDepsMakeFile)
#AutoGenObject.CreateAsBuiltInf()
self.Progress.Stop("done!")
if Target == "genmake":
return True
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))
# build modules
if BuildModule:
if Target != 'fds':
BuildCommand = BuildCommand + [Target]
AutoGenObject.BuildTime = LaunchCommand(BuildCommand, AutoGenObject.MakeFileDir)
self.CreateAsBuiltInf()
if GlobalData.gBinCacheDest:
self.GenDestCache()
elif GlobalData.gUseHashCache and not GlobalData.gBinCacheSource:
# Only for --hash
# Update PreMakeCacheChain files
self.GenLocalPreMakeCache()
self.BuildModules = []
return True
# genfds
if Target == 'fds':
if GenFdsApi(AutoGenObject.GenFdsCommandDict, self.Db):
EdkLogger.error("build", COMMAND_FAILURE)
Threshold = self.GetFreeSizeThreshold()
if Threshold:
self.CheckFreeSizeThreshold(Threshold, AutoGenObject.FvDir)
return True
# run
if Target == 'run':
return True
# build library
if Target == 'libraries':
pass
# not build modules
# cleanall
if Target == 'cleanall':
try:
#os.rmdir(AutoGenObject.BuildDir)
RemoveDirectory(AutoGenObject.BuildDir, True)
except WindowsError as X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
return True
在edk2的`build.py`文件中,`\_BuildPa` 和 `\_Build` 这两个函数具有不同的作用和功能,它们分别用于不同的构建任务。
### 最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
### 资料预览
给大家整理的视频资料:
![](https://img-blog.csdnimg.cn/img_convert/0187fd5a2442e4197be320ad90c3d6a2.png)
给大家整理的电子书资料:
![](https://img-blog.csdnimg.cn/img_convert/6f5c6f5b3afd064f94f736b67b2251f1.png)
**如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
d:
self.CheckFreeSizeThreshold(Threshold, AutoGenObject.FvDir)
return True
# run
if Target == 'run':
return True
# build library
if Target == 'libraries':
pass
# not build modules
# cleanall
if Target == 'cleanall':
try:
#os.rmdir(AutoGenObject.BuildDir)
RemoveDirectory(AutoGenObject.BuildDir, True)
except WindowsError as X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
return True
在edk2的build.py
文件中,\_BuildPa
和 \_Build
这两个函数具有不同的作用和功能,它们分别用于不同的构建任务。
最后的话
最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!
资料预览
给大家整理的视频资料:
[外链图片转存中…(img-1chhl1DU-1715888654615)]
给大家整理的电子书资料:
[外链图片转存中…(img-3NkEckoD-1715888654616)]
如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!