Commit 04beb0ae authored by Siddhartha's avatar Siddhartha
Browse files

nixos/lib/make-disk-image: Add ability to setup an XBOOTLDR partition

parent 0309c267
Loading
Loading
Loading
Loading
+39 −16
Original line number Diff line number Diff line
@@ -56,6 +56,14 @@ This partition table type uses GPT and:
- creates an FAT32 ESP partition from 8MiB to specified `bootSize` parameter (256MiB by default), set it bootable ;
- creates an primary ext4 partition starting after the boot partition and extending to the full disk image

#### `efixbootldr`

This partition table type uses GPT and:

- creates an FAT32 ESP partition from 8MiB to 100MiB, set it bootable ;
- creates an FAT32 BOOT partition from 100MiB to specified `bootSize` parameter (256MiB by default), set `bls_boot` flag ;
- creates an primary ext4 partition starting after the boot partition and extending to the full disk image

#### `hybrid`

This partition table type uses GPT and:
@@ -111,19 +119,7 @@ To solve this, you can run `fdisk -l $image` and generate `dd if=$image of=$imag
  # When setting one of `user' or `group', the other needs to be set too.
  contents ? []

, # Type of partition table to use; either "legacy", "efi", or "none".
  # For "efi" images, the GPT partition table is used and a mandatory ESP
  #   partition of reasonable size is created in addition to the root partition.
  # For "legacy", the msdos partition table is used and a single large root
  #   partition is created.
  # For "legacy+gpt", the GPT partition table is used, a 1MiB no-fs partition for
  #   use by the bootloader is created, and a single large root partition is
  #   created.
  # For "hybrid", the GPT partition table is used and a mandatory ESP
  #   partition of reasonable size is created in addition to the root partition.
  #   Also a legacy MBR will be present.
  # For "none", no partition table is created. Enabling `installBootLoader`
  #   most likely fails as GRUB will probably refuse to install.
, # Type of partition table to use; described in the `Image Partitioning` section above.
  partitionTableType ? "legacy"

, # Whether to invoke `switch-to-configuration boot` during image creation
@@ -193,11 +189,11 @@ To solve this, you can run `fdisk -l $image` and generate `dd if=$image of=$imag
  additionalPaths ? []
}:

assert (lib.assertOneOf "partitionTableType" partitionTableType [ "legacy" "legacy+gpt" "efi" "hybrid" "none" ]);
assert (lib.assertOneOf "partitionTableType" partitionTableType [ "legacy" "legacy+gpt" "efi" "efixbootldr" "hybrid" "none" ]);
assert (lib.assertMsg (fsType == "ext4" && deterministic -> rootFSUID != null) "In deterministic mode with a ext4 partition, rootFSUID must be non-null, by default, it is equal to rootGPUID.");
  # We use -E offset=X below, which is only supported by e2fsprogs
assert (lib.assertMsg (partitionTableType != "none" -> fsType == "ext4") "to produce a partition table, we need to use -E offset flag which is support only for fsType = ext4");
assert (lib.assertMsg (touchEFIVars -> partitionTableType == "hybrid" || partitionTableType == "efi" || partitionTableType == "legacy+gpt") "EFI variables can be used only with a partition table of type: hybrid, efi or legacy+gpt.");
assert (lib.assertMsg (touchEFIVars -> partitionTableType == "hybrid" || partitionTableType == "efi" || partitionTableType == "efixbootldr" || partitionTableType == "legacy+gpt") "EFI variables can be used only with a partition table of type: hybrid, efi, efixbootldr, or legacy+gpt.");
  # If only Nix store image, then: contents must be empty, configFile must be unset, and we should no install bootloader.
assert (lib.assertMsg (onlyNixStore -> contents == [] && configFile == null && !installBootLoader) "In a only Nix store image, the contents must be empty, no configuration must be provided and no bootloader should be installed.");
# Either both or none of {user,group} need to be set
@@ -225,6 +221,7 @@ let format' = format; in let
    legacy = "1";
    "legacy+gpt" = "2";
    efi = "2";
    efixbootldr = "3";
    hybrid = "3";
  }.${partitionTableType};

@@ -266,6 +263,23 @@ let format' = format; in let
          $diskImage
      ''}
    '';
    efixbootldr = ''
      parted --script $diskImage -- \
        mklabel gpt \
        mkpart ESP fat32 8MiB 100MiB \
        set 1 boot on \
        mkpart BOOT fat32 100MiB ${bootSize} \
        set 2 bls_boot on \
        mkpart ROOT ext4 ${bootSize} -1
      ${optionalString deterministic ''
          sgdisk \
          --disk-guid=97FD5997-D90B-4AA3-8D16-C1723AEA73C \
          --partition-guid=1:1C06F03B-704E-4657-B9CD-681A087A2FDC  \
          --partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F  \
          --partition-guid=3:${rootGPUID} \
          $diskImage
      ''}
    '';
    hybrid = ''
      parted --script $diskImage -- \
        mklabel gpt \
@@ -436,7 +450,7 @@ let format' = format; in let
    diskImage=nixos.raw

    ${if diskSize == "auto" then ''
      ${if partitionTableType == "efi" || partitionTableType == "hybrid" then ''
      ${if partitionTableType == "efi" || partitionTableType == "efixbootldr" || partitionTableType == "hybrid" then ''
        # Add the GPT at the end
        gptSpace=$(( 512 * 34 * 1 ))
        # Normally we'd need to account for alignment and things, if bootSize
@@ -570,6 +584,15 @@ let format' = format; in let

        ${optionalString touchEFIVars "mount -t efivarfs efivarfs /sys/firmware/efi/efivars"}
      ''}
      ${optionalString (partitionTableType == "efixbootldr") ''
        mkdir -p /mnt/{boot,efi}
        mkfs.vfat -n ESP /dev/vda1
        mkfs.vfat -n BOOT /dev/vda2
        mount /dev/vda1 /mnt/efi
        mount /dev/vda2 /mnt/boot

        ${optionalString touchEFIVars "mount -t efivarfs efivarfs /sys/firmware/efi/efivars"}
      ''}

      # Install a configuration.nix
      mkdir -p /mnt/etc/nixos