From d9c1a97ef633cfea7af801bc9974746520efefab Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 23 Jun 2025 02:32:17 +0000 Subject: [PATCH] modules/image.nix: remove dependency on mobile-nixos the images build, but i have not tried booting them --- integrations/nur/default.nix | 1 - modules/image.nix | 299 ++++++++++++++++++++------ pkgs/by-name/mobile-nixos/package.nix | 19 -- 3 files changed, 238 insertions(+), 81 deletions(-) delete mode 100644 pkgs/by-name/mobile-nixos/package.nix diff --git a/integrations/nur/default.nix b/integrations/nur/default.nix index 90b3cd043..bf4a009b6 100644 --- a/integrations/nur/default.nix +++ b/integrations/nur/default.nix @@ -39,7 +39,6 @@ let "linux-postmarketos-allwinner" "linux-postmarketos-exynos5" "linux-postmarketos-pinephonepro" - "mobile-nixos" "nixpkgs-bootstrap" "nixpkgs-wayland" "sops-nix" diff --git a/modules/image.nix b/modules/image.nix index 02e6c244f..f84c6f949 100644 --- a/modules/image.nix +++ b/modules/image.nix @@ -23,12 +23,6 @@ in default = []; type = types.listOf types.package; }; - # extra (empty) directories to create in the rootfs. - # for example, /var/log might be required by the boot process, so ensure it exists. - sane.image.extraDirectories = mkOption { - default = []; - type = types.listOf types.str; - }; # the GPT header is fixed to Logical Block Address 1, # but we can actually put the partition entries anywhere. @@ -47,9 +41,7 @@ in sane.image.firstPartGap = mkOption { # align the first part to 16 MiB. # do this by inserting a gap of 16 MiB - gptHeaderSize - # and then multiply by 1MiB and subtract 1 because mobile-nixos - # has a bug which will divide this by 1 MiB (and round up) - default = (16 * 1024 * 1024 - 34 * 512) * 1024 * 1024 - 1; + default = 16 * 1024 * 1024 - 34 * 512; type = types.nullOr types.int; }; sane.image.platformPartSize = mkOption { @@ -107,91 +99,276 @@ in uuidFromFs = fs: builtins.head (builtins.match "/dev/disk/by-uuid/(.+)" fs.device); vfatUuidFromFs = fs: builtins.replaceStrings ["-"] [""] (uuidFromFs fs); - fsBuilderMapBoot = { - "vfat" = pkgs.mobile-nixos.imageBuilder.fileSystem.makeESP; - }; - fsBuilderMapNix = { - "ext4" = pkgs.mobile-nixos.imageBuilder.fileSystem.makeExt4; - "btrfs" = pkgs.mobile-nixos.imageBuilder.fileSystem.makeBtrfs; - }; + # TODO: consolidate bootFsImg, nixFsImg builders; split into separate file? - bootFsImg = fsBuilderMapBoot."${bootFs.fsType}" { - # fs properties - name = "ESP"; + bootFsImg = pkgs.runCommandNoCC "ESP" { + nativeBuildInputs = with pkgs; [ + dosfstools + libfaketime + mtools + ]; partitionID = vfatUuidFromFs bootFs; + size = cfg.bootPartSize; + sectorSize = cfg.sectorSize; # partition properties partitionLabel = "EFI System"; + partitionType = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"; # "EFI" partitionUUID = "44444444-4444-4444-4444-4444${vfatUuidFromFs bootFs}"; - size = cfg.bootPartSize; - inherit (cfg) sectorSize; - blockSize = cfg.sectorSize; # has to be a multiple of sectorSize + } '' + # hoisted (in simplified form) from pkgs.mobile-nixos.imageBuilder.fileSystem.makeESP + mkdir -p $out + mkdir -p files - populateCommands = let - extras = builtins.toString (builtins.map (d: "cp -R ${d}/* ./") cfg.extraBootFiles); - in '' + ( + cd files echo "running installBootLoader" ${config.boot.loader.generic-extlinux-compatible.populateCmd} -c ${config.system.build.toplevel} -d . echo "ran installBootLoader" - ${extras} + for d in ${lib.escapeShellArgs cfg.extraBootFiles}; do + cp -R $d/* ./ + done echo "copied extraBootFiles" - ''; - }; - nixFsImg = fsBuilderMapNix."${nixFs.fsType}" { + ) + + ( + set -x + truncate -s $size "$out/partition.img" + ) + + echo " -> Making filesystem" + faketime -f "1970-01-01 00:00:01" mkfs.vfat \ + -F 32 \ + -S "$sectorSize" \ + -i "$partitionID" \ + -n "$partName" \ + "$out/partition.img" + + echo " -> Copying files" + ( + cd files + for f in ./* ./.*; do + if [[ "$f" != "./." && "$f" != "./.." ]]; then + faketime -f "1970-01-01 00:00:01" \ + mcopy -psv -i "$out/partition.img" "$f" :: + fi + done + ) + + echo " -> Checking filesystem" + fsck.vfat -vn "$out/partition.img" + + cat >> $out/layout.json <&2 + + # Adds one blockSize per directory, they do take some place, in the end. + local directories=$(find . -type d | wc -l) + echo "Reserving $directories sectors for directories..." 1>&2 + ) + + size=$(( $directories + $size )) + size=$(( $size * $blockSize)) + echo "$size" + } + + mkdir -p $out + mkdir -p files + + ( + cd files + mkdir -p ./${storeRelPath} echo "Copying system closure..." while IFS= read -r path; do echo " Copying $path" cp -prf "$path" ./${storeRelPath} - done < "${closureInfo}/store-paths" + done < "${pkgs.buildPackages.closureInfo { rootPaths = config.system.build.toplevel; }}/store-paths" echo "Done copying system closure..." - cp -v ${closureInfo}/registration ./nix-path-registration - ''; - }; - img = (pkgs.mobile-nixos.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. - headerHole = cfg.extraGPTPadding; - partitions = [ - (pkgs.mobile-nixos.imageBuilder.gap cfg.firstPartGap) - ] ++ lib.optionals (cfg.platformPartSize != null) [ - { - name = "kernel"; #< TODO: is it safe to rename this? - filename = "${config.system.build.platformPartition}"; - # from: - partitionType = "FE3A2A5D-4F32-41A7-B725-ACCC3285A309"; - length = cfg.platformPartSize; - } + ) + + ( + size=$(compute-minimal-size) + + set -x + truncate -s $size "$out/partition.img" + ) + + ( + cd files + set -x + mkfs.btrfs \ + -r . \ + -L "$partName" \ + -U "$partitionID" \ + --shrink \ + "$out/partition.img" + ) + + cat >> $out/layout.json < + partitionType = "FE3A2A5D-4F32-41A7-B725-ACCC3285A309"; # "ChromeOS Kernel" + partitionLabel = "kernel"; #< TODO: is it safe to rename this? + } '' + mkdir $out + truncate -s $partSize $out/partition.img + dd if=$partImage of=$out/partition.img bs=512 + # TODO: assert that the `dd` command didn't overflow the allocated partition space + cat >> $out/layout.json < primary GPT header" + totalSize=$part0Start + for part in $partitions; do + echo "- $totalSize -> $part" + partSize=$(getPartSize $part) + totalSize=$(( $totalSize + $partSize )) + done + echo "- $totalSize -> secondary GPT header" + totalSize=$(( $totalSize + $gptSize )) + echo "- $totalSize -> end of disk" + + truncate -s $totalSize $out/disk.img + # Zeroes the GPT + cgpt create -z $out/disk.img + # Create the GPT with space if desired + cgpt create -p 0 $out/disk.img + # Add the PMBR + cgpt boot -p $out/disk.img + ) + + ( + partStart=$part0Start + for part in $partitions; do + partSize=$(getPartSize $part) + partitionType=$(jq -r .partitionType $part/layout.json) + partitionUUID=$(jq -r .partitionUUID $part/layout.json) + partitionLabel=$(jq -r .partitionLabel $part/layout.json) + + ( + set -x + cgpt add \ + -b "$(( $partStart / $sectorSize ))" \ + -s "$(( $partSize / $sectorSize ))" \ + -t "$partitionType" \ + -u "$partitionUUID" \ + -l "$partitionLabel" \ + $out/disk.img + dd conv=notrunc if=$part/partition.img of=$out/disk.img \ + seek=$(( $partStart / $sectorSize)) count=$(( $partSize / $sectorSize )) bs=$sectorSize + ) + + partStart=$(( $partStart + $partSize )) + done + ) + + echo "disk image created:" + ls -lh $out/disk.img + cgpt show $out/disk.img + ''; in { - system.build.img = pkgs.runCommand "nixos-with-bootloader" { + system.build.img = pkgs.runCommandNoCC "nixos-with-bootloader" { preferLocalBuild = true; passthru = { inherit bootFsImg nixFsImg; - withoutBootloader = img; #< XXX: this derivation places the image at $out/nixos.img + withoutBootloader = img; #< XXX: this derivation places the image at $out/disk.img }; } ( if cfg.installBootloader == null then '' diff --git a/pkgs/by-name/mobile-nixos/package.nix b/pkgs/by-name/mobile-nixos/package.nix deleted file mode 100644 index 6aaa753bd..000000000 --- a/pkgs/by-name/mobile-nixos/package.nix +++ /dev/null @@ -1,19 +0,0 @@ -{ pkgs -, fetchFromGitHub -}: -let - src = fetchFromGitHub { - owner = "nixos"; - repo = "mobile-nixos"; - # XXX: commit `0f3ac0bef1aea70254a3bae35e3cc2561623f4c1` - # replaces the imageBuilder with a "new implementation from celun" and wildly breaks my use. - # pinning to d25d3b... is equivalent to holding at 2023-09-15 - rev = "d25d3b87e7f300d8066e31d792337d9cd7ecd23b"; - hash = "sha256-MiVokKlpcJmfoGuWAMeW1En7gZ5hk0rCQArYm6P9XCc="; - }; - overlay = import "${src}/overlay/overlay.nix"; - final = pkgs.extend overlay; -in src.overrideAttrs (base: { - # passthru only mobile-nixos' own packages -- not the whole nixpkgs-with-mobile-nixos-as-overlay: - passthru = base.passthru // (overlay final pkgs); -})