1
0
Fork 0
nix-system-configurations/nixos/raspi/disko-config.nix

176 lines
5.6 KiB
Nix

# SPDX-FileCopyrightText: 2025 Ethan Reece <contact@ethanreece.com>
#
# SPDX-License-Identifier: MIT
#
# Uses unlicensed snippets from https://github.com/nix-community/disko/issues/550 meant for public use.
{ pkgs, ... }:
let
# SPDX-SnippetBegin
# SPDX-SnippetCopyrightText: 2024 MatthewCroughan <https://github.com/nix-community/disko/issues/550#issuecomment-2503736973>
configTxt = pkgs.writeText "config.txt" ''
[pi4]
kernel=u-boot-rpi4.bin
enable_gic=1
# Otherwise the resolution will be weird in most cases, compared to
# what the pi3 firmware does by default.
disable_overscan=1
# Supported in newer board revisions
arm_boost=1
[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1
[all]
# Boot in 64-bit mode.
arm_64bit=1
# U-Boot needs this to work, regardless of whether UART is actually used or not.
# Look in arch/arm/mach-bcm283x/Kconfig in the U-Boot tree to see if this is still
# a requirement in the future.
enable_uart=1
# Prevent the firmware from smashing the framebuffer setup done by the mainline kernel
# when attempting to show low-voltage or overtemperature warnings.
avoid_warnings=1
'';
# SPDX-SnippetEnd
device = "/dev/sda";
labels = {
boot = "NIXOS_BOOT";
firmware = "NIXOS_FW";
luks = "NIXOS_LUKS";
root = "NIXOS_ROOT";
};
in
{
boot.postBootCommands = ''
# On the first boot, resize the disk
if [ -f /persistent/disko-first-boot ]; then
set -euo pipefail
set -x
# Figure out device names for the boot device and root filesystem.
rootPart=$(${pkgs.util-linux}/bin/findmnt -n -o SOURCE /)
cryptDevice=$(lsblk -npo PKNAME "$rootPart")
bootDevice=$(lsblk -npo PKNAME "/dev/mapper/$cryptDevice")
partNum=$(lsblk -npo MAJ:MIN "/dev/mapper/$cryptDevice" | ${pkgs.gawk}/bin/awk -F: '{print $2}')
# Resize partition to fill disk
echo ",+," | sfdisk -N$partNum --no-reread "$bootDevice"
${pkgs.parted}/bin/partprobe
# Resize cryptographic layer
${pkgs.cryptsetup}/bin/cryptsetup resize "$cryptDevice"
# Resize physical volume
${pkgs.lvm2}/bin/pvresize "/dev/mapper/$cryptDevice"
# Resize logical volume
${pkgs.lvm2}/bin/lvextend -l +100%FREE "$rootPart"
# Resize Btrfs filesystem
${pkgs.btrfs-progs}/bin/btrfs filesystem resize max /
# Prevents this from running on later boots.
rm -f /persistent/disko-first-boot
fi
'';
disko = {
# SPDX-SnippetBegin
# SPDX-License-Identifier: LicenseRef-Unspecified
# SPDX-SnippetCopyrightText: 2024 MatthewCroughan <https://github.com/nix-community/disko/issues/550#issuecomment-2503736973>
imageBuilder = {
kernelPackages = pkgs.linuxPackages_latest;
extraPostVM = ''
${pkgs.zstd}/bin/zstd --compress $out/*raw
rm $out/*raw
'';
};
devices = {
disk = {
disk1 = {
inherit device;
imageSize = "20G";
type = "disk";
postCreateHook = ''
lsblk
sgdisk -A 1:set:2 ${device}
'';
content = {
type = "gpt";
partitions = {
firmware = {
size = "30M";
priority = 1;
type = "0700";
label = labels.firmware;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/firmware";
postMountHook = toString (
pkgs.writeScript "postMountHook.sh" ''
(cd ${pkgs.raspberrypifw}/share/raspberrypi/boot && cp bootcode.bin fixup*.dat start*.elf *.dtb /mnt/firmware/)
cp ${pkgs.ubootRaspberryPi4_64bit}/u-boot.bin /mnt/firmware/u-boot-rpi4.bin
cp ${configTxt} /mnt/firmware/config.txt
''
);
};
};
# SPDX-SnippetEnd
boot = {
size = "1G";
type = "EF00";
label = labels.boot;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
};
luks = {
size = "100%";
content = {
types = "luks";
name = "encrypted";
label = labels.luks;
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"root" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" ];
};
"persistent" = {
mountpoint = "/persistent";
mountOptions = [ "compress=zstd" ];
};
"nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" ];
};
};
postMountHook = toString (
pkgs.writeScript "postMountHook.sh" ''
touch /mnt/persistent/disko-first-boot
''
);
};
};
};
};
};
};
};
};
};
}