问题描述
我开始用edk2编写一个简单的应用程序。
所以要编写一个简单的edk2 UEFI应用程序,我是这样开始的:
#git clone https://github.com/tianocore/edk2.git
test
(有,我已经写了: TARGET_ARCH = IA32 X64 TOOL_CHAIN_TAG = VS2017)
#. edksetup.sh Basetools
Loading prevIoUs configuration from /media/ledoux/Data/osdev/devos/edk2/edk2/Conf/BuildEnv.sh
WORKSPACE: /media/ledoux/Data/osdev/devos/edk2/edk2
EDK_TOOLS_PATH: /media/ledoux/Data/osdev/devos/edk2/edk2/Basetools
CONF_PATH: /media/ledoux/Data/osdev/devos/edk2/edk2/Conf
#vi Conf/target.txt
为什么构建失败? 是因为存储库不正确吗? 构建后如何创建OVMF.fd文件???
解决方法
这里有一个完整的 Linux Ubuntu 20 教程。它在我这边工作得很好。
设置 EDK2
以下是我为让 EDK2 在 Linux Ubuntu 20 上运行而采取的步骤:
-
sudo apt-get install build-essential git uuid-dev iasl nasm python python3-distutils python3-apt
-
git clone https://github.com/tianocore/edk2.git
-
从这里下载 brotli https://github.com/tianocore/edk2/releases/tag/edk2-stable202011(第三个文件)
-
安装在 ~/edk2/BaseTools/Source/C/BrotliCompress/brotli
-
cd edk2
-
make -C BaseTools
-
运行“.edksetup.sh”(包括点)
-
在文本编辑器中打开 Conf/target.txt 将 ACTIVE_PLATFORM 更改为 MdeModulePkg/MdeModulePkg.dsc TOOL_CHAIN_TAG 到 GCC5 和 TARGET_ARCH 到 X64
-
从这里下载 oniguruma https://github.com/kkos/oniguruma/tree/abfc8ff81df4067f309032467785e06975678f0d
-
复制brotli到~/edk2/MdeModulePkg/Library/BrotliCustomDecompressLib/brotli 和 oniguruma 到 ~/edk2/MdeModulePkg/Universal/RegularExpressionDxe/oniguruma
-
构建
如果您在任何步骤关闭 bash 终端,只需重新运行“.edksetup.sh”,因为这样您就无法运行构建命令。
编译自己的 efi 应用
上面将简单地向您展示它的一般工作原理。一旦所有这些都有效,您想要编译自己的 Hello World 示例,如下所示。
#include <Uefi.h>
EFI_STATUS EFIAPI UefiMain (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable){
SystemTable->ConOut->OutputString(SystemTable->ConOut,L"Hello World\n");
return EFI_SUCCESS;
}
为了做到这一点,您需要采取更多步骤。
-
在 edk2 目录中创建一个工作目录,如 ~edk2/BootloaderPkg。在那里,放置 2 个文件,一个名为 Bootloader.c,一个名为 Bootloader.inf。
-
在 Bootloader.c 中放置上面的代码。在 Bootloader.inf 中放置以下内容
[Defines]
INF_VERSION = 1.25
BASE_NAME = Bootloader
FILE_GUID = 66949615-9653-4a86-8c61-6ef0952973b9
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
[Sources]
Bootloader.c
[Packages]
MdePkg/MdePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
[Guids]
[Ppis]
[Protocols]
[FeaturePcd]
[Pcd]
- 如 https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-Writing-Simple-Application 所述,
使用您的项目 .inf 文件更新现有平台 .DSC 文件。下面列出了一些例子。
所以我所做的是从 MdeModulePackage 中取出 .DSC 文件,并使用以下内容对其进行了一些修改:
[Defines]
PLATFORM_NAME = MdeModule
PLATFORM_GUID = 587CE499-6CBE-43cd-94E2-186218569478
PLATFORM_VERSION = 0.98
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = BootloaderPkg/Build
SUPPORTED_ARCHITECTURES = IA32|X64|EBC|ARM|AARCH64|RISCV64
BUILD_TARGETS = DEBUG|RELEASE|NOOPT
SKUID_IDENTIFIER = DEFAULT
[LibraryClasses]
#
# Entry point
#
PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
#
# Basic
#
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
#
# UEFI & PI
#
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
#
# Generic Modules
#
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
#
# Misc
#
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf
S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
PlatformBootManagerLib|MdeModulePkg/Library/PlatformBootManagerLibNull/PlatformBootManagerLibNull.inf
PciHostBridgeLib|MdeModulePkg/Library/PciHostBridgeLibNull/PciHostBridgeLibNull.inf
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf
VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
[LibraryClasses.EBC.PEIM]
IoLib|MdePkg/Library/PeiIoLibCpuIo/PeiIoLibCpuIo.inf
[LibraryClasses.common.PEI_CORE]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
[LibraryClasses.common.DXE_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf
VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
[LibraryClasses.common.SMM_CORE]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf
SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf
SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf
SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf
MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
[LibraryClasses.common.MM_STANDALONE]
HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf
MemoryAllocationLib|MdeModulePkg/Library/BaseMemoryAllocationLibNull/BaseMemoryAllocationLibNull.inf
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxStandaloneMmLib.inf
MemLib|StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
[Components]
BootloaderPkg/Bootloader.inf
[BuildOptions]
将该内容放入名为 BootloaderPkg.dsc 的文件中,并将其放入您的工作目录中。
-
将 Conf/target.txt 文件中的 ACTIVE_PLATFORM 行更改为
ACTIVE_PLATFORM = BootloaderPkg/BootloaderPkg.dsc
。 -
完成此操作后,您就可以编译自己的 EFI 应用程序了。打开终端并输入以下命令:
cd edk2
. edksetup.sh
build
现在您应该在 ~/edk2/BootloaderPkg/Build 目录中拥有所有类型的文件,包括 Bootloader.efi,它是已编译的 EFI 应用程序。
测试 EFI 应用程序
现在您想测试它,很高兴拥有一个 EFI 应用程序。编写一个 bash 脚本并在其中输入以下命令(取自此处 https://wiki.osdev.org/UEFI)
dd if=/dev/zero of=edk2/BootloaderPkg/disk.img bs=512 count=93750
gdisk edk2/BootloaderPkg/disk.img #o n ef00 w
sudo losetup --offset 1048576 --sizelimit 46934528 /dev/loop7 edk2/BootloaderPkg/disk.img
sudo mkdosfs -F 32 /dev/loop7
sudo mount /dev/loop7 /mnt
sudo cp edk2/BootloaderPkg/Build/DEBUG_GCC5/X64/Bootloader.efi /mnt
sudo umount /mnt
sudo losetup -d /dev/loop7
将该脚本放入您的主目录并启动该脚本。系统将提示您输入内容。按 o、y、n、回车、回车、回车、ef00、w 和 y 的顺序键入。这将使您拥有一个使用 FAT32 分区的 disk.img 并在其上包含文件 Bootloader.efi(EFI 应用程序)。
完成后,您需要下载 OVMF 和 qemu,所以输入
sudo apt install ovmf qemu qemu-system-x86
完成此操作后,键入以下命令以在 QEMU 中启动 EFI shell 并测试您的 EFI 应用程序。
sudo qemu-system-x86_64 -cpu qemu64 -drive if=pflash,format=raw,unit=0,file=/usr/share/OVMF/OVMF_CODE.fd,readonly=on -drive if=pflash,unit=1,file=/usr/share/OVMF/OVMF_VARS.fd -drive format=raw,file=edk2/BootloaderPkg/disk.img,if=virtio
您应该会在几秒钟后看到一个 UEFI shell。然后输入 fs0:
和 Bootloader.efi
。这将更改目录,然后启动您的 EFI 应用。
您正在Linux下进行构建,因此没有Visual Studio(VS2017指的是Visual Studio)。构建系统确实应该说些有用的东西,但是……我可以从自己的实验中确认它没有。
改为使用GCC5的工具链标签-对于最新的gcc10版本,该标签仍然有效。
,令我惊讶的是,您在构建EDK2方面的发展达到了极限。
这是我要做的:
- 确保已安装以下软件包:gcc-c ++,nasm,libuuid-devel,acpica-tools
- 确保您使用的是GCC bdf链接程序,即/usr/bin/ld.bfd,而不是黄金链接程序。
作为普通用户:
$ git clone https://github.com/tianocore/edk2.git
$ cd edk2
$ git submodule update --init
$ cd BaseTools
$ make
假设您已成功构建了工具,接下来测试构建现有的EDK2软件包:
$ cd edk2
$ build -p MdeModulePkg/MdeModulePkg.dsc -t GCC5 -a X64
...
- Done -
Build end time: 19:36:56,Sep.04 2020
Build total time: 00:02:41
$
如果MdeModulePkg
成功构建,则可以使用EDK2构建第一个UEFI应用程序。