https://github.com/tianocore/edk2
https://github.com/tianocore/edk2-platforms
https://github.com/tianocore/edk2-non-osi
除此之外,还可以使用Linaro的efi编译脚本:
https://git.linaro.org/uefi/uefi-tools.git/
. edk2/edksetup.sh
make -C edk2/BaseTools
$ build -n $NUM_CPUS -a AARCH64 -t GCC5 -p Platform/ARM/JunoPkg/ArmJuno.dsc
主要过程就是加载编译的变量,然后编译好efi工具,efi工具用来编译固件(包含固件生成工具等等),最后就是使用build命令编译某个平台的pkg,build命令行的参数也可以在配置文件指定。具体的参考github了。
脚本更简单一些,一条命令类似于./uefi-tools/edk2-build.sh juno这样就好了,因为脚本里面有个配置文件uefi-tools/edk2-platforms.config写好了每一个板子的配置,当然也可以自己添加自己的板子配置进去。
几个仓库里面,基本上是以模块(module)包(pkg)这两种单位为基本结构,
飞腾E2000Q开发板的UEFI固件编译:
edk2-platforms/Platform/Phytium/CherryPkg/CherryPkg.dsc
#注释掉下面一行
MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
edk2-platforms/Platform/Phytium/CherryPkg/CherryPkg.fdf
#注释掉下面一行
INF MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
可以看出,其实edk2的编译和qt cmake makefile编译方法类似了。
其他未总结的,比如开机热键修改,BIOS菜单修改等等,未完待续(弄驱动这种我肯定是没能力也没精力去写的,改一改配置设置还行)。
/home/user/Documents/e2000/e2000-v1.5_20230608/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd
/home/user/Documents/e2000/e2000-v1.5_20230608/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_VARS.fd
下面是日志
Fd File Name:QEMU_EFI (/home/user/Documents/e2000/e2000-v1.5_20230608/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd)
Generate Region at Offset 0x0
Region Size = 0x1000
Region Name = DATA
Generate Region at Offset 0x1000
Region Size = 0x1FF000
Region Name = FV
Generating FVMAIN_COMPACT FV
Generating FVMAIN FV
#######
Fd File Name:QEMU_VARS (/home/user/Documents/e2000/e2000-v1.5_20230608/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/QEMU_VARS.fd)
Generate Region at Offset 0x0
Region Size = 0x40000
Region Name = DATA
Generate Region at Offset 0x40000
Region Size = 0x40000
Region Name = DATA
Generate Region at Offset 0x80000
Region Size = 0x40000
Region Name = None
GUID cross reference file can be found at /home/user/Documents/e2000/e2000-v1.5_20230608/Build/ArmVirtQemu-AARCH64/DEBUG_GCC5/FV/Guid.xref
FV Space Information
FVMAIN [99%Full] 6865920 (0x68c400) total, 6865880 (0x68c3d8) used, 40 (0x28) free
FVMAIN_COMPACT [58%Full] 2093056 (0x1ff000) total, 1217000 (0x1291e8) used, 876056 (0xd5e18) free
- Done -
Build end time: 14:38:52, Jun.17 2023
Build total time: 00:03:00
------------------------------------------------------------
ArmVirtPkg QEMU (AARCH64) DEBUG pass
------------------------------------------------------------
pass 1
fail 0
然后要使用qemu+kvm测试还需要把这两个文件坐下扩容,不然启动失败
qemu-img resize -f raw QEMU_VARS.fd 64M
qemu-img resize -f raw QEMU_EFI.fd 64M
测试命令
sudo qemu-system-aarch64 -m 4096M \
-machine virt-3.1,accel=kvm,usb=off,dump-guest-core=off,gic-version=3 \
-cpu host \
-drive file=/home/user/temp/QEMU_EFI.fd,if=pflash,format=raw,unit=0,readonly=on \
-drive file=/home/user/temp/QEMU_VARS.fd,if=pflash,format=raw,unit=1 \
-device pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \
-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
-device pcie-root-port,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \
-device pcie-root-port,port=0xb,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \
-device pcie-root-port,port=0xc,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \
-device pcie-root-port,port=0xd,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \
-device virtio-gpu-pci,id=video0,max_outputs=1,bus=pci.5,addr=0x0 \
-netdev tap,id=hostnet0,vhost=on \
-device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:54:fb:35,bus=pci.1,addr=0x0 \
-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \
-device usb-kbd,id=input0,bus=usb.0,port=1 \
-device usb-mouse,id=input1,bus=usb.0,port=2
可以直接图形和串口2个窗口查看启动过程。
build-qemu-efi-aarch64:
$(MAKE) -f debian/rules build-qemu-efi EDK2_ARCH_DIR=AArch64 EDK2_HOST_ARCH=AARCH64 FW_NAME=AAVMF
build-qemu-efi: setup-build
mkdir -p ShellBinPkg/UefiShell/$(EDK2_ARCH_DIR) FatBinPkg/EnhancedFatDxe/$(EDK2_ARCH_DIR)
set -e; . ./edksetup.sh; \
build -a $(EDK2_HOST_ARCH) -p ShellPkg/ShellPkg.dsc \
-b RELEASE -t $(EDK2_TOOLCHAIN); \
cp -a Build/Shell/RELEASE_$(EDK2_TOOLCHAIN)/$(EDK2_HOST_ARCH)/Shell.efi \
ShellBinPkg/UefiShell/$(EDK2_ARCH_DIR)/Shell.efi; \
build -a $(EDK2_HOST_ARCH) -p FatPkg/FatPkg.dsc \
-m FatPkg/EnhancedFatDxe/Fat.inf \
-t $(EDK2_TOOLCHAIN) -b RELEASE; \
cp -a Build/Fat/RELEASE_$(EDK2_TOOLCHAIN)/$(EDK2_HOST_ARCH)/Fat.efi \
FatBinPkg/EnhancedFatDxe/$(EDK2_ARCH_DIR)/Fat.efi; \
build -a $(EDK2_HOST_ARCH) \
-t $(EDK2_TOOLCHAIN) \
-p ArmVirtPkg/ArmVirtQemu.dsc \
$(AAVMF_FLAGS) -b RELEASE
dd if=/dev/zero of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_CODE.fd bs=1M seek=64 count=0
dd if=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/QEMU_EFI.fd of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_CODE.fd conv=notrunc
dd if=/dev/zero of=Build/ArmVirtQemu-$(EDK2_HOST_ARCH)/RELEASE_$(EDK2_TOOLCHAIN)/FV/$(FW_NAME)_VARS.fd bs=1M seek=64 count=0
最后dd那两下差点没看懂,仔细想了下,才发现是直接把文件增大到64M(seek是dd对目标文件跳过多少个bs开始写),debian的这个rules这里发现两个文件也需要扩容到64M。
这里摘抄一张大神书里面的图片,整个启动过程还是比较清晰的,对我目前来说,我就是想改个LOGO,然后BIOS配置界面
稍微做点文字上的自定义(功能就算了,精力跟不上,开发基础也不够)
于是乎,最有用的应该就是BDS阶段,BDS作为一个特殊的DEX加载后,应该就是我的切入点。
查看edk2/ArmVirtPkg/ArmVirtQemu.dsc固件的包描述文件 Bds部分。
#
# Bds
#
MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
<LibraryClasses>
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
}
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Logo/LogoDxe.inf
MdeModulePkg/Application/UiApp/UiApp.inf {
<LibraryClasses>
NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
}
OvmfPkg/QemuKernelLoaderFsDxe/QemuKernelLoaderFsDxe.inf {
<LibraryClasses>
NULL|OvmfPkg/Library/BlobVerifierLibNull/BlobVerifierLibNull.inf
}
盲猜这部分我需要去查看的有
MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Logo/LogoDxe.inf
MdeModulePkg/Application/UiApp/UiApp.inf
这几个模块,通过启动过程的debug日志字符串查找
edk2/MdeModulePkg/Universal/BdsDxe/BdsEntry.c这个文件在UEFI显卡界面显示LOGO并走进度条的时候串口打印
DEBUG ((DEBUG_INFO, "[Bds]BdsWait(%d)..Zzzz...\n", (UINTN)TimeoutRemain));
对于BIOS配置界面,盲猜应该在edk2/MdeModulePkg/Application/UiApp这个模块内,具体看了下代码,dsc文件定义了入口函数是ENTRY_POINT = InitializeUserInterface直接在edk2/MdeModulePkg/Application/UiApp/FrontPage.c文件搜索,这个函数内的UiEntry函数就有 InitializeFrontPage(); 来初始化配置页面,继续跟下去,InitializeFrontPage里面UpdateFrontPageBannerStrings里面读取了smibios来配置bios配置界面的顶部banner,就是下面这个图里面的 CPU 内存
查看文件,发现BIOS配置界面总共有5行,第四第五行都是空的,前面几行都是从SMBIOS接口获取的数据,动态,暂时不研究咋修改,尝试给第四行的空字符串加上自定义的,在文件edk2/MdeModulePkg/Application/UiApp/FrontPageStrings.uni中修改字符串如下:
#string STR_CUSTOMIZE_BANNER_LINE4_LEFT #language en-US "Made by Actionchen"
#language fr-FR ""
#string STR_CUSTOMIZE_BANNER_LINE4_RIGHT #language en-US "2023-06-07"
重新编译固件后再测试,已经显示为自定义的字符串了。
这个其他部分有时间页面慢慢研究,没有开发能力折腾这个是缓慢的。