ubuntu20.04下搭建EDK2开发环境
EDK2是UEFI应用程序的官方开发环境。它是由开源的Tianocore项目开发的,英特尔、惠普和微软是该项目的主要贡献者。虽然它可能比GNU-EFI大,但它有更多的功能,因此,一些操作系统开发人员可能更喜欢它而不是GNU-EFI。
什么是EDK2?
EDK2完全实现了UEFI规范。它包含开放虚拟机固件(OVMF) UEFI固件包,主要针对QEMU,许多操作系统开发人员使用它来测试他们的UEFI应用程序。它也有用于QEMU和各种板的ARM和AArch64固件包,以及用于各种HiFive板的RISC-V固件包。它还为UEFI驱动程序开发人员提供了工具。
EDK2的结构
EDK2由多个仓库组成,所有这些仓库都可以在https://github.com/tianocore上找到。主要有:
- edk2,它包含构建系统、库、OVMF和ArmVirt固件。
- edk2-platforms,其中包含用于各种真实硬件平台的固件,例如SiFive U450、Raspberry Pi等。
- edk2-non-osi,它包含各种平台的专有二进制blob。
EDK2本身是用C语言和一些Python编写的,并在BSD 2 Clause +专利许可下获得许可。这些blobs都有自己的许可证。
目录结构
EDK2被分成多个子目录,每个子目录通常包含一个“包”。OvmfPkg子目录包含OVMF, MdePkg子目录包含UEFI库,等等。其中每一个都包含一个以.dsc结尾的文件。该文件描述文件夹内的包,并包含诸如依赖项、不同组件等内容。每个组件都有自己的文件,其中包含源、应用程序类型等。
构建EDK2基础
无论您尝试从EDK2构建什么,都必须完成这些步骤。首先,您必须决定是否只想在主要的EDK2仓库中构建东西,还是也想从EDK2平台中构建东西。注意,这些指南假定您使用的是Linux系统(Linux的Windows子系统也可以)。
使用edk2平台进行构建
确保你已经安装了所有的依赖项:
apt install build-essential git python2 uuid-dev nasm acpica-tools
如果您确实需要在真实硬件上运行的固件,那么您必须执行以下步骤。
首先,我们需要创建工作空间文件夹
mkdir edk2 && cd edk2 export WORKSPACE=$PWD
现在我们需要将源代码克隆到所有的仓库。edk2-non-osi是可选的,具体取决于您正在构建的平台,但我还是建议下载它
git clone https://github.com/tianocore/edk2.git -b"stable/202011" git clone https://github.com/tianocore/edk2-platforms.git git clone https://github.com/tianocore/edk2-non-osi.git cd edk2 && git submodule update --init cd ../edk2-platforms && git submodule update --init && cd ..
我们需要让EDK2的构建系统知道这些文件夹的位置。我们还将设置一些其他变量
export EDK_TOOLS_PATH="$PWD/edk2/BaseTools" export PACKAGES_PATH="$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-osi"
我们现在必须设置环境
. edk2/edksetup.sh make -C edk2/BaseTools
要在edk2-platforms中为某个平台构建,只需找到相关的.dsc文件。
构建EDK2 UEFI应用程序
一旦构建了EDK2的基础部分,构建UEFI应用程序就非常容易了。作为操作系统开发人员,主要的软件包将与MdeModulePkg一起工作,这是一个完整的UEFI封装库。
首先,我们必须创建一个包含应用程序的目录。我们将在主EDK2目录中创建它,如下所示:
cd edk2 mkdir MyEfiApp
现在,在MyEfiApp目录下创建一个名为MyEfiApp.inf的文件。内容如下:
[Defines] INF_VERSION = 1.25 BASE_NAME = MyEfiApp FILE_GUID = # Get a GUID from guidgen.com MODULE_TYPE = UEFI_APPLICATION VERSION_STRING = 1.0 ENTRY_POINT = UefiEntry [Sources] UefiMain.c [Packages] MdePkg/MdePkg.dec [LibraryClasses] UefiApplicationEntryPoint UefiLib [Guids] [Ppis] [Protocols] [FeaturePcd] [Pcd]
注意:上面的FILE_GUID不能空,否则编译时报错。具体填什么值可以从其他.inf文件中参考下。
在和MyEfiApp.inf同一个目录MyEfiApp中创建一个名为UefiMain.c的文件。并赋予它以下内容:
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/UefiBootServicesTableLib.h> EFI_STATUS EFIAPI UefiEntry(IN EFI_HANDLE imgHandle, IN EFI_SYSTEM_TABLE* sysTable) { gST = sysTable; gBS = sysTable->BootServices; gImageHandle = imgHandle; // UEFI apps automatically exit after 5 minutes. Stop that here gBS->SetWatchdogTimer(0, 0, 0, NULL); Print(L"Hello, world!\r\n"); // Allocate a string CHAR16* str = NULL; gBS->AllocatePool(EfiLoaderData, 36, (VOID**)&str); // Copy over a string CHAR16* str2 = L"Allocated string\r\n"; gBS->CopyMem((VOID*)str, (VOID*)str2, 36); Print(str); gBS->FreePool(str); return EFI_SUCCESS; }
如果需要,现在运行 . edksetup.sh 。然后,在MdeModulePkg/MdeModulePkg.dsc找到“Components”部分,然后加上这个
[Components]
...
MyEfiApp/MyEfiApp.inf
之后,像这样调用EDK2的构建系统来构建MyEfiApp:
build -a X64 -t GCC5 -p MdeModulePkg/MdeModulePkg.dsc
-a指定目标平台,可以指定为:IA32, X64, AARCH64, ARM 或者 RISCV64.
最后,在Build/MdeModule/DEBUG_GCC5/X64文件夹中,应该有一个名为MyEfiApp.efi的文件。
构建OVMF和ArmVirt
构建OVMF和ArmVirtPkg很容易,在设置EDK2之后,为OVMF运行以下命令:
build -a YOUR_ARCH -t GCC5 -p OvmfPkg/OvmfPkgYOUR_ARCH.dsc
对于OVMF, YOUR_ARCH只能是IA32或X64。对于ArmVirtPkg,运行这个:
build -a YOUR_ARCH -t GCC5 -p ArmVirtPkg/ArmVirtQemu.dsc
YOUR_ARCH只能是ARM或AARCH64。在此之后,固件将输出OVMF Build/OvmfYOUR_ARCH/DEBUG_GCC5/FV,或ArmVirtPkg Build/ArmVirtQemu-YOUR_ARCH/DEBUG_GCC5/FV。
本文参考:
https://wiki.osdev.org/EDK2
https://wiki.osdev.org/GNU-EFI
https://kcm.trellix.com/corporate/index?page=content&id=KB90801&locale=en_US
本文来自博客园,作者:闹闹爸爸,转载请注明原文链接:https://www.cnblogs.com/wanglouxiaozi/p/17881933.html