OS Dev with QEMU, OVMF, and GDB on Windows

According to The OSDev WikiAny recent version of QEMU with a recent version of OVMF will be sufficient to run a UEFI application“. Nice. How do we set this up on a Windows host?

  1. Download a QEMU Windows build from https://qemu.weilnetz.de/w64/ (direct link to the latest version as of the writing of this: https://qemu.weilnetz.de/w64/2020/qemu-w64-setup-20200814.exe ) (Why does this page even have 32-bit builds? Is anyone in 2020 still using a 32-bit computer?)
  2. Install it
  3. Download the latest Open Virtual Machine Firmware x86-64 build (which is part of Tianocore EFI Development Kit 2) from https://www.kraxel.org/repos/jenkins/edk2/ (direct link to the latest version as of the writing of this: https://www.kraxel.org/repos/jenkins/edk2/edk2.git-ovmf-x64-0-20201023.1487.g2363c69260.noarch.rpm )
  4. Extract the .rpm using 7zip or some other archive opening tool.
  5. Make a batch file to test out QEMU + OVMF:
    "c:\Program Files\qemu\qemu-system-x86_64.exe" -bios "C:\<path where you extracted the rpm>\usr\share\edk2.git\ovmf-x64\OVMF-pure-efi.fd"
  6. When you run it, you should get a message like “BdsDxe: failed to load Boot0001…” and it should eventually dump you into a UEFI shell. This means OVMF is running.
  7. Now modify the batch file to add a few flags. We need to listen on the default GDB port:
    "c:\Program Files\qemu\qemu-system-x86_64.exe" -bios "C:\<path where you extracted the rpm>\usr\share\edk2.git\ovmf-x64\OVMF-pure-efi.fd" -s -S
  8. Now run it again. The UEFI bootloader shouldn’t run. QEMU is waiting for us to connect via GDB and tell it to start running.
  9. We’ll need a GDB that works on Windows. Codesourcery (now part of Mentor Graphics) has cross-compiler toolchains, including a “Linux” GDB that will run on Windows. https://www.mentor.com/embedded-software/toolchain-services/ (Direct link to the latest version as of the writing of this: https://sourcery.mentor.com/GNUToolchain/package14750/public/x86_64-amd-linux-gnu/amd-2016.11-19-x86_64-amd-linux-gnu.exe – later versions are source-only and don’t have builds(?!) )
  10. Let’s make another batch file to test running our newly-installed Windows-compiled GDB!:
  11. Run that, and you should get a GDB terminal.
  12. Type “target remote tcp::1234“. GDB should complain that no executable has been specified, which verifies that it’s connected and found that to be true!
  13. Type “continue“, and the UEFI bootloader should run!
  14. From here, it’ll be a good idea to create a kernel and try to add a breakpoint.
  15. Here’s a blog post on how to create a simple kernel that just prints “OK” to the console: https://os.phil-opp.com/multiboot-kernel/
  16. NASM Windows builds can be found here: https://www.nasm.us/pub/nasm/releasebuilds/
  17. Following the above blog post should be straightforward, but as a hint, here’s my batch file for creating the kernel.bin file:
    "C:\Program Files\NASM\nasm.exe" multiboot_header.asm
    "C:\Program Files\NASM\nasm.exe" boot.asm
    "C:\Program Files\NASM\nasm.exe" -f elf64 boot.asm
    "C:\Program Files\NASM\nasm.exe" -f elf64 multiboot_header.asm
    "C:\mgc\embedded\codebench\bin\x86_64-amd-linux-gnu-ld.exe" -n -o kernel.bin -T linker.ld multiboot_header.o boot.o
  18. TODO: Probably want to backtrack here a bit and create an EFI executable instead. Probably using NASM, because GNU-EFI does too much of the work for us, and this is primarily a learning adventure for me.

Leave a Reply

%d bloggers like this: