Skip to content

Instantly share code, notes, and snippets.

@theomacx86
Last active September 11, 2022 23:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theomacx86/3abf8854a013fc5226045671de63a900 to your computer and use it in GitHub Desktop.
Save theomacx86/3abf8854a013fc5226045671de63a900 to your computer and use it in GitHub Desktop.
GSOC 2022 - QemuOpenBoardPkg

GSOC 2022 - QemuOpenBoardPkg

Théo Jehl - theojehl76@gmail.com

Mentors:

Isaac Oram - isaac.w.oram@intel.com

Pedro Falcato - pedro.falcato@gmail.com

This document covers the creation of QemuOpenBoardPkg, a board port following the MinPlatform specification, mentored by Isaac Oram and Pedro Falcato.

Overview

The board port aims to be a simple, easy-to-understand package for QEMU that provides a starting place for new developers interested in board ports, or current firmware developers who are new to the MinPlatform specification.

Thanks to OVMF, not everything had to be done from scratch, the direction chosen for this package was a mix of code re-use and creation of new modules. Pre-EFI initialization code was re-written with only the essential elements, to give a starting point in x86_64 initialization code.

Tools used

QEMU

QEMU is an open-source emulation and virtualization software .For this project, we focused solely on QEMU's x86 emulation. It provides support for two Intel chipsets:

  • i440FX/PIIX4
  • MCH/Q35

With those chipsets, QEMU emulates other devices, such as a Cirrus video card, a serial port, and the NE2000 network card. Qemu also allows virtualization using a hypervisor like KVM or Xen.

MinPlatform

MinPlatform is a specification used to define code and boot flow, organized around stages, defining the built code and the expected functionalities in each stage. The board port implements only minimal functionalities to achieve a basic working solution that can be extended to meet different systems expectations.

In the current state, MinPlatform defines 6 stages

  • I: Minimal debug (Temporary memory, board-specific pre-memory init..)
  • II: Memory functional (Install permanent memory, post-memory init)
  • III: Boot to UEFI shell (Loads DXE and DXE modules, boots to UEFI shell)
  • IV: Boot to OS (ACPI, SMM initialization..)
  • V: Security enable (Non-volatile variable storage, secure boot)
  • VI: Advanced features (non-essential features)

Work achieved

These commits (V2) have not yet been merged at the time of writing. To follow the MinPlatform idea and to make stage implementation history easier to read, each commit corresponds to a MinPlatform stage.

Cover letter

QemuOpenBoardPkg: Add QemuOpenBoardPkg

QemuOpenBoardPkg: Enable stage 2

QemuOpenBoardPkg: Enable stage 3

QemuOpenBoardPkg: Enable stage 4

Clarity was the main objective of the package. Boot flow must be easy and quick to understand. Modules and libraries are split into different FDF and DSC files, each one corresponding to a MinPlatform stage.

This package is a mix of OVMFand new modules. The first thing to be rewritten was the Platform initialization PEI module. For both learning and GSOC purpose, this module performs minimal CPU, memory, and PCI/PCIe initialization. PlatformSecLib was also rewritten, serving as an example of a simple IA32 reset vector.

The target architecture for PEI and DXE core/modules can be set independently for future modularity. In the current state, PEI must be built for IA32, as the reset vector does not yet support x86_64. DXE core and modules can be built for IA32 or x86_64

The package implements up to stage 4 of the specification, due to PIIX4/i440FX small amount of allocatable SMRAM, SMM support is only reserved for Q35 systems.

In the current state, the package can boot an operating system like UEFI Windows or Linux. It also supports KVM.

Challenges

  • Since I had no prior experience with UEFI before this GSOC, I had to get used to EDK2 codebase, style, build systems and PCDs, getting started with UEFI was extremely rewarding, dramatically increasing my knowledge of x86_64 initialization.
  • QEMU provides an already working memory and passes E820 entries via a special device called QEMU FW CFG, not all memory being usable memory, a lot of memory overlapping happened during the project, allowing me to learn about memory mapped devices like PCIe, APIC or the shadow bios area below 1Mb.
  • Library overlapping happened with the mix of libraries being quickly confusing when starting. Situations where the Pcd module would not load because of a module calling itself the non-initialized PCD lib would lead to the boot being stuck because of those loops.
  • MinPlatformPkg includes files are not up-to-date with the spec and don't contain the correct libraries. I came up with the stage-driven include files used in the project. Those are subject to debate in the next section.
  • Memory below 4Gb: QEMU only allows usable memory from 0 to 2.8Gb, the rest being reserved for memory-mapped devices, leading again to memory overlapping issues. To circumvent this, PEI Core is only allowed to use the biggest chunk of contiguous memory available below 2.8Gb, even if built using x86_64.
  • LibraryClasses can have multiple instances, they can be set for CPU architecture, for driver type, and per-driver. Hence it's easy to get lost and use the wrong libraries. The report generated at build came up very handy in these situations. Even with a well written DSC file, it's easy to make mistakes.
  • When starting up the project, most of the FVs were empty. With time a lot of FVs and FD resizing took place to accomodate for all the required modules. It often lead to a mis-aligned reset vector and a non-bootable image. A FlashMap was then used to calculate dynamically most of the PCDs to reduce the risk of breaking the package with miscalculations.

Bugs / Issues

  • Secure boot does not work, persistent storage is not yet working.

Evolution

The goal, in the long run, would be to provide a learning oriented progression, from very basic QEMU drivers to fully featured OVMF drivers. This would entail new, very basic drivers leveraging OVMF libraries and clear steps to use the more feature rich OVMF drivers as one becomes more familiar with edk2, QEMU, and OVMF. The first one is QEMU FVB service (still in development at the time of writting), allowing for persistent storage.

The current architecture of the DSC and FDF include files is being discussed, currently, it's one FDF and one DSC per stage, functionalities like ACPI, SMBIOS, and SMM are not clearly separated. Stages could be split into functionalities per stages. With further improvements, it could be re-used in MinPlatformPkg itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment