# UEFI HTTP Boot with Libvirt ## UEFI boot sequence * For OS installation, EFI cannot find a bootable device by traversing its BootOrder entries. * HTTP boot has been supported by UEFI 2.5[^1]. * As EFI Boot Manger moves on to find a bootable, removable device, it looks for an EFI partition, formatted in Fat32, Fat16 or Fat12 with an \EFI\Boot\ directory structure and that BOOTX64.EFI is in that directory. * DHCP server will provide BOOTX64.EFI according to option `dhcp-boot=tag:efi-http,&quot;http://192.168.100.1/httpboot/EFI/BOOT/BOOTX64.EFI&quot;`. In this case this option will be configured into libvirt network setting. * `BOOTX64.EFI` is GRUB EFI application which reads its configuration from the `/EFI/BOOT/grub.cfg` file(the same direcotry as where the `BOOTX64.EFI` is located) on boot media(boot.iso, or network boot). This file contains menu information. * The GRUB2 boot loader is used on systems with UEFI firmware * The GRUB2 configuration file is `EFI/BOOT/grub.cfg` on the boot media. * `inst.stage2=` boot option in grub.cfg specifies the location of the installation program runtime image. [`HTTP`](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/performing_an_advanced_rhel_installation/kickstart-and-advanced-boot-options_installing-rhel-as-an-experienced-user#installation-source-boot-options_kickstart-and-advanced-boot-options) is one of supported boot option. * `linuxefi` - this option defines which kernel will be booted. * `initrdefi` - location of the initial RAM disk (initrd) image to be loaded. * In a Linux system, the kernel and the initial ramdisk (or initrd) play major roles for loading the operating system from a disk drive and into memory (or RAM) ## Libvirt network configuration ```xml <network xmlns:dnsmasq='http://libvirt.org/schemas/network/dnsmasq/1.0'> <name>integration</name> <uuid>1c8fe98c-b53a-4ca4-bbdb-deb0f26b3579</uuid> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <bridge name='integration' stp='on' delay='0'/> <mac address='52:54:00:36:46:ef'/> <ip address='192.168.100.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.100.2' end='192.168.100.254'/> <host mac='34:49:22:B0:83:30' name='vm' ip='192.168.100.50'/> </dhcp> </ip> <dnsmasq:options> <dnsmasq:option value='dhcp-vendorclass=set:efi-http,HTTPClient:Arch:00016'/> <dnsmasq:option value='dhcp-option-force=tag:efi-http,60,HTTPClient'/> <dnsmasq:option value='dhcp-boot=tag:efi-http,&quot;http://192.168.100.1/httpboot/EFI/BOOT/BOOTX64.EFI&quot;'/> </dnsmasq:options> ``` ## grub.cfg to install from HTTP server ```shell=bash set default="3" function load_video { insmod efi_gop insmod efi_uga insmod video_bochs insmod video_cirrus insmod all_video } load_video set gfxpayload=keep insmod gzio insmod part_gpt insmod ext2 set timeout=-1 ### END /etc/grub.d/00_header ### search --no-floppy --set=root -l 'RHEL-8-4-0-BaseOS-x86_64' ### BEGIN /etc/grub.d/10_linux ### menuentry 'Install Red Hat Enterprise Linux 8.4' --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=RHEL-8-4-0-BaseOS-x86_64 quiet initrdefi /images/pxeboot/initrd.img } menuentry 'Test this media & install Red Hat Enterprise Linux 8.4' --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=RHEL-8-4-0-BaseOS-x86_64 rd.live.check quiet initrdefi /images/pxeboot/initrd.img } submenu 'Troubleshooting -->' { menuentry 'Install Red Hat Enterprise Linux 8.4 in basic graphics mode' --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=RHEL-8-4-0-BaseOS-x86_64 nomodeset quiet initrdefi /images/pxeboot/initrd.img } menuentry 'Rescue a Red Hat Enterprise Linux system' --class fedora --class gnu-linux --class gnu --class os { linuxefi /images/pxeboot/vmlinuz inst.stage2=hd:LABEL=RHEL-8-4-0-BaseOS-x86_64 rescue quiet initrdefi /images/pxeboot/initrd.img } } menuentry 'Install Red Hat Enterprise Linux for Edge 8.4' --class fedora --class gnu-linux --class gnu --class os { linuxefi /httpboot/images/pxeboot/vmlinuz inst.stage2=http://192.168.100.1/httpboot inst.ks=http://192.168.100.1/ks.cfg quiet initrdefi /httpboot/images/pxeboot/initrd.img } ``` ## virt-install to work with HTTP boot and installation ```shell=bash sudo virt-install --name="httpboot"\ --disk path="/var/lib/libvirt/images/httpboot.qcow2",format=qcow2 \ --ram 3072 \ --vcpus 2 \ --network network=integration,mac=34:49:22:B0:83:30 \ --os-type linux \ --os-variant rhel8-unknown \ --pxe \ --boot uefi,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/edk2/ovmf/OVMF_VARS.fd,loader_secure=no \ --nographics \ --noreboot ``` [^1]: https://uefi.org/sites/default/files/resources/UEFI%202_5.pdf (Section 23.7)