# 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,"http://192.168.100.1/httpboot/EFI/BOOT/BOOTX64.EFI"`. 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,"http://192.168.100.1/httpboot/EFI/BOOT/BOOTX64.EFI"'/>
</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)