Skip to content

Instantly share code, notes, and snippets.

@rickynils
Created February 5, 2026 18:02
Show Gist options
  • Select an option

  • Save rickynils/5b919bebaacb10311f8ae1513d1734c6 to your computer and use it in GitHub Desktop.

Select an option

Save rickynils/5b919bebaacb10311f8ae1513d1734c6 to your computer and use it in GitHub Desktop.
image_x86_64 = pkgs.runCommand "${cfg.product}-image" {
buildInputs = with pkgs; [
bc
coreutils
dosfstools
e2fsprogs
fakeroot
gnutar
jq
mtools
parted
pigz
syslinux
unixtools.xxd
];
closureInfo = pkgs.closureInfo {
rootPaths = [config.system.build.toplevel];
};
inherit (pkgs) syslinux;
sys = config.system.build.toplevel;
imageInfo = pkgs.writeText "image-info.json" (builtins.toJSON (imageInfo));
nixosInfo = pkgs.writeText "nixos.json" (builtins.toJSON config.system.nixos);
} ''
# Use fakeroot so the created file systems have entries with uid:gid=0:0
fakeroot "${pkgs.writers.writeBash "image_x86_64" ''
mkdir -p "$out/nix-support"
echo "Copying nix closures..."
mkdir nixstore
for p in $(cat $closureInfo/store-paths); do
cp -rdT "$p" "nixstore/$(basename "$p")"
done
store_size_mb="$(echo "scale=0; $(du -sxm nixstore | cut -f1) / 0.8" | bc -l)"
boot_size_mb=128
root_size_mb=128
disk_size_mb="$((2 + boot_size_mb + store_size_mb + root_size_mb))"
inode_count="$(echo "scale=0; $(find nixstore | wc -l) / 0.9" | bc -l)"
truncate -s ''${disk_size_mb}M disk.raw
truncate -s ''${boot_size_mb}M boot.fat
echo "Creating a FAT file system for the boot files..."
mkfs.fat -n SYSLINUX boot.fat
echo "Installing syslinux..."
syslinux --directory / --install boot.fat
echo "Populating the boot file system..."
mcopy -i boot.fat $sys/kernel ::kernel
mcopy -i boot.fat $sys/initrd ::initrd
mcopy -i boot.fat - ::syslinux.cfg <<EOF
SERIAL 0 9600
DEFAULT nixos
LABEL nixos
SAY Now booting the NixOS from SYSLINUX...
LINUX kernel
INITRD initrd
APPEND init=$sys/init systemConfig=$sys $(cat $sys/kernel-params)
EOF
echo "Copying the boot filesystem to the disk image..."
dd bs=1M seek=1 conv=notrunc,sparse if=boot.fat of=disk.raw
echo "Creating an EXT4 file system for the nix store..."
mkfs.ext4 -v \
-d nixstore -L nixstore \
-U "${nixstoreUUID}" \
-N "$inode_count" \
-E offset=$((1024*1024*(1+boot_size_mb))) disk.raw ''${store_size_mb}M
echo "Creating an EXT4 file system for the root..."
mkfs.ext4 -v \
-L "${if cfg.ephemeralRoot then "var" else rootLabel}" \
-U "${rootUUID}" \
-E offset=$((1024*1024*(1+boot_size_mb+store_size_mb))) disk.raw ''${root_size_mb}M
echo "Creating a partition table..."
parted --script disk.raw -- \
unit MiB \
mklabel msdos \
mkpart primary fat32 1 $((1+boot_size_mb)) \
mkpart primary ext4 $((1+boot_size_mb)) $((1+boot_size_mb+store_size_mb)) \
mkpart primary ext4 $((1+boot_size_mb+store_size_mb)) 100% \
set 1 boot on \
print
echo "Copying the SYSLINUX MBR..."
dd bs=440 conv=notrunc if=$syslinux/share/syslinux/mbr.bin of=disk.raw
logicalBytes="$(stat -c%s disk.raw)"
echo "Finalizing the disk image..."
${if cfg.image.format == "raw" then ''
file="$out/image.raw"
mv disk.raw "$file"
'' else ''
file="$out/image.tar.gz"
tar --create -S --format=oldgnu disk.raw | pigz -c - > "$file"
''}
echo "Writing image info.."
cp "$nixosInfo" "$out/nix-support/nixos-info.json"
jq <"$imageInfo" >"$out/nix-support/image-info.json" \
--arg file "$file" \
--argjson logicalBytes "$logicalBytes" \
--arg hash "$(sha256sum "$file" | cut -d ' ' -f1 | xxd -r -p | base64)" \
'({
"file": $file,
"file_sha256_base64": $hash,
"logical_bytes": $logicalBytes,
"boot_mode": "legacy-bios"
}) * .'
''}"
'';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment