EDK2環境搭建 & QEMU雙平臺安裝
EDK2環境搭建
本文涉及OVMF虛擬機固件鏡像的編譯,以及在Windows和Linux(Ubuntu)上分別安裝QEMU虛擬機加載鏡像文件,執行HelloWorld程序。
一、TianoCore的官方介紹
Welcome to TianoCore, the community supporting an open source implementation of the Unified Extensible Firmware Interface (UEFI). EDK II is a modern, feature-rich, cross-platform firmware development environment for the UEFI and UEFI Platform Initialization (PI) specifications. We hope that you’ll review our wiki documentation, use TianoCore for platform firmware, report any issues you find, and contribute to the community.
TianoCore 致力于支持 UEFI(統一可擴展固件接口)的開源實現。EDK II 是一個現代化、功能強大且跨平臺的固件開發環境,完全遵循 UEFI 及 UEFI PI(平臺初始化)規范。
二、UEFI & EDKII & OVMF
- UEFI是一種標準或者規范手冊。它定義了系統的啟動流程,實現從硬件到操作系統的引導過程,定義了固件與操作系統之間的接口。比方說要蓋房子,規范就規定了房子要有承重墻,電路布線規則,門窗大小等。
- EDK2的全稱是EFI Development Kit II,是由Intel主導的開源UEFI開發框架。開發者可以基于EDK2編寫自己的UEFI固件。
- OVMF全稱是Open Virtual Machine Firmware,是EDK2的一個子項目,專門針對QEMU虛擬機環境提供UEFI支持。輸出的文件通常是
OVMF.fd或者OVMF_CODE.fd/OVMF_VARS.fd。
三、EDK2環境搭建
-
安裝依賴
sudo apt update sudo apt install -y build-essential uuid-dev iasl git nasm\ python3-distutils python2-pip python3-setuptools python3-venv python3-dev\ flex bison openssl libssl-dev libpython3-dev -
獲取源碼
# edk2的GitHub官網 https://github.com/tianocore/edk2/tree/master # 獲取穩定版本 git clone https://github.com/tianocore/edk2.git -b stable/202011mkdir -p ~/src cd ~/src git clone https://github.com/tianocore/edk2.git -b stable/202011 cd edk2 git submodule update --initgit submodule update --init的作用是從當前倉庫的配置.gitmodules里讀取子倉庫submodule列表, 初始化并把這些子倉庫檢出到對應的子目錄。涉及的關鍵文件,
.gitmodules:主倉庫里的文本文件,記錄了哪些路徑是子模塊以及子模塊的遠程URL。例如[submodule "BaseTools"] path = BaseTools url = https://github.com/tianocore/edk2-BaseTools.git常用選項:
--recursive:對子模塊內嵌套的子模塊也遞歸執行--init和update。 -
編譯
BaseToolscd ~/src/edk2 make -C BaseTools # 完成后期望看到 GenFv GenFw GenFfs VolInfo 等工具 ls -l BaseTools/Source/C/bin -
初始化構建環境
cd ~/src/edk2 source edksetup.sh這一步會在
Conf/下生成targart.txt、tool_def.txt。如果以后每次打開新shell要構建,可以把這句加入到~/.bashrc。 -
編輯
Conf/targart.txt# 適用于本地x86_64的最小配置 ACTIVE_PLATFORM = OvmfPkg/OvmfPkgX64.dsc TARGET = DEBUG TARGET_ARCH = X64 TOOL_CHAIN_TAG = GCC5 BUILD_RULE_CONF = Conf/build_rule.txtACTIVE_PLATFORM指向要構建的Platform.dsc(這里是OVMF x64)。
TOOL_CHAIN_TAG = GCC5這里的GCC5是默認選項,不用改成GCC。
TARGET有兩個常用的選項,分別是DEBUG和RELEASE。二者分別表示編譯的固件版本為調試版本和發布版本。調試版本幾乎不會編譯優化,保留完整的調試符號,鏡像較大,啟動速度略慢,用于固件的開發、調試、驗證階段。 -
構建
OVME(x64固件)cd ~/src/edk2 source edksetup.sh # 需要注意的是,在編輯過Conf/targart.txt之后可以直接build build -a X64 -t GCC5 -p OvmfPkg/OvmfPkgX64.dsc -b DEBUG # 構建成功后,固件文件位于 ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV/ # 重要文件示例:OVMF_CODE.fd OVMF_VARS.fd OVMF.fd此時其實固件已經生成完畢了。
-
生成直接可用的
bios.bin(可選)cd ~/src/edk2/Build/OvmfX64/DEBUG_GCC5/FV cat OVMF_CODE.fd OVMF_VARS.fd > ~/run-ovmf/bios.bin # 校驗大小接近 OVMF_CODE + OVMF_VARS ls -lh ~/run-ovmf/bios.bin -
創建測試用的FAT磁盤目錄
mkdir -p ~/run-ovmf/hda-contents/EFI/BOOT把一個
64-bit的EFI程序放進去,下面編譯HelloWorld。 -
HelloWorld編譯# 默認HelloWorld的位置在:MdeModulePkg/Application/HelloWorld/HelloWorld.inf build -a X64 -t GCC5 -p MdeModulePkg/MdeModulePkg.dsc -m MdeModulePkg/Application/HelloWorld/HelloWorld.inf # 生成的文件路徑:Build/MdeModule/DEBUG_GCC5/X64/HelloWorld.efi cp ~/src/edk2/Build/MdeModule/DEBUG_GCC5/X64/HelloWorld.efi hda-contents/EFI/BOOT/BOOTX64.EFI -
運行
QEMUqemu-system-x86_64 -bios /home/ayuan/run-ovmf/OVMF.fd -drive format=raw,file=fat:rw:/home/ayuan/run-ovmf/hda-contents -m 512M cat OVMF_CODE.fd OVMF_VARS.fd > ~/run-ovmf/bios.bin qemu-system-x86_64 \ -bios /home/ayuan/run-ovmf/bios.bin \ -drive format=raw,file=fat:rw:/home/ayuan/run-ovmf/hda-contents \ -m 1024M以上兩個命令有所區別。
OVMF.fd的固件結構是單文件,是CODE和VARS在一起的。其中CODE是UEFI的代碼段,VARS是內嵌的變量存儲區,這種情況下啟動后修改的UEFI變量不會持久保存,下次啟動會恢復初始狀態。與之相反的是第二條命令,其可以持久保存UEFI的設置。
在Ubuntu20.04上運行QUMU遇到的問題以及解決方法
一、執行QEMU界面卡住,無法進入shell
-
直接使用命令
sudo apt install qemu-system-x86_64安裝的版本在執行時會卡到Guest has not initialized the display (yet)界面,無法進入下一步,如圖1所示。
圖1:錯誤頁面示意圖 - 考慮是
QEMU虛擬機版本的問題,所以接下來嘗試兩種解決方法,一種是使用Windows安裝QEMU虛擬機運行自Linux編譯出的OVMF固件鏡像。另一種是在Ubuntu上利用源碼編譯出更高版本的QEMU虛擬機。
- 考慮是
二、Windows上安裝QEMU執行OVMF.fd
安裝步驟(只講關鍵步驟)
-
下載版本如圖二。
圖2:win下qemu下載版本 -
正常步驟安裝即可。
-
將安裝路徑
D:\Program Files\qemu添加至環境變量path,直接搜索環境變量即可。
圖3:添加環境變量 -
安裝完畢確認。
qemu-system-x86_64 -version -
執行。
qemu-system-x86_64 -bios D:\users\wsy\Desktop\EDK2\edk2\run-ovmf\bios.bin -drive format=raw,file=fat:rw:D:\users\wsy\Desktop\EDK2\edk2\run-ovmf\hda-contents -m 512M -
進入
shell。
Boot Manager->EFI Interal Shell進入到shell。進入對應的目錄執行
HelloWorld。
圖4:執行HelloWorld
-
三、Ubuntu上編譯出更高版本的QEMU
3.1 使用apt命令安裝qemu
# 安裝基礎的QEMU包
sudo apt update
sudo apt install qemu-kvm qemu-utils
# 常用的組件有
# qemu-kvm: KVM加速支持
# qemu-utils: QEMU工具集(qemu-img等)
# qemu-system: 完整的系統模擬器(可替換為特定架構)
# virt-manager: 圖形化管理工具(可選)
# 可以安裝完整的QEMU套件,也可以安裝特定架構的QEMU
sudo apt install qemu-system qemu-utils virt-manager
# 或者
sudo apt install qemu-system-x86
# 驗證安裝
qemu-system-x86_64 --version
# 此時安裝上的版本是6.0,上面我們提到默認的版本太低了,可能導致問題。所以接下來的命令是獲取更高版本的源碼,編譯安裝。
3.2 舊版本qemu卸載
卸載方式與安裝方式有關,我用到的安裝方式有兩種,一種是通過apt命令直接下載,另一種是git clone源碼編譯,兩種安裝方式對應著兩種卸載方式。
如果是通過apt安裝的:
sudo apt remove --purge qemu qemu-system qemu-utils qemu-kvm
sudo apt autoremove --purge
sudo apt clean
# 查看是否殘留,如果還有相關殘留,繼續remove即可
dpkg -l | grep qemu
如果是通過源碼編譯安裝的:
cd /home/name/src/qemu
sudo make uninstall
# 如果沒有uninstall目標,可以手動刪除QEMU的安裝文件
sudo rm -f /usr/local/bin/qemu-system-* \
/usr/local/bin/qemu-img \
/usr/local/bin/qemu-nbd \
/usr/local/bin/qemu-pr-helper
sudo rm -rf /usr/local/share/qemu
sudo rm -rf /usr/local/libexec/qemu
sudo rm -rf /usr/local/include/qemu
# 清理舊的配置或者殘留
sudo ldconfig
# 驗證
which qemu-system-x86_64
ls /usr/local/bin | grep qemu
3.3 qemu源碼克隆編譯
-
qemu項目的git地址為https://github.com/qemu/qemu/tree/master。 -
克隆和編譯步驟。
# 如果不加-b stable-9.0則克隆下來的是最新版本,但不是最新穩定版,這里我們選擇9.0的穩定版本。 git clone https://github.com/qemu/qemu.git -b stable-9.0 # 安裝常用的依賴 sudo apt update sudo apt install -y \ git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev \ libaio-dev libbluetooth-dev libbrlapi-dev libcap-dev libcurl4-gnutls-dev \ libgtk-3-dev libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev \ librbd-dev librdmacm-dev libsasl2-dev libsdl2-dev libseccomp-dev \ libsnappy-dev libssh-dev libvde-dev libvte-2.91-dev libxen-dev \ liblzo2-dev python3 python3-pip pkg-config ninja-build上面列出的依賴介紹(這里我自己好奇用
ChatGPT搜了一下,大家可以直接安裝即可)。?? 一、基礎構建工具(編譯器和構建系統) 包名 作用說明 git 用來克隆 QEMU 源碼倉庫。 pkg-config 用來在編譯時查找庫的頭文件和鏈接參數(自動生成 -I、-L 選項)。 python3 QEMU 的構建腳本使用 Python 編寫。 python3-pip 用于安裝額外的 Python 構建模塊(如 meson、ninja)。 ninja-build QEMU 使用的現代化構建系統(比 make 更快)。 ?? 二、核心依賴(QEMU 模擬和設備框架) 包名 作用說明 libglib2.0-dev QEMU 使用的核心工具庫,提供事件循環、線程、數據結構(必須)。 libfdt-dev 支持設備樹(Flattened Device Tree),在 ARM 平臺或嵌入式模擬中使用。 libpixman-1-dev 圖像像素操作庫,QEMU 的圖形輸出(SDL/VNC)依賴它。 zlib1g-dev 壓縮庫,QEMU 用它來支持壓縮磁盤鏡像(qcow2 等)。 ?? 三、I/O 與虛擬化設備支持 包名 作用說明 libaio-dev 異步 I/O 支持(提升磁盤讀寫性能)。 libnuma-dev 支持 NUMA(多CPU內存架構),在多核模擬時使用。 libseccomp-dev 啟用沙盒隔離,提升安全性(防止主機被虛擬機訪問)。 libcap-dev 支持 Linux capability 權限控制。 libxen-dev 支持 Xen 虛擬化環境的接口。 libvde-dev 支持虛擬分布式以太網(Virtual Distributed Ethernet)實現虛擬機間互聯。 ?? 四、網絡與遠程訪問支持 包名 作用說明 libcurl4-gnutls-dev 讓 QEMU 能通過 HTTP/HTTPS 下載鏡像或遠程訪問資源。 libsasl2-dev 用于遠程認證(SMTP、VNC 登錄等)。 libssh-dev 支持通過 SSH 協議訪問磁盤鏡像或遠程遷移虛擬機。 librdmacm-dev / libibverbs-dev 支持 RDMA(遠程直接內存訪問),加速虛擬機之間通信。 librbd-dev 提供對 Ceph RADOS 塊設備(分布式存儲)的支持。 ??? 五、圖形界面與輸入輸出支持 包名 作用說明 libsdl2-dev SDL 圖形庫,提供基本的 GUI 窗口(QEMU 的顯示輸出)。 libgtk-3-dev GTK 圖形界面庫,使 QEMU 的 GUI 更現代(帶菜單欄、控制按鈕)。 libvte-2.91-dev 終端控件支持(用于 QEMU 的 GTK 版內置終端)。 libjpeg8-dev JPEG 圖像支持(VNC 輸出截圖、視頻編碼)。 liblzo2-dev 壓縮支持庫(用于 qcow2 壓縮鏡像)。 libsnappy-dev Google Snappy 壓縮支持,提高磁盤鏡像 I/O 性能。安裝過程中如遇依賴問題,可以使用
aptitude命令獲取解決方案后繼續安裝,舉例如下。# 以libgtk-3-dev為例,安裝時遇到如下問題 ayuan@ayuan-virtual-machine:~/src/qemu$ sudo apt install libgtk-3-dev ... 下列軟件包有未滿足的依賴關系: libpango1.0-dev : 依賴: gir1.2-pango-1.0 (= 1.50.6+ds-2) 但是 1.50.6+ds-2ubuntu1 正要被安裝 ...... E: 無法修正錯誤,因為您要求某些軟件包保持現狀,就是它們破壞了軟件包間的依賴關系。 ayuan@ayuan-virtual-machine:~/src/qemu$ # 解決方法 sudo aptitude install libgtk-3-dev # 然后出現如下字樣 保持 下列軟件包于其當前版本: 1) libgtk-3-dev [未安裝的] 是否接受該解決方案?[Y/n/q/?] # 如果選擇Y,那么該依賴仍然不會被安裝,所以這里選擇n,此時: 安裝 下列軟件包: 1) icu-devtools [70.1-2 (jammy)] 2) libdatrie-dev [0.2.13-2 (jammy)] 3) libgraphite2-dev [1.3.14-1build2 (jammy)] 4) libharfbuzz-dev [2.7.4-1ubuntu3.2 (jammy-security)] 5) libharfbuzz-gobject0 [2.7.4-1ubuntu3.2 (jammy-security)] 6) libicu-dev [70.1-2 (jammy)] 7) libpango1.0-dev [1.50.6+ds-2 (jammy)] 8) libthai-dev [0.1.29-1build1 (jammy)] 9) libxft-dev [2.3.4-1 (jammy)] 10) pango1.0-tools [1.50.6+ds-2 (jammy)] 降級 下列軟件包: 11) gir1.2-pango-1.0 [1.50.6+ds-2ubuntu1 (now) -> 1.50.6+ds-2 (jammy)] 12) libpango-1.0-0 [1.50.6+ds-2ubuntu1 (now) -> 1.50.6+ds-2 (jammy)] 13) libpangocairo-1.0-0 [1.50.6+ds-2ubuntu1 (now) -> 1.50.6+ds-2 (jammy)] 14) libpangoft2-1.0-0 [1.50.6+ds-2ubuntu1 (now) -> 1.50.6+ds-2 (jammy)] 15) libpangoxft-1.0-0 [1.50.6+ds-2ubuntu1 (now) -> 1.50.6+ds-2 (jammy)] 是否接受該解決方案?[Y/n/q/?] # 這時候就可以選擇Y,進行安裝了。接下來是主要的安裝流程,安裝過程中也會遇到一些依賴問題,可以用AI搜索解決這里不過多贅述。
注:如果遇到類似缺少某個頭文件
.h,通常可以按以下規律解決:缺失頭文件 對應開發包(Ubuntu) libusb.h / libusb-1.0/libusb.h libusb-1.0-0-dev glib.h libglib2.0-dev pixman.h libpixman-1-dev snappy-c.h libsnappy-dev gnutls/gnutls.h libgnutls28-dev nettle/nettle.h libnettle-devcd qemu/ mkdir build && cd build ../configure \ --prefix=/usr/local/qemu \ --target-list=x86_64-softmmu,aarch64-softmmu \ --enable-kvm \ --enable-sdl \ --enable-gtk \ --enable-vnc \ --enable-curses \ --enable-debug \ --enable-libusb \ --enable-nettle \ --enable-snappy \ --enable-gnutls \ --enable-opengl ninja # 或者更快的ninja -j$(nproc) sudo ninja install # 安裝完成后會有 prefix : /usr/local/qemu在終端顯示,這就是安裝位置。 # 驗證安裝是否成功 /usr/local/qemu/bin/qemu-system-x86_64 --version # 為了在任何路徑都能調用該命令,添加環境變量 echo 'export PATH=/usr/local/qemu/bin:$PATH' >> ~/.bashrc -
經過以上步驟安裝新版本的
qemu之后,再次執行我們編譯好的固件,問題得到了解決。
參考文章
【1】ChatGPT
【2】https://blog.csdn.net/qq_36035382/article/details/125308044
每天進步一點點,腳踏實地!

本文簡單介紹了Linux環境下搭建EDK2開發環境的關鍵步驟和命令。
浙公網安備 33010602011771號