diff --git a/machines/lappy/default.nix b/machines/lappy/default.nix index d08f621b..0fb5b4e9 100644 --- a/machines/lappy/default.nix +++ b/machines/lappy/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{ pkgs, ... }: { imports = [ ./fs.nix @@ -6,7 +6,9 @@ colinsane.gui.sway.enable = true; colinsane.impermanence.enable = true; - colinsane.extlinux.enable = true; + boot.loader.generic-extlinux-compatible.enable = true; + boot.loader.efi.canTouchEfiVariables = false; + colinsane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; # docs: https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion system.stateVersion = "21.05"; diff --git a/modules/hardware/default.nix b/modules/hardware/default.nix index 0ef52ad0..e9f0b575 100644 --- a/modules/hardware/default.nix +++ b/modules/hardware/default.nix @@ -2,7 +2,6 @@ { imports = [ - ./extlinux.nix ./x86_64.nix ]; } diff --git a/modules/hardware/extlinux-builder.sh b/modules/hardware/extlinux-builder.sh deleted file mode 100755 index f51570e0..00000000 --- a/modules/hardware/extlinux-builder.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! @bash@/bin/sh -ex - -# this wraps /nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.sh -# to expose a COMPLETE extlinux bootloader installation. - -# parse CLI. we only care about some of the flags -target=/boot # default target -while getopts "t:c:d:g:n:r" opt; do - case "$opt" in - d) target="$OPTARG" ;; - *) ;; - esac -done - -# populate /boot/extlinux/extlinux.conf & /boot/nixos -@genericBuilder@ $@ - -# populate the EFI directory with syslinux, and configure it to read that extlinux.conf file managed by nixos -mkdir -p $target/EFI/syslinux $target/EFI/BOOT -cp @syslinux@/share/syslinux/efi64/* $target/EFI/syslinux/ -echo "DEFAULT trampoline" > $target/EFI/syslinux/syslinux.cfg -echo "LABEL trampoline" >> $target/EFI/syslinux/syslinux.cfg -echo "CONFIG ../../extlinux/extlinux.conf ../../extlinux" >> $target/EFI/syslinux/syslinux.cfg - -# create the EFI/BOOT/BOOTX64.EFI default entry -cp $target/EFI/syslinux/* $target/EFI/BOOT -mv $target/EFI/BOOT/syslinux.efi $target/EFI/BOOT/BOOTX64.EFI diff --git a/modules/hardware/extlinux.nix b/modules/hardware/extlinux.nix deleted file mode 100644 index 5c874814..00000000 --- a/modules/hardware/extlinux.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ lib, pkgs, config, nixpkgs, ... }: - -with lib; -let - cfg = config.colinsane.extlinux; - genericBuilder = (import "${nixpkgs}/nixos/modules/system/boot/loader/generic-extlinux-compatible/extlinux-conf-builder.nix" { inherit pkgs; }); - builder = pkgs.substituteAll { - src = ./extlinux-builder.sh; - isExecutable = true; - inherit (pkgs) bash syslinux; - inherit genericBuilder; - }; -in -{ - options = { - colinsane.extlinux.enable = mkOption { - default = false; - type = types.bool; - }; - }; - - config = mkIf cfg.enable { - # XXX: i'm not 100% sure this is true. i saw some errors related to reading EFI vars though. - boot.loader.efi.canTouchEfiVariables = false; - system.build.installBootLoader = let - dtCfg = config.hardware.deviceTree; - builderArgs = "-g 20 -t 5" - + lib.optionalString (dtCfg.name != null) "-n ${dtCfg.name}"; - - in "${builder} ${builderArgs} -c"; - system.boot.loader.id = "extlinux"; - }; - - # i'm not sure why the below doesn't work instead?? - # config = mkIf cfg.enable { - # system.build.installBootLoader = - # let - # generic-install = (import "${nixpkgs}/nixos/modules/system/boot/loader/generic-extlinux-compatible/default.nix" { - # inherit lib pkgs; - # config = config // { - # boot.loader.generic-extlinux-compatible.enable = true; - # }; - # }); - # in generic-install.config.system.build.installBootLoader; - # system.boot.loader.id = "extlinux"; - # }; -} diff --git a/modules/image.nix b/modules/image.nix index b2ab430e..45134b64 100644 --- a/modules/image.nix +++ b/modules/image.nix @@ -1,90 +1,105 @@ { config, lib, pkgs, mobile-nixos, utils, ... }: +with lib; let - # return true if super starts with sub - startsWith = super: sub: ( - (builtins.substring 0 (builtins.stringLength sub) super) == sub - ); - # return the (string) path to get from `stem` to `path` - relPath = stem: path: ( - builtins.head (builtins.match "^${stem}(.+)" path) - ); - - fileSystems = config.fileSystems; - bootFs = fileSystems."/boot"; - nixFs = fileSystems."/nix/store" or fileSystems."/nix" or fileSystems."/"; - # resolves to e.g. "nix/store", "/store" or "" - storeRelPath = relPath nixFs.mountPoint "/nix/store"; - - # return a list of all the `device` values -- one for each fileSystems."$x" - devices = builtins.attrValues (builtins.mapAttrs (mount: entry: entry.device) fileSystems); - # filter the devices to just those which sit under nixFs - subNixMounts = builtins.filter (a: startsWith (builtins.toString a) nixFs.mountPoint) devices; - # e.g. ["/nix/persist/var"] -> ["/persist/var"] if nixFs sits at /nix - subNixRelMounts = builtins.map (m: relPath nixFs.mountPoint m) subNixMounts; - makeSubNixMounts = builtins.toString (builtins.map (m: "mkdir -p ./${m};") subNixRelMounts); - - uuidFromFs = fs: builtins.head (builtins.match "/dev/disk/by-uuid/(.+)" fs.device); - vfatUuidFromFs = fs: builtins.replaceStrings ["-"] [""] (uuidFromFs fs); - - fsBuilderMapBoot = { - "vfat" = pkgs.imageBuilder.fileSystem.makeESP; - }; - fsBuilderMapNix = { - "ext4" = pkgs.imageBuilder.fileSystem.makeExt4; - "btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs; - }; + cfg = config.colinsane.image; in { - system.build.img-without-firmware = with pkgs; imageBuilder.diskImage.makeGPT { - name = "nixos"; - diskID = vfatUuidFromFs bootFs; - # leave some space for firmware - # TODO: we'd prefer to turn this into a protected firmware partition, rather than reserving space in the GPT header itself - # Tow-Boot manages to do that; not sure how. - # TODO: does this method work on all systems (test on lappy) - headerHole = imageBuilder.size.MiB 16; - partitions = [ - (fsBuilderMapBoot."${bootFs.fsType}" { - # fs properties - name = "ESP"; - partitionID = vfatUuidFromFs bootFs; - # partition properties - partitionLabel = "EFI System"; - partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}"; - size = imageBuilder.size.MiB 256; - - populateCommands = '' - echo "running installBootLoader" - ${config.system.build.installBootLoader} ${config.system.build.toplevel} -d . - echo "ran installBootLoader" - ''; - }) - (fsBuilderMapNix."${nixFs.fsType}" { - # fs properties - name = "NIXOS_SYSTEM"; - partitionID = uuidFromFs nixFs; - # partition properties - partitionLabel = "Linux filesystem"; - partitionUUID = uuidFromFs nixFs; - populateCommands = - let - closureInfo = buildPackages.closureInfo { rootPaths = config.system.build.toplevel; }; - in - '' - mkdir -p ./${storeRelPath} - # TODO: we should either fix up the owners (and perms?), or only create the bare minimum needed for boot (i.e. /var/*) - ${makeSubNixMounts} - echo "Copying system closure..." - while IFS= read -r path; do - echo " Copying $path" - cp -prf "$path" ./${storeRelPath} - done < "${closureInfo}/store-paths" - echo "Done copying system closure..." - cp -v ${closureInfo}/registration ./nix-path-registration - ''; - }) - ]; + options = { + colinsane.image.extraBootFiles = mkOption { + default = []; + type = types.listOf types.package; + }; + }; + config = let + # return true if super starts with sub + startsWith = super: sub: ( + (builtins.substring 0 (builtins.stringLength sub) super) == sub + ); + # return the (string) path to get from `stem` to `path` + relPath = stem: path: ( + builtins.head (builtins.match "^${stem}(.+)" path) + ); + + fileSystems = config.fileSystems; + bootFs = fileSystems."/boot"; + nixFs = fileSystems."/nix/store" or fileSystems."/nix" or fileSystems."/"; + # resolves to e.g. "nix/store", "/store" or "" + storeRelPath = relPath nixFs.mountPoint "/nix/store"; + + # return a list of all the `device` values -- one for each fileSystems."$x" + devices = builtins.attrValues (builtins.mapAttrs (mount: entry: entry.device) fileSystems); + # filter the devices to just those which sit under nixFs + subNixMounts = builtins.filter (a: startsWith (builtins.toString a) nixFs.mountPoint) devices; + # e.g. ["/nix/persist/var"] -> ["/persist/var"] if nixFs sits at /nix + subNixRelMounts = builtins.map (m: relPath nixFs.mountPoint m) subNixMounts; + makeSubNixMounts = builtins.toString (builtins.map (m: "mkdir -p ./${m};") subNixRelMounts); + + uuidFromFs = fs: builtins.head (builtins.match "/dev/disk/by-uuid/(.+)" fs.device); + vfatUuidFromFs = fs: builtins.replaceStrings ["-"] [""] (uuidFromFs fs); + + fsBuilderMapBoot = { + "vfat" = pkgs.imageBuilder.fileSystem.makeESP; + }; + fsBuilderMapNix = { + "ext4" = pkgs.imageBuilder.fileSystem.makeExt4; + "btrfs" = pkgs.imageBuilder.fileSystem.makeBtrfs; + }; + in { + system.build.img-without-firmware = with pkgs; imageBuilder.diskImage.makeGPT { + name = "nixos"; + diskID = vfatUuidFromFs bootFs; + # leave some space for firmware + # TODO: we'd prefer to turn this into a protected firmware partition, rather than reserving space in the GPT header itself + # Tow-Boot manages to do that; not sure how. + # TODO: does this method work on all systems (test on lappy) + headerHole = imageBuilder.size.MiB 16; + partitions = [ + (fsBuilderMapBoot."${bootFs.fsType}" { + # fs properties + name = "ESP"; + partitionID = vfatUuidFromFs bootFs; + # partition properties + partitionLabel = "EFI System"; + partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}"; + size = imageBuilder.size.MiB 256; + + populateCommands = let + extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles); + in '' + echo "running installBootLoader" + ${config.system.build.installBootLoader} ${config.system.build.toplevel} -d . + echo "ran installBootLoader" + ${extras} + echo "copied extraBootFiles" + ''; + }) + (fsBuilderMapNix."${nixFs.fsType}" { + # fs properties + name = "NIXOS_SYSTEM"; + partitionID = uuidFromFs nixFs; + # partition properties + partitionLabel = "Linux filesystem"; + partitionUUID = uuidFromFs nixFs; + populateCommands = + let + closureInfo = buildPackages.closureInfo { rootPaths = config.system.build.toplevel; }; + in + '' + mkdir -p ./${storeRelPath} + # TODO: we should either fix up the owners (and perms?), or only create the bare minimum needed for boot (i.e. /var/*) + ${makeSubNixMounts} + echo "Copying system closure..." + while IFS= read -r path; do + echo " Copying $path" + cp -prf "$path" ./${storeRelPath} + done < "${closureInfo}/store-paths" + echo "Done copying system closure..." + cp -v ${closureInfo}/registration ./nix-path-registration + ''; + }) + ]; + }; + system.build.img = lib.mkDefault config.system.build.img-without-firmware; }; - system.build.img = lib.mkDefault config.system.build.img-without-firmware; }