Booting HOWTO

License notice

Copyright © 2023 Strahinya Radich. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front‑Cover Texts, and no Back‑Cover Texts. A copy of the license is included in the file LICENSE.

Foreword

One of the perhaps most frequent issues with configuring a Unix‑like OS is setting up boot configuration correctly. The perceived difficulty mostly comes from not understanding the basic concepts behind booting.

This guide will attempt to summarize the most important concepts and offer some practical shorthands for setting up booting with Galeb. All the commands assume running them as root, as with any system administration tasks. The most practical way to do that is to login as root or use the command

su -l root

Firmware type

There are two firmware types: the older, BIOS, and newer, UEFI. Which one of the two is used depends on your system. If you can run

efibootmgr -v

and it doesn't give an error message but a list of boot entries, then you have UEFI. With Linux as kernel, a mounted efivarfs, usually at /sys/firmware/efi/efivars, is also needed for the above command to work.

Partition table type

There are two partition table types: older, Master Boot Record (MBR), and newer, GUID Partition Table (GPT). UEFI systems usually use GPT, but other combinations are also possible.

Boot loader

The program which carries out the initial stage of booting an OS is called a boot loader. This can be a program like GRUB, rEFInd, SYSLINUX, LILO and so on, or, in the case of Linux with UEFI, the kernel itself (EFISTUB).

Linux boot

During the boot process, Linux executes the init program (usually /sbin/init) on the system root partition. This can be done in two ways:

Partition can always be specified by a device pathname, such as root=/dev/sda2, which can lead to boot failure if the storage device driver (kernel module) is inaccessible or the disk configuration is changed. For example, this can happen when plugging in a USB flash drive or physically connecting hard drives to different cables, and rebooting, or otherwise changing the order of hard disks.

Partition on GPT systems can also be specified by PARTUUID, which uniquely identifies a partition: root=PARTUUID=.... This is the recommended approach.

Recommended setup in Galeb

The following is the basic recommended partition configuration in Galeb on the traditional SCSI drives. It assumes an UEFI/GPT system.

Partition Mountpoint Filesystem Type Size
/dev/sda1 /boot vfat (32-bit) ~500MB
/dev/sda2 / ext4 Rest

When configuring a boot entry, this means that the kernel command line will include

root=/dev/sda2

or

root=PARTUUID=[PARTUUID of /dev/sda2]

and that the ESP is in /dev/sda1, mounted later during the boot process to /boot. This is where the kernel stub should go into, and will later be accessible from the booted system at /boot/vmlinuz.

When the partition /dev/sda2 exists, its PARTUUID can be obtained with the command

lsblk -no PARTUUID /dev/sda2

NVME SSDs require the nvme and nvme_core kernel modules, and the partition device pathnames usually become /dev/nvme0n1p1 and /dev/nvme0n1p2, respectively:

Partition Mountpoint Filesystem Type Size
/dev/nvme0n1p1 /boot vfat (32-bit) ~500MB
/dev/nvme0n1p2 / ext4 Rest

Creating a boot entry in efibootmgr

The necessary command line parameters will be briefly explained here. For more information, see man 8 lsblk, man 8 efibootmgr and efibootmgr -h.

partuuid=$(lsblk -no PARTUUID /dev/sda2)
efibootmgr -c -d /dev/sda -l '\vmlinuz' -L 'Galeb EFISTUB' -p1 \
	-u 'initrd=\initramfs.img root=PARTUUID='${partuuid}' rw'

Explanation

partuuid=$(lsblk -no PARTUUID /dev/sda2)
Obtain the PARTUUID of /dev/sda2 and store it in the shell variable partuuid.
-c
Create a new boot entry.
-d /dev/sda
Disk on which the root partition is (boot disk).
-l '\vmlinuz'
Boot loader (our EFISTUB) is in the file vmlinuz on ESP.
-L 'Galeb EFISTUB'
Label for the boot entry.
-p1
ESP is the partition #1 on the boot disk (/dev/sda1).
-u
Treat the kernel command line as UCS-2.
'initrd=\initramfs.img root=PARTUUID='${partuuid}' rw'
Kernel command line, quoted to prevent parsing by the shell. Value of the shell variable partuuid is inserted where needed.

Boot image

After the boot scripts have finished, you will be presented with a choice to create a boot image. The boot image will be compressed with xz and needs to be sent to a USB flash medium, for example:

xz -dc galeb-2.2-x86_64-20230417.raw.xz > /dev/sdb

or, if you have pv:

xz -dc galeb-2.2-x86_64-20230417.raw.xz | pv > /dev/sdb

Be careful when specifying the device you send the output to, in order to not overwrite any existing partitions (your hard disk, etc)! You can find out the correct device by using

lsblk -f

or

blkid

The boot image is designed for UEFI systems and will be partitioned as GPT.

When you reboot, enter UEFI setup and choose to boot from USB flash. Fallback shim will automatically create a boot entry for Galeb, which will set the device specified as USBROOT in lib/env.sh as the root device for that entry. If the boot fails, you need to reboot back into your original system, remove the UEFI entry (for example, by using efibootmgr(8)), change USBROOT in lib/env.sh, rerun the bootstrap scripts, copy the newly generated image to USB flash and reboot.

You can safely remove the “Galeb USB” UEFI entry if you don't need it anymore, since it will be automatically generated by fallback shim whenever you choose to boot from the Galeb USB medium.

Multi-booting

If you are using Galeb with other distributions which are using GRUB, and in particular GRUB's os-prober, when you have added a custom configuration snippet in /etc/grub.d/40_custom (if Galeb is installed in /dev/sda2):

uuid=$(lsblk -no UUID /dev/sda2)
cat <<! >>/etc/grub.d/40_custom
menuentry "Galeb 2.2" --class os {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        search --no-floppy --set=root --fs-uuid $uuid
        linux /boot/vmlinuz root=UUID=$uuid rw rootdelay=1 rootfstype=ext4
        initrd /boot/initramfs.img
}
!

you might want to then also add an exception to /etc/default/grub so a new menu item for Galeb's partition doesn't get added by os-prober every time there is a kernel update. First, take note of the UUID of the partition where Galeb is installed:

GALEB_PART=/dev/sda2
GALEB_UUID=$(lsblk -no UUID $GALEB_PART)

then append it to /etc/default/grub in your other distro:

cat <<! >> /etc/default/grub
GRUB_OS_PROBER_SKIP_LIST=$GALEB_UUID@$GALEB_PART
!

You should then regenerate GRUB's configuration file in your distro.

See also

  1. https://wiki.archlinux.org/title/Partitioning#Example_layouts

  2. https://wiki.archlinux.org/title/EFI_system_partition

  3. https://wiki.archlinux.org/title/EFISTUB

  4. http://www.ivarch.com/programs/pv.shtml

  5. https://git.sr.ht/~strahinja/galeb-mkinitramfs/

Generated by slweb © 2020-2024 Strahinya Radich.