galeb

Једноставна статичка дистрибуција заснована на musl-у
git clone https://git.sr.ht/~strahinja/galeb
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

BOOTING (9304B)


      1 Booting HOWTO
      2 =============
      3 
      4 License notice
      5 --------------
      6 
      7 Copyright (c)  2023  Strahinya Radich.
      8 Permission is granted to copy, distribute and/or modify this document
      9 under the terms of the GNU Free Documentation License, Version 1.3
     10 or any later version published by the Free Software Foundation;
     11 with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
     12 A copy of the license is included in the file LICENSE.fdl.
     13 
     14 
     15 Foreword
     16 --------
     17 
     18 One of the perhaps most frequent issues with configuring a Unix-like OS is
     19 setting up boot configuration correctly. The perceived difficulty mostly comes
     20 from not understanding the basic concepts behind booting.
     21 
     22 This guide will attempt to summarize the most important concepts and offer some
     23 practical shorthands for setting up booting with Galeb. All the commands assume
     24 running them as root, as with any system administration tasks. The most
     25 practical way to do that is to login as root or use the command
     26 
     27 	su -l root
     28 
     29 
     30 Firmware type
     31 -------------
     32 
     33 There are two firmware types: the older, BIOS, and newer, UEFI. Which one of the
     34 two is used depends on your system. If you can run
     35 
     36 	efibootmgr -v
     37 
     38 and it doesn't give an error message but a list of boot entries, then you have
     39 UEFI. With Linux as kernel, a mounted efivarfs, usually at
     40 /sys/firmware/efi/efivars, is also needed for the above command to work.
     41 
     42 
     43 Partition table type
     44 --------------------
     45 
     46 There are two partition table types: older, Master Boot Record (MBR), and newer,
     47 GUID Partition Table (GPT). UEFI systems usually use GPT, but other combinations
     48 are also possible.
     49 
     50 
     51 Boot loader
     52 -----------
     53 
     54 The program which carries out the initial stage of booting an OS is called a
     55 boot loader. This can be a program like GRUB, rEFInd, SYSLINUX, LILO and so on,
     56 or, in the case of Linux with UEFI, the kernel itself (EFISTUB).
     57 
     58 * With BIOS, bootloaders are written into the (master or volume) boot records of
     59   disk partitions themselves (BIOS/MBR) or BIOS boot partitions (BIOS/GPT), and
     60   this is where the system will look for them.
     61 
     62 * With UEFI/GPT, bootloaders are normal files on an EFI System Partition (ESP).
     63   In order for the system to find them, their boot entries must be written to
     64   EFI variables. This can be done by the program efibootmgr(8), but it can also
     65   be done by the UEFI interface or an UEFI shell.
     66 
     67 
     68 Linux boot
     69 ----------
     70 
     71 During the boot process, Linux executes the init program (usually /sbin/init)
     72 on the system root partition. This can be done in two ways:
     73 
     74 * By creating an initial root partition (initramfs) having a temporary init
     75   program, which if needed handles loading the necessary kernel modules
     76   (drivers) to access the root partition. This method also supports advanced
     77   partition selection, for example by their UUIDs or LABELs, and doesn't
     78   require the support for filesystem type of the root partition to be compiled
     79   into the kernel. initramfs is passed to EFISTUB through the kernel command
     80   line: `initrd=\initramfs.img`, where the "root" directory is ESP.
     81 
     82   Note that UEFI uses DOS filesystem path separator, backslash (\),
     83   instead of a slash (/) used on Unix-like systems.
     84 
     85 * By compiling the necessary filesystem modules and storage device drivers into
     86   the kernel and specifying the root partition on the kernel command line. This
     87   is more minimal, as it doesn't require initramfs. However, advanced partition
     88   selection by UUIDs and LABELs is not supported (but see below), and licenses
     89   for "binary blobs" (drivers/modules) usually clash with the requirements of
     90   GPL (which is the license of the kernel), preventing them from being compiled
     91   in the kernel in such a way. That's why initramfs is the most used option, and
     92   recommended in Galeb. In Galeb, there is a script mkinitramfs(8), which can be
     93   used to generate initramfs. Refer to [5].
     94 
     95 Partition can always be specified by a device pathname, such as
     96 `root=/dev/sda2`, which can lead to boot failure if the storage device driver
     97 (kernel module) is inaccessible or the disk configuration is changed. For
     98 example, this can happen when plugging in a USB flash drive or physically
     99 connecting hard drives to different cables, and rebooting, or otherwise changing
    100 the order of hard disks.
    101 
    102 Partition on GPT systems can also be specified by PARTUUID, which uniquely
    103 identifies a partition: `root=PARTUUID=...`. This is the recommended approach.
    104 
    105 
    106 Recommended setup in Galeb
    107 --------------------------
    108 
    109 The following is the basic recommended partition configuration in Galeb on the
    110 traditional SCSI drives. It assumes an UEFI/GPT system.
    111 
    112 	Partition	Mountpoint	Filesystem Type		Size
    113 	--------------------------------------------------------------
    114 	/dev/sda1	/boot		vfat (32-bit)		~500MB
    115 	/dev/sda2	/		ext4			Rest
    116 
    117 When configuring a boot entry, this means that the kernel command line will
    118 include
    119 
    120 	root=/dev/sda2
    121 
    122 or
    123 
    124 	root=PARTUUID=[PARTUUID of /dev/sda2]
    125 
    126 and that the ESP is in /dev/sda1, mounted later during the boot process to
    127 /boot. This is where the kernel stub should go into, and will later be
    128 accessible from the booted system at /boot/vmlinuz.
    129 
    130 When the partition /dev/sda2 exists, its PARTUUID can be obtained with the
    131 command:
    132 
    133 	lsblk -no PARTUUID /dev/sda2
    134 
    135 NVME SSDs require the nvme and nvme_core kernel modules, and the partition
    136 device pathnames usually become /dev/nvme0n1p1 and /dev/nvme0n1p2, respectively:
    137 
    138 	Partition	Mountpoint	Filesystem Type		Size
    139 	--------------------------------------------------------------
    140 	/dev/nvme0n1p1	/boot		vfat (32-bit)		~500MB
    141 	/dev/nvme0n1p2	/		ext4			Rest
    142 
    143 
    144 Creating a boot entry in efibootmgr
    145 -----------------------------------
    146 
    147 The necessary command line parameters will be briefly explained here. For more
    148 information, see `man 8 efibootmgr` and `efibootmgr -h`.
    149 
    150 	partuuid=$(lsblk -no PARTUUID /dev/sda2)
    151 	efibootmgr -c -d /dev/sda -l '\vmlinuz' -L 'Galeb EFISTUB' -p1 \
    152 		-u 'initrd=\initramfs.img root=PARTUUID='${partuuid}' rw'
    153 
    154 
    155 Explanation
    156 -----------
    157 
    158 partuuid=$(lsblk -no PARTUUID /dev/sda2)
    159 	Obtain the PARTUUID of /dev/sda2 and store it in the shell variable
    160 	`partuuid`.
    161 
    162 -c	Create a new boot entry.
    163 
    164 -d /dev/sda
    165 	Disk on which the root partition is (boot disk).
    166 
    167 -l '\vmlinuz'
    168 	Boot loader (our EFISTUB) is in the file vmlinuz on ESP.
    169 
    170 -L 'Galeb EFISTUB'
    171 	Label for the boot entry.
    172 
    173 -p1	ESP is the partition #1 on the boot disk (/dev/sda1).
    174 
    175 -u	Treat the kernel command line as UCS-2.
    176 
    177 'initrd=\initramfs.img root=PARTUUID='${partuuid}' rw'
    178 	Kernel command line, quoted to prevent parsing by the shell. Value of
    179 	the shell variable `partuuid` is inserted where needed.
    180 
    181 
    182 Boot image
    183 ----------
    184 
    185 After the boot scripts have finished, you will be presented with a choice to
    186 create a boot image. The boot image will be compressed with xz and needs to be
    187 sent to a USB flash medium, for example:
    188 
    189 	xz -dc galeb-2.2-x86_64-20230417.raw.xz > /dev/sdb
    190 
    191 or, if you have pv[4]:
    192 
    193 	xz -dc galeb-2.2-x86_64-20230417.raw.xz | pv > /dev/sdb
    194 
    195 _Be careful when specifying the device you send the output to, in order to not
    196 overwrite any existing partitions (your hard disk, etc)!_ You can find out the
    197 correct device by using
    198 
    199 	lsblk -f
    200 
    201 or
    202 
    203 	blkid
    204 
    205 The boot image is designed for UEFI systems and will be partitioned as GPT.
    206 
    207 When you reboot, enter UEFI setup and choose to boot from USB flash. Fallback
    208 shim will automatically create a boot entry for Galeb, which will set the device
    209 specified as USBROOT in lib/env.sh as the root device for that entry. If the
    210 boot fails, you need to reboot back into your original system, remove the UEFI
    211 entry (for example, by using efibootmgr(8)), change USBROOT in lib/env.sh, rerun
    212 the bootstrap scripts, copy the newly generated image to USB flash and reboot.
    213 
    214 You can safely remove the "Galeb USB" UEFI entry if you don't need it anymore,
    215 since it will be automatically generated by fallback shim whenever you choose to
    216 boot from the Galeb USB medium.
    217 
    218 
    219 Multi-booting
    220 -------------
    221 
    222 If you are using Galeb with other distributions which are using GRUB, and in
    223 particular GRUB's os-prober, when you have added a custom configuration snippet
    224 in /etc/grub.d/40_custom (if Galeb is installed in /dev/sda2):
    225 
    226 	uuid=$(lsblk -no UUID /dev/sda2)
    227 	cat <<! >>/etc/grub.d/40_custom
    228 menuentry "Galeb 2.2" --class os {
    229         load_video
    230         insmod gzio
    231         insmod part_gpt
    232         insmod ext2
    233         search --no-floppy --set=root --fs-uuid $uuid
    234         linux /boot/vmlinuz root=UUID=$uuid rw rootdelay=1 rootfstype=ext4
    235         initrd /boot/initramfs.img
    236 }
    237 !
    238 
    239 you might want to then also add an exception to /etc/default/grub so a new menu
    240 item for Galeb's partition doesn't get added by os-prober every time there is a
    241 kernel update. First, take note of the UUID of the partition where Galeb is
    242 installed:
    243 
    244 	GALEB_PART=/dev/sda2
    245 	GALEB_UUID=$(lsblk -no UUID $GALEB_PART)
    246 
    247 then append it to /etc/default/grub in your other distro:
    248 
    249 	cat <<! >> /etc/default/grub
    250 	GRUB_OS_PROBER_SKIP_LIST=$GALEB_UUID@$GALEB_PART
    251 	!
    252 
    253 You should then regenerate GRUB's configuration file in your distro.
    254 
    255 
    256 See also
    257 --------
    258 
    259 1. https://wiki.archlinux.org/title/Partitioning#Example_layouts
    260 2. https://wiki.archlinux.org/title/EFI_system_partition
    261 3. https://wiki.archlinux.org/title/EFISTUB
    262 4. http://www.ivarch.com/programs/pv.shtml
    263 5. https://git.sr.ht/~strahinja/galeb-mkinitramfs/