]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
mkosi: add basic support for XBOOTLDR partitions 326/head
authorLennart Poettering <lennart@poettering.net>
Tue, 5 Feb 2019 15:44:06 +0000 (16:44 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 14 Feb 2019 10:09:51 +0000 (11:09 +0100)
As documentated in the boot loader specification

mkosi

diff --git a/mkosi b/mkosi
index dd8235d2452c7347da805435e842d767ca4e7ea4..fe34e11a97c64d42373b0b5f9f1033fadf5195a8 100755 (executable)
--- a/mkosi
+++ b/mkosi
@@ -174,6 +174,7 @@ GPT_BIOS               = uuid.UUID("2168614864496e6f744e656564454649")  # NOQA:
 GPT_SWAP               = uuid.UUID("0657fd6da4ab43c484e50933c84b4f4f")  # NOQA: E221
 GPT_HOME               = uuid.UUID("933ac7e12eb44f13b8440e14e2aef915")  # NOQA: E221
 GPT_SRV                = uuid.UUID("3b8f842520e04f3b907f1a25a76f98e8")  # NOQA: E221
+GPT_XBOOTLDR           = uuid.UUID("bc13c2ff59e64262a352b275fd6f7172")  # NOQA: E221
 GPT_ROOT_X86_VERITY    = uuid.UUID("d13c5d3bb5d1422ab29f9454fdc89d76")  # NOQA: E221
 GPT_ROOT_X86_64_VERITY = uuid.UUID("2c7357edebd246d9aec123d437ec2bf5")  # NOQA: E221
 GPT_ROOT_ARM_VERITY    = uuid.UUID("7386cdf2203c47a9a498f2ecce45a2d6")  # NOQA: E221
@@ -473,6 +474,8 @@ def image_size(args: CommandLineArguments) -> int:
             size += args.esp_size
         if "bios" in args.boot_protocols:
             size += BIOS_PARTITION_SIZE
+    if args.xbootldr_size is not None:
+        size += args.xbootldr_size
     if args.swap_size is not None:
         size += args.swap_size
     if args.verity_size is not None:
@@ -507,6 +510,13 @@ def determine_partition_table(args: CommandLineArguments) -> Tuple[str, bool]:
 
         run_sfdisk = True
 
+    if args.xbootldr_size is not None:
+        table += f'size={args.xbootldr_size // 512}, type={GPT_XBOOTLDR}, name="Boot Loader Partition"\n'
+        args.xbootldr_partno = pn
+        pn += 1
+    else:
+        args.xbootldr_partno = None
+
     if args.swap_size is not None:
         table += f'size={args.swap_size // 512}, type={GPT_SWAP}, name="Swap Partition"\n'
         args.swap_partno = pn
@@ -679,6 +689,18 @@ def prepare_esp(args: CommandLineArguments, loopdev: Optional[str], cached: bool
         run(["mkfs.fat", "-nEFI", "-F32", partition(loopdev, args.esp_partno)], check=True)
 
 
+def prepare_xbootldr(args: CommandLineArguments, loopdev: Optional[str], cached: bool) -> None:
+    if loopdev is None:
+        return
+    if cached:
+        return
+    if args.xbootldr_partno is None:
+        return
+
+    with complete_step('Formatting XBOOTLDR partition'):
+        run(["mkfs.fat", "-nXBOOTLDR", "-F32", partition(loopdev, args.xbootldr_partno)], check=True)
+
+
 def mkfs_ext4(label: str, mount: str, dev: str) -> None:
     run(["mkfs.ext4", "-L", label, "-M", mount, dev], check=True)
 
@@ -937,6 +959,9 @@ def mount_image(args: CommandLineArguments,
         if args.esp_partno is not None:
             mount_loop(args, partition(loopdev, args.esp_partno), os.path.join(root, "efi"))
 
+        if args.xbootldr_partno is not None:
+            mount_loop(args, partition(loopdev, args.xbootldr_partno), os.path.join(root, "boot"))
+
         # Make sure /tmp and /run are not part of the image
         mount_tmpfs(os.path.join(root, "run"))
         mount_tmpfs(os.path.join(root, "tmp"))
@@ -1045,20 +1070,33 @@ def prepare_tree(args: CommandLineArguments, workspace: str, run_build_script: b
             f.write(args.machine_id)
             f.write("\n")
 
-        os.mkdir(os.path.join(workspace, "root", "boot"), 0o700)
+        if args.xbootldr_partno is not None:
+            # Create directories for kernels and entries if this is enabled
+            os.mkdir(os.path.join(workspace, "root", "boot/EFI"), 0o700)
+            os.mkdir(os.path.join(workspace, "root", "boot/EFI/Linux"), 0o700)
+            os.mkdir(os.path.join(workspace, "root", "boot/loader"), 0o700)
+            os.mkdir(os.path.join(workspace, "root", "boot/loader/entries"), 0o700)
+            os.mkdir(os.path.join(workspace, "root", "boot", args.machine_id), 0o700)
+        else:
+            # If this is not enabled, let's create an empty directory on /boot
+            os.mkdir(os.path.join(workspace, "root", "boot"), 0o700)
 
         if args.esp_partno is not None:
             os.mkdir(os.path.join(workspace, "root", "efi/EFI"), 0o700)
             os.mkdir(os.path.join(workspace, "root", "efi/EFI/BOOT"), 0o700)
-            os.mkdir(os.path.join(workspace, "root", "efi/EFI/Linux"), 0o700)
             os.mkdir(os.path.join(workspace, "root", "efi/EFI/systemd"), 0o700)
             os.mkdir(os.path.join(workspace, "root", "efi/loader"), 0o700)
-            os.mkdir(os.path.join(workspace, "root", "efi/loader/entries"), 0o700)
-            os.mkdir(os.path.join(workspace, "root", "efi", args.machine_id), 0o700)
 
-            os.symlink("../efi", os.path.join(workspace, "root", "boot/efi"))
-            os.symlink("efi/loader", os.path.join(workspace, "root", "boot/loader"))
-            os.symlink("efi/" + args.machine_id, os.path.join(workspace, "root", "boot", args.machine_id))
+            if args.xbootldr_partno is None:
+                # Create directories for kernels and entries, unless the XBOOTLDR partition is turned on
+                os.mkdir(os.path.join(workspace, "root", "efi/EFI/Linux"), 0o700)
+                os.mkdir(os.path.join(workspace, "root", "efi/loader/entries"), 0o700)
+                os.mkdir(os.path.join(workspace, "root", "efi", args.machine_id), 0o700)
+
+                # Create some compatibility symlinks in /boot in case that is not set up otherwise
+                os.symlink("../efi", os.path.join(workspace, "root", "boot/efi"))
+                os.symlink("../efi/loader", os.path.join(workspace, "root", "boot/loader"))
+                os.symlink("../efi/" + args.machine_id, os.path.join(workspace, "root", "boot", args.machine_id))
 
         os.mkdir(os.path.join(workspace, "root", "etc/kernel"), 0o755)
 
@@ -2591,7 +2629,10 @@ def install_unified_kernel(args: CommandLineArguments,
             if not kver.is_dir():
                 continue
 
-            boot_binary = "/efi/EFI/Linux/linux-" + kver.name
+            # Place kernel in XBOOTLDR partition if it is turned on, otherwise in the ESP
+            prefix = "/efi" if args.xbootldr_size is None else "/boot"
+
+            boot_binary = prefix + "/EFI/Linux/linux-" + kver.name
             if root_hash is not None:
                 boot_binary += "-" + root_hash
             boot_binary += ".efi"
@@ -3035,6 +3076,8 @@ def parse_args() -> CommandLineArguments:
                        help='Set size of root partition (only gpt_ext4, gpt_xfs, gpt_btrfs)', metavar='BYTES')
     group.add_argument("--esp-size",
                        help='Set size of EFI system partition (only gpt_ext4, gpt_xfs, gpt_btrfs, gpt_squashfs)', metavar='BYTES')  # NOQA: E501
+    group.add_argument("--xbootldr-size",
+                       help='Set size of the XBOOTLDR partition (only gpt_ext4, gpt_xfs, gpt_btrfs, gpt_squashfs)', metavar='BYTES')  # NOQA: E501
     group.add_argument("--swap-size",
                        help='Set size of swap partition (only gpt_ext4, gpt_xfs, gpt_btrfs, gpt_squashfs)', metavar='BYTES')  # NOQA: E501
     group.add_argument("--home-size",
@@ -3398,6 +3441,9 @@ def process_setting(args: CommandLineArguments, section: str, key: Optional[str]
         elif key == "ESPSize":
             if args.esp_size is None:
                 args.esp_size = value
+        elif key == "BootLoaderSize":
+            if args.xbootldr_size is None:
+                args.xbootldr_size = value
         elif key == "SwapSize":
             if args.swap_size is None:
                 args.swap_size = value
@@ -3822,6 +3868,7 @@ def load_args(args) -> CommandLineArguments:
     args.home_size = parse_bytes(args.home_size)
     args.srv_size = parse_bytes(args.srv_size)
     args.esp_size = parse_bytes(args.esp_size)
+    args.xbootldr_size = parse_bytes(args.xbootldr_size)
     args.swap_size = parse_bytes(args.swap_size)
 
     if args.output_format in (OutputFormat.gpt_ext4, OutputFormat.gpt_btrfs) and args.root_size is None:
@@ -4000,6 +4047,7 @@ def print_summary(args: CommandLineArguments) -> None:
             sys.stderr.write("                   ESP: " + format_bytes_or_disabled(args.esp_size) + "\n")
         if "bios" in args.boot_protocols:
             sys.stderr.write("                  BIOS: " + format_bytes_or_disabled(BIOS_PARTITION_SIZE) + "\n")
+        sys.stderr.write("    XBOOTLDR Partition: " + format_bytes_or_disabled(args.xbootldr_size) + "\n")
         sys.stderr.write("       /home Partition: " + format_bytes_or_disabled(args.home_size) + "\n")
         sys.stderr.write("        /srv Partition: " + format_bytes_or_disabled(args.srv_size) + "\n")
 
@@ -4086,6 +4134,7 @@ def build_image(args: CommandLineArguments,
 
         prepare_swap(args, loopdev, cached)
         prepare_esp(args, loopdev, cached)
+        prepare_xbootldr(args, loopdev, cached)
 
         if loopdev is not None:
             luks_format_root(args, loopdev, run_build_script, cached)