]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Add Bootloader option
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 16 Aug 2023 13:33:29 +0000 (15:33 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 16 Aug 2023 13:56:22 +0000 (15:56 +0200)
For some use cases, we don't want systemd-boot but to boot directly
from a UKI, so let's support that by bringing back the --bootloader
option.

mkosi/__init__.py
mkosi/config.py
mkosi/resources/mkosi.md

index 1b231d95489f28379981ccda467d686ed0282fc1..0bf0a160429fbda571e5ba5ad372466056cbe8ce 100644 (file)
@@ -23,6 +23,7 @@ from typing import Any, ContextManager, Mapping, Optional, TextIO, Union
 
 from mkosi.archive import extract_tar, make_cpio, make_tar
 from mkosi.config import (
+    Bootloader,
     Compression,
     ConfigFeature,
     DocFormat,
@@ -454,6 +455,9 @@ def install_boot_loader(state: MkosiState) -> None:
     if state.config.bootable == ConfigFeature.disabled:
         return
 
+    if state.config.bootloader != Bootloader.systemd_boot:
+        return
+
     if state.config.output_format == OutputFormat.cpio and state.config.bootable == ConfigFeature.auto:
         return
 
@@ -716,6 +720,9 @@ def install_unified_kernel(state: MkosiState, partitions: Sequence[Partition]) -
     if state.config.bootable == ConfigFeature.disabled:
         return
 
+    if state.config.bootloader not in (Bootloader.systemd_boot, Bootloader.uki):
+        return
+
     for kver, kimg in gen_kernel_images(state):
         shutil.copy(state.root / kimg, state.staging / state.config.output_split_kernel)
         break
@@ -740,7 +747,9 @@ def install_unified_kernel(state: MkosiState, partitions: Sequence[Partition]) -
             if (state.root / "etc/kernel/tries").exists():
                 boot_count = f'+{(state.root / "etc/kernel/tries").read_text().strip()}'
 
-            if state.config.image_version:
+            if state.config.bootloader == Bootloader.uki:
+                boot_binary = state.root / "efi/EFI/BOOT/BOOTX64.EFI"
+            elif state.config.image_version:
                 boot_binary = state.root / f"efi/EFI/Linux/{image_id}_{state.config.image_version}-{kver}{boot_count}.efi"
             elif roothash:
                 _, _, h = roothash.partition("=")
@@ -857,6 +866,9 @@ def install_unified_kernel(state: MkosiState, partitions: Sequence[Partition]) -
 
             print_output_size(boot_binary)
 
+            if state.config.bootloader == Bootloader.uki:
+                break
+
     if state.config.bootable == ConfigFeature.enabled and not (state.staging / state.config.output_split_uki).exists():
         die("A bootable image was requested but no kernel was found")
 
@@ -1357,7 +1369,7 @@ def make_image(state: MkosiState, skip: Sequence[str] = [], split: bool = False)
         definitions = state.workspace / "repart-definitions"
         if not definitions.exists():
             definitions.mkdir()
-            bootdir = state.root / "efi/EFI/BOOT"
+            bootdir = state.root / "usr/lib/systemd/boot/efi"
 
             # If Bootable=auto and we have at least one UKI and a bootloader, let's generate an ESP partition.
             add = (state.config.bootable == ConfigFeature.enabled or
index d43b7b2ff9d95a24e9f69d992dd89d95760a8cb6..37bd235c4f64b12e82356e1337314ffc94969e3e 100644 (file)
@@ -115,6 +115,11 @@ class DocFormat(StrEnum):
     system   = enum.auto()
 
 
+class Bootloader(StrEnum):
+    uki          = enum.auto()
+    systemd_boot = enum.auto()
+
+
 def parse_boolean(s: str) -> bool:
     "Parse 1/true/yes/y/t/on as true and 0/false/no/n/f/off/None as false"
     s_l = s.lower()
@@ -688,6 +693,7 @@ class MkosiConfig:
     with_network: bool
 
     bootable: ConfigFeature
+    bootloader: Bootloader
     initrds: list[Path]
     kernel_command_line: list[str]
     kernel_modules_include: list[str]
@@ -1180,6 +1186,15 @@ class MkosiConfigParser:
             match=config_match_feature,
             help="Generate ESP partition with systemd-boot and UKIs for installed kernels",
         ),
+        MkosiConfigSetting(
+            dest="bootloader",
+            metavar="BOOTLOADER",
+            section="Content",
+            parse=config_make_enum_parser(Bootloader),
+            choices=Bootloader.values(),
+            default=Bootloader.systemd_boot,
+            help="Specify which bootloader to use",
+        ),
         MkosiConfigSetting(
             dest="initrds",
             long="--initrd",
@@ -2227,6 +2242,7 @@ Clean Package Manager Metadata: {yes_no_auto(config.clean_package_metadata)}
           Scripts With Network: {yes_no(config.with_network)}
 
                       Bootable: {yes_no_auto(config.bootable)}
+                    Bootloader: {config.bootloader}
                        Initrds: {line_join_list(config.initrds)}
            Kernel Command Line: {line_join_list(config.kernel_command_line)}
         Kernel Modules Include: {line_join_list(config.kernel_modules_include)}
index 3d7204634e8c693748afca5b17ee2d927ffa1130..29d08cc0648ab6209cc6eb9ba07d023a64349bde 100644 (file)
@@ -780,6 +780,16 @@ they should be specified with a boolean argument: either "1", "yes", or "true" t
   image, no unified kernel images will be generated and no ESP partition
   will be added to the image if the disk output format is used.
 
+`Bootloader=`, `--bootloader=`
+
+: Takes one of `systemd-boot` or `uki`. Defaults to `systemd-boot`. If
+  set to `systemd-boot`, systemd-boot will be installed and for each
+  installed kernel, a UKI will be generated and stored in `EFI/Linux` in
+  the ESP partition. If set to `uki`, systemd-boot will not be installed
+  and a single UKI will be generated for the latest installed kernel
+  (the one with the highest version) and stored in
+  `EFI/BOOT/BOOTX64.EFI`.
+
 `Initrds=`, `--initrd`
 
 : Use user-provided initrd(s). Takes a comma separated list of paths to