From Grub2 to LILO:  Booting Qubes

Last modified: Thu Jan 21 19:53:38 EST 2016

January 2016 — So I'm trying to play with Qubes 3.0 while keeping Slackware 14.1 as my main working OS.  Slackware uses LILO, Qubes uses Grub2.  The default auto-installer for Grub2 didn't pick up my Slackware partition, and the grub config file is hundreds of lines of autogenerated barf.

Furthermore, Qubes uses the multiboot feature of Grub2 that LILO doesn't have.  The following notes describe the process of adding Qubes to my working LILO config.

Tools and patches


According to, LILO development has stopped at version 24.2 (though someone may pick it up again).  The version tested was 24.0.


Source: (c.f.

"mbootpack is a tool that takes a multiboot kernel and modules (e.g. a Xen VMM, linux kernel and initrd), and packages them up as a single file that looks like a bzImage linux kernel.  The aim is to allow you to boot multiboot kernels (in particular, Xen) using bootloaders that don't support multiboot (i.e. pretty much anything except GRUB and SYSLINUX).  This is, as you might expect, pretty grim stuff, involving lots of lovely 16-bit real-mode code."

Version 0.6a released 2008-12-09 was the last release and the only one that works with 64 bit.

To make it build, I had to modify the Makefile to add -I/usr/src/linux/arch/x86/include to INCS, so that it would find asm/page.h.


extract-vmlinux lives in the kernel source tree in the scripts directory.  As of kernel 4.4, it still needs patching for the following failure:

mktemp: cannot create temp file /tmp/vmlinux-XXX: Invalid argument

Per the fix was

< tmp=$(mktemp /tmp/vmlinux-XXX)
> tmp=$(mktemp /tmp/vmlinux-XXXXXX)


Based on this guidance, which didn't quite work because it predates the need for extract-vmlinux.

Here is the relevant section of barf from grub.cfg (found in /boot/grub2 in the Qubes file system).

### BEGIN /etc/grub.d/20_linux_xen ###
menuentry 'Qubes, with Xen hypervisor' --class qubes --class gnu-linux --class gnu --class os --class xen $menuentry_id_option 'xen-gnulinux-simple-7de0184b-7df2-4e30-b137-df147e289fdd' {
	insmod part_msdos
	insmod ext2
	set root='hd0,msdos8'
	if [ x$feature_platform_search_hint = xy ]; then
	  search --no-floppy --fs-uuid --set=root --hint-bios=hd1,msdos8 --hint-efi=hd1,msdos8 --hint-baremetal=ahci1,msdos8 --hint='hd0,msdos8'  9b48d7be-5d01-4eeb-8fd9-e183fe38f57c
	  search --no-floppy --fs-uuid --set=root 9b48d7be-5d01-4eeb-8fd9-e183fe38f57c
	echo	'Loading Xen 4.4.2 ...'
        if [ "$grub_platform" = "pc" -o "$grub_platform" = "" ]; then
            xen_rm_opts="no-real-mode edd=off"
	multiboot	/xen-4.4.2.gz placeholder  console=none dom0_mem=min:1024M ${xen_rm_opts}
	echo	'Loading Linux 3.19.8-100.fc20.x86_64 ...'
	module	/vmlinuz-3.19.8-100.fc20.x86_64 placeholder root=UUID=7de0184b-7df2-4e30-b137-df147e289fdd ro vconsole.font=latarcyrheb-sun16  rhgb quiet 
	echo	'Loading initial ramdisk ...'
	module	/initramfs-3.19.8-100.fc20.x86_64.img

Yuck.  The important bits are these:


xen-4.4.2.gz placeholder console=none dom0_mem=min:1024M ${xen_rm_opts}
vmlinuz-3.19.8-100.fc20.x86_64 placeholder root=UUID=7de0184b-7df2-4e30-b137-df147e289fdd ro vconsole.font=latarcyrheb-sun16 rhgb quiet

In my case, 'hd0,msdos8' apparently means /dev/sdb8 (Qubes boot partition where the referenced blobs live).  I assume that "placeholder" is garbage and that ${xen_rm_opts} is empty.

Creating the merged bootable blob (with /dev/sdb8 temporarily mounted on /mnt):

bash-4.2$ gzip -dc /mnt/xen-4.4.2.gz > xen-4.4.2
bash-4.2$ ./extract-vmlinux /mnt/vmlinuz-3.19.8-100.fc20.x86_64 > vmlinux-3.19.8-100.fc20.x86_64
bash-4.2$ cp -a /mnt/initramfs-3.19.8-100.fc20.x86_64.img .
bash-4.2$ mbootpack -o qubes.img -m vmlinux-3.19.8-100.fc20.x86_64 -m initramfs-3.19.8-100.fc20.x86_64.img xen-4.4.2
Loading xen-4.4.2 using ELF header.
Placed kernel section (0x100000+0x1fa000)
Loaded kernel from xen-4.4.2
Placed MBI and strings (0x9c2c+0x3d4)
Placed section (0x2fa000+0x12a9910), align=0x1000
Loaded module from vmlinux-3.19.8-100.fc20.x86_64
Placed section (0x15a4000+0xe77b6d), align=0x1000
Warning: initramfs-3.19.8-100.fc20.x86_64.img looks like a compressed file.
Loaded module from initramfs-3.19.8-100.fc20.x86_64.img
Kernel entry is 0x100000, MBI is 0x9c2c.
High sections: 0x231bb6d bytes at 0x100000.
Wrote bzImage header: 512 + 2410 bytes.
Wrote 1 low-memory sections.
Wrote 3 high-memory sections.
bash-4.2$ ls -s --block-size=1 qubes.img 
36818944 qubes.img

Finally, qubes.img goes into the Slackware /boot directory and lilo.conf gets the following new section.

image = /boot/qubes.img
  append="console=none dom0_mem=min:1024M -- root=UUID=7de0184b-7df2-4e30-b137-df147e289fdd ro"
  label = qubes

That seemed to work.