TL;DR: The main problem is that you can't run an EFI application directly with QEMU's -kernel
option. -kernel
is meant for starting Multiboot compliant executables or loading Linux bzImage files.
Since your question suggests you have managed to compile and link an EFI application with one of the tutorials, this answer will strictly focus on methods of running it with QEMU. Which tutorial or method you followed to build the EFI application itself doesn't matter.
Use this command in your project directory to create a series of subdirectories for use as an EFI boot drive:
mkdir -p bootdrv/EFI/BOOT/
You only have to create the directories once. Once they have been created, copy your hello.efi
file to the file named bootdrv/EFI/BOOT/BOOTX64.EFI
. EFI/BOOT/BOOTX64.EFI
is the default boot file for 64-bit UEFI. On 32-bit UEFI the default boot file is EFI/BOOT/BOOTIA32.EFI
. Run the following command to launch your EFI program:
qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw
This mounts the bootdrv
directory as a FAT file system in the emulator as the first hard drive. 64-bit EFI should automatically run the file EFI/BOOT/BOOTX64.EFI
As an alternative you can copy your hello.efi
file to the directory bootdrv/EFI/BOOT/
, and create a startup script with the name bootdrv/EFI/BOOT/startup.nsh
containing the following commands:
\EFI\BOOT\hello.efi
pause
EFI/BOOT/startup.nsh
is the default startup script that will be run in the absence of a default EFI application. The file should contain a blank line after the last command. The command \EFI\BOOT\hello.efi
runs hello.efi
and pause
prompts to press a key. You don't have to specify pause
, it's just convenient if the program you run exits back to the shell. You can run it with same command as before:
qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:bootdrv,format=raw
This mounts the bootdrv
directory as a FAT file system in the emulator as the first hard drive. EFI will load EFI/BOOT/startup.nsh
as a startup script and execute the commands contained in it. That should automatically run hello.efi
.