Home Email Me If you find this useful, consider supporting me with the links below.
Donate with PayPal Amazon Wish List Donate with Venmo Donate with Dogecoin Donate with Bitcoin

Bootloader UEFI & BIOS dual support

Overview

Lately I’ve had a requirement to install linux on a thumb drive to work in both UEFI & BIOS based systems. I’ve been a long time lover of lilo & extlinux. Grub seemed overly complicated and a nighmare to maintain.

After some digging I found a great article from slackware which shows UEFI booting with syslinux (extlinux’s successor). This gave me a great first step in my experimentation. I got the UEFI stuff to boot and then overlaid the BIOS install over that.

This guide assumes you have the ability to RTFM and have a pretty deep knowledge about the boot process of a linux install. In my case I did everyting using debian.

The basic goal

Note: this is not a complete guide to install linux. This is just a jumpstart to get the bootloader and drive partitioning up and running.

Lessons learned

Reference:

Syslinux Install Guide

Prep the disk and setup partitions

shred -n 0 -z -v /dev/sdb
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart boot fat32 0% 1024MB
parted /dev/sdb mkpart swap linux-swap 1024MB 2048MB
parted /dev/sdb mkpart root btrfs 2048MB 100%

parted /dev/sdb set 1 legacy_boot on
parted /dev/sdb set 1 esp on
parted /dev/sdb set 1 boot on

Verify your settings

parted /dev/sdb print

    Model: General USB Flash Disk (scsi)
    Disk /dev/sdb: 4027MB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags: 

    Number  Start   End     Size    File system  Name  Flags
     1      1049kB  1024MB  1023MB               boot  boot, legacy_boot, esp
     2      1024MB  2048MB  1023MB               swap  swap
     3      2048MB  4025MB  1978MB               root

Create the filesystems

mkfs.vfat -F 32 /dev/sdb1
mkswap /dev/sdb2
mkfs.btrfs /dev/sdb3

Setup BIOS Boot

dd bs=440 count=1 conv=notrunc if=/usr/lib/syslinux/mbr/gptmbr.bin of=/dev/sdb
syslinux --install /dev/sdb1
mount /dev/sdb1 /media/tmp
cp /usr/lib/syslinux/modules/bios/menu.c32 /media/tmp
cp /usr/lib/syslinux/modules/bios/libutil.c32 /media/tmp

Setup UEFI Boot

mkdir --parents /media/tmp/EFI/BOOT/
cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi /media/tmp/EFI/BOOT/BOOTX64.EFI
cp /usr/lib/syslinux/modules/efi64/ldlinux.e64 /media/tmp/EFI/BOOT/
cp /usr/lib/syslinux/modules/efi64/menu.c32 /media/tmp/EFI/BOOT/
cp /usr/lib/syslinux/modules/efi64/libutil.c32 /media/tmp/EFI/BOOT/

Retrieve GUIDs for partitions

blkid

    /dev/sdb1: UUID="3A78-C0A0" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="boot" PARTUUID="3a822b98-5fa1-4ffe-b62d-c9484c29e9c9"
    /dev/sdb2: UUID="11b483f0-6bbc-40bf-b612-68d101f719ee" TYPE="swap" PARTLABEL="swap" PARTUUID="24d16141-7232-4b8e-9d55-4141e82ae56e"
    /dev/sdb3: UUID="bacc9064-a76d-42d7-a969-4995d1a024af" UUID_SUB="9b29c06f-b92c-4780-a95c-b29ffe1a9ae6" BLOCK_SIZE="4096" TYPE="btrfs" PARTLABEL="root" PARTUUID="bc10faff-7bfb-427d-accc-d41d745f6e65"

Create syslinux.cfg (Same file 2 locations)

/media/tmp/syslinux.cfg
/media/tmp/EFI/BOOT/syslinux.cfg

    UI menu.c32
    PROMPT 0
    TIMEOUT 100
    DEFAULT linux

    MENU TITLE Machine Boot Menu

    LABEL linux
    MENU LABEL My Linux Install
    LINUX /vmlinuz
    APPEND ro initrd=/initrd.img root=UUID=bacc9064-a76d-42d7-a969-4995d1a024af fsck.repair=yes noresume

Cannot create vmlinuz & initrd.img symlinks in /boot

This is bit of a huge hack but seems to work. I created a hook file after update-initramfs that will copy the files rather than generate symlinks.

/etc/initramfs/post-update.d/syslinux-fat32

    #!/bin/bash
    echo "Executing: $0"
    echo "Params: $@"
    cp -v "/boot/initrd.img-$1" /boot/initrd.img
    cp -v "/boot/vmlinuz-$1" /boot/vmlinuz
Last Updated: 2020-07-10