This document discusses various ways to customize a bootloader's behavior based on hardware properties detected at boot time. It presents options for tweaking Grub2 or Syslinux to select different boot options depending on characteristics like the CPU type, virtualization support, or whether the system is running in a hypervisor. Specific examples are provided of using Syslinux modules or Lua scripts to detect properties and adjust the kernel command line accordingly in order to boot different kernels optimized for the detected hardware.
2. Back to the Future
● First presentation of HDT @ KR2012
● Does HDT can define a way to boot ?
– NO, just inspecting hardware with a cli/gui
● How can I make my system booting based on
hardware properties ?
3. Tweaking a Bootloader
● Only the bootloader can do this job
● Making the hardware detection ASAP
● Link between hw properties and boot
entry/option
● Anyone in the room for hacking grub2 ?
4. Syslinux
● Syslinux provides libs to get HW information
– CPU
– Memory
– PCI
– DMI
– ACPI
– VESA
– Included since 2009 (3.74)
5. Two ways to make it
● Creating specific COM32 modules
– like IFCPU
– Raw C code, compiled against syslinux
● Using LUA scripts
– Custom defined behaviors based on HW
properties
6. Ifcpu.c32
label ifcpu
com32 ifcpu.c32
append <cpu_features> -- boot_entry_1 -- boot_entry_2
label boot_entry_1
kernel vmlinuz_entry1
append ...
label boot_entry_2
kernel vmlinuz_entry2
append ...
cpu_features could be :
64: x86_64 compatible (lm)
hvm: hardware virtualization (hvm or svm)
pae : Physical Address Extension (PAE)
multicore: multi-core CPUs
smp : multi-processor system
hypervisor : Running under an hypervisor
8. Using LUA
-- Including other modules
package.path = package.path .. ";pxelinux.cfg/?.lua;isolinux/?.lua"
require("hypervisor")
-- Setting up the original options
append=""
-- Adjust them regarding the hypervisor detection
append=detect_hypervisor(append)
-- Booting the kernel
print("Booting with " .. append )
kernel = syslinux.loadfile("/vmlinuz")
initrd = syslinux.initramfs_init()
syslinux.initramfs_load_archive(initrd, "/core.gz");
syslinux.boot_it(kernel, initrd, append)
script.lua
9. Using LUA
function detect_hypervisor (append)
cpuflags = cpu.flags()
if ( string.match(cpuflags["flags.hypervisor"], "yes")) then
print ("Hypervisor detected");
append=append .. "nr_cpus=1"
else
append=append .. "whatever_you_want"
end
return append
end
hypervisor.lua