EDKII 环境搭建 & 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

  1. UEFI是一种标准或者规范手册。它定义了系统的启动流程,实现从硬件到操作系统的引导过程,定义了固件与操作系统之间的接口。比方说要盖房子,规范就规定了房子要有承重墙,电路布线规则,门窗大小等。
  2. EDK2的全称是EFI Development Kit II,是由Intel主导的开源UEFI开发框架。开发者可以基于EDK2编写自己的UEFI固件。
  3. OVMF全称是Open Virtual Machine Firmware,是EDK2的一个子项目,专门针对QEMU虚拟机环境提供UEFI支持。输出的文件通常是OVMF.fd或者OVMF_CODE.fd / OVMF_VARS.fd

三、EDK2环境搭建

  1. 安装依赖

    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
    
  2. 获取源码

    # edk2的GitHub官网 https://github.com/tianocore/edk2/tree/master
    # 获取稳定版本
    git clone https://github.com/tianocore/edk2.git -b stable/202011
    
    mkdir -p ~/src
    cd ~/src
    git clone https://github.com/tianocore/edk2.git -b stable/202011
    cd edk2
    git submodule update --init
    

    git submodule update --init的作用是从当前仓库的配置.gitmodules里读取子仓库submodule列表, 初始化并把这些子仓库检出到对应的子目录。

    涉及的关键文件,.gitmodules:主仓库里的文本文件,记录了哪些路径是子模块以及子模块的远程URL。例如

    [submodule "BaseTools"]
      path = BaseTools
      url = https://github.com/tianocore/edk2-BaseTools.git
    

    常用选项:--recursive:对子模块内嵌套的子模块也递归执行--initupdate

  3. 编译BaseTools

    cd ~/src/edk2
    make -C BaseTools
    
    # 完成后期望看到 GenFv GenFw GenFfs VolInfo 等工具
    ls -l BaseTools/Source/C/bin
    
  4. 初始化构建环境

    cd ~/src/edk2
    source edksetup.sh
    

    这一步会在Conf/下生成targart.txt、tool_def.txt。如果以后每次打开新shell要构建,可以把这句加入到~/.bashrc。

  5. 编辑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.txt
    

    ACTIVE_PLATFORM指向要构建的Platform.dsc(这里是OVMF x64)。
    TOOL_CHAIN_TAG = GCC5这里的GCC5是默认选项,不用改成GCC
    TARGET有两个常用的选项,分别是DEBUGRELEASE。二者分别表示编译的固件版本为调试版本和发布版本。调试版本几乎不会编译优化,保留完整的调试符号,镜像较大,启动速度略慢,用于固件的开发、调试、验证阶段。

  6. 构建OVMEx64固件)

    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
    

    此时其实固件已经生成完毕了。

  7. 生成直接可用的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
    
  8. 创建测试用的FAT磁盘目录

    mkdir -p ~/run-ovmf/hda-contents/EFI/BOOT
    

    把一个 64-bitEFI 程序放进去,下面编译HelloWorld

  9. 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
    
  10. 运行QEMU

    qemu-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的固件结构是单文件,是CODEVARS在一起的。其中CODE是UEFI的代码段,VARS是内嵌的变量存储区,这种情况下启动后修改的UEFI变量不会持久保存,下次启动会恢复初始状态。与之相反的是第二条命令,其可以持久保存UEFI的设置。

在Ubuntu20.04上运行QUMU遇到的问题以及解决方法

一、执行QEMU界面卡住,无法进入shell

  1. 直接使用命令sudo apt install qemu-system-x86_64安装的版本在执行时会卡到Guest has not initialized the display (yet)界面,无法进入下一步,如图1所示。

    图1:错误页面示意图
    1. 考虑是QEMU虚拟机版本的问题,所以接下来尝试两种解决方法,一种是使用Windows安装QEMU虚拟机运行自Linux编译出的OVMF固件镜像。另一种是在Ubuntu上利用源码编译出更高版本的QEMU虚拟机。

二、Windows上安装QEMU执行OVMF.fd

安装步骤(只讲关键步骤)

  1. 下载地址:https://qemu.weilnetz.de/w64/

  2. 下载版本如图二。

    图2:win下qemu下载版本
    1. 正常步骤安装即可。

    2. 将安装路径D:\Program Files\qemu添加至环境变量path,直接搜索环境变量即可。

      图3:添加环境变量
    3. 安装完毕确认。

      qemu-system-x86_64 -version
      
    4. 执行。

      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
      
    5. 进入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源码克隆编译

  1. qemu项目的git地址为https://github.com/qemu/qemu/tree/master。

  2. 克隆和编译步骤。

    # 如果不加-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-dev
    
    cd 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
    
  3. 经过以上步骤安装新版本的qemu之后,再次执行我们编译好的固件,问题得到了解决。

参考文章

【1】ChatGPT

【2】https://blog.csdn.net/qq_36035382/article/details/125308044


每天进步一点点,脚踏实地!

posted @ 2025-10-29 00:11  阿源-  阅读(119)  评论(0)    收藏  举报