* [PATCH 0/2] Move verity and EFI creation to separate Nix derivations
@ 2025-11-05 22:33 Demi Marie Obenour
2025-11-05 22:33 ` [PATCH 1/2] Create Nix derivation for building verity images Demi Marie Obenour
` (2 more replies)
0 siblings, 3 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-05 22:33 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Demi Marie Obenour (2):
Create Nix derivation for building verity images
Move UKI creation to a separate derivation
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 25 +++++--------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 24 +++++-------------------
host/rootfs/shell.nix | 3 +++
host/verity.nix | 19 +++++++++++++++++++
lib/common.mk | 1 -
pkgs/default.nix | 2 ++
release/live/Makefile | 37 +++++--------------------------------
release/live/default.nix | 22 +++++++---------------
10 files changed, 95 insertions(+), 88 deletions(-)
---
base-commit: 43a8c81c58d73967635f57fdd84734d44120bc39
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH 1/2] Create Nix derivation for building verity images
2025-11-05 22:33 [PATCH 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-05 22:33 ` Demi Marie Obenour
2025-11-06 10:20 ` Alyssa Ross
2025-11-05 22:33 ` [PATCH 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-05 22:33 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This gets rid of a lot of duplicated code and allows building the verity
roothash and superblock only when needed. It also removes a hack used
to work around make limitations. Furthermore,
'veritysetup --root-hash-file' is used to avoid an awk script.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
nix-shell --pure --run 'make run' in host/initramfs fails. This is a
preexisting bug and I will send a separate patch for it.
---
host/initramfs/Makefile | 25 +++++--------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 24 +++++-------------------
host/rootfs/shell.nix | 3 +++
host/verity.nix | 19 +++++++++++++++++++
lib/common.mk | 1 -
pkgs/default.nix | 1 +
release/live/Makefile | 26 +++++---------------------
release/live/default.nix | 4 +++-
9 files changed, 44 insertions(+), 63 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..5c8c0eb2e50efcef33d78f91b562d8e79a76a900 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,11 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
+ $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +54,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index eeba865e3ac793f67ae1808a92cf5eb1b37d57af..3e2abd17d2a989aa056d6f20633c624717e6b775 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -3,7 +3,7 @@
import ../../lib/call-package.nix (
{ callSpectrumPackage, rootfs, pkgsStatic, stdenv
-, cryptsetup, qemu_kvm, tar2ext4, util-linux
+, cryptsetup, qemu_kvm, tar2ext4, util-linux, verity
}:
let
@@ -18,5 +18,7 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = rootfs;
+ ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -82,25 +82,11 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
+ $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
debug:
@@ -110,7 +96,7 @@ debug:
$(VMLINUX)
.PHONY: debug
-run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
+run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
truncate -s 10G "$$ext" && \
@@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -5,6 +5,7 @@
import ../../lib/call-package.nix (
{ callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
, btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
+, verity
}:
rootfs.overrideAttrs (
@@ -20,5 +21,7 @@ rootfs.overrideAttrs (
KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
LINUX_SRC = srcOnly passthru.kernel.configfile;
VMLINUX = "${passthru.kernel.dev}/vmlinux";
+ ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
};
})) (_: {})
diff --git a/host/verity.nix b/host/verity.nix
new file mode 100644
index 0000000000000000000000000000000000000000..b144c4e270e8aa874b38c0aec69b6d99393a14b9
--- /dev/null
+++ b/host/verity.nix
@@ -0,0 +1,19 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix ({ cryptsetup, runCommand, rootfs }:
+runCommand "spectrum-verity" {
+ nativeBuildInputs = [ cryptsetup ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ env = { ROOTFS = rootfs; };
+} ''
+ mkdir -- "$out"
+ veritysetup format "--root-hash-file=$out/rootfs.verity.roothash" \
+ -- "$ROOTFS" "$out/rootfs.verity.superblock"
+ # veritysetup doesn't append a newline, so the shell read command fails
+ echo >> "$out/rootfs.verity.roothash"
+ ''
+) (_: {})
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..f4aa15ef8fc053ae61a8d875eac4fc6a094411c6 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -15,7 +15,6 @@ S6_IPCSERVER_SOCKETBINDER = s6-ipcserver-socketbinder
TAR = tar
TRUNCATE = truncate
UKIFY = ukify
-VERITYSETUP = veritysetup
VIRTIOFSD = virtiofsd
PACKAGES_FILE != \
diff --git a/pkgs/default.nix b/pkgs/default.nix
index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..bc02f6b2f532f3ee1a2ea3aa45de3c9561bbb6ab 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -36,6 +36,7 @@ let
path: (import path { inherit (self) callPackage; }).override;
rootfs = self.callSpectrumPackage ../host/rootfs {};
+ verity = self.callSpectrumPackage ../host/verity.nix {};
spectrum-build-tools = self.callSpectrumPackage ../tools {
appSupport = false;
buildSupport = true;
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..191b44944af0adf965e1d5f2785719b236bfd99c 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY":verity:$$(../../scripts/format-uuid.sh "$$(dd if="$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..32901f00a270f6dae005563b2e4082ad225c61e1 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
{ callSpectrumPackage, spectrum-build-tools, rootfs, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
+, systemdUkify, verity
}:
let
@@ -47,6 +47,8 @@ stdenv.mkDerivation {
INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = rootfs;
+ ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
EFINAME = "BOOT${toUpper efiArch}.EFI";
} // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH 2/2] Move UKI creation to a separate derivation
2025-11-05 22:33 [PATCH 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-05 22:33 ` [PATCH 1/2] Create Nix derivation for building verity images Demi Marie Obenour
@ 2025-11-05 22:33 ` Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-05 22:33 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
pkgs/default.nix | 1 +
release/live/Makefile | 15 ++-------------
release/live/default.nix | 20 +++++---------------
4 files changed, 54 insertions(+), 28 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..45c76e4f37f52a62744318df3590dd429c005fe9
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ bash, callSpectrumPackage, cryptsetup, runCommand
+, stdenv, systemdUkify, rootfs, verity
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd bash ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit systemd; };
+ env = {
+ DTBS = "${rootfs.kernel}/dtbs";
+ KERNEL = kernel;
+ INITRAMFS = initramfs;
+ VERITY = verity;
+ };
+} ''
+ read -r roothash < "$VERITY/rootfs.verity.roothash"
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d "$DTBS" ]; then
+ find "$DTBS" -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux "$KERNEL" \
+ --initrd "$INITRAMFS" \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/pkgs/default.nix b/pkgs/default.nix
index bc02f6b2f532f3ee1a2ea3aa45de3c9561bbb6ab..95f431f560f6bf61dd56141a349210526a519838 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -37,6 +37,7 @@ let
rootfs = self.callSpectrumPackage ../host/rootfs {};
verity = self.callSpectrumPackage ../host/verity.nix {};
+ efi = self.callSpectrumPackage ../host/efi.nix {};
spectrum-build-tools = self.callSpectrumPackage ../tools {
appSupport = false;
buildSupport = true;
diff --git a/release/live/Makefile b/release/live/Makefile
index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
+ ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
diff --git a/release/live/default.nix b/release/live/default.nix
index 32901f00a270f6dae005563b2e4082ad225c61e1..8b9f48997963608db86a1d3346bfe2b66f55adf5 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
{ callSpectrumPackage, spectrum-build-tools, rootfs, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify, verity
+, verity, efi
}:
let
@@ -14,13 +14,6 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
in
@@ -40,19 +33,16 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
- KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = rootfs;
ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
- SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -65,6 +55,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit rootfs; };
}
) (_: {})
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH 1/2] Create Nix derivation for building verity images
2025-11-05 22:33 ` [PATCH 1/2] Create Nix derivation for building verity images Demi Marie Obenour
@ 2025-11-06 10:20 ` Alyssa Ross
2025-11-06 10:55 ` Demi Marie Obenour
0 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-06 10:20 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 5158 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> This gets rid of a lot of duplicated code and allows building the verity
> roothash and superblock only when needed. It also removes a hack used
> to work around make limitations. Furthermore,
> 'veritysetup --root-hash-file' is used to avoid an awk script.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> nix-shell --pure --run 'make run' in host/initramfs fails. This is a
> preexisting bug and I will send a separate patch for it.
> ---
> host/initramfs/Makefile | 25 +++++--------------------
> host/initramfs/shell.nix | 4 +++-
> host/rootfs/Makefile | 24 +++++-------------------
> host/rootfs/shell.nix | 3 +++
> host/verity.nix | 19 +++++++++++++++++++
> lib/common.mk | 1 -
> pkgs/default.nix | 1 +
> release/live/Makefile | 26 +++++---------------------
> release/live/default.nix | 4 +++-
> 9 files changed, 44 insertions(+), 63 deletions(-)
> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
> index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
> --- a/host/rootfs/Makefile
> +++ b/host/rootfs/Makefile
> @@ -82,25 +82,11 @@ clean:
> rm -rf build
> .PHONY: clean
>
> -# veritysetup format produces two files, but Make only (portably)
> -# supports one output per rule, so we combine the two outputs then
> -# define two more rules to separate them again.
> -build/rootfs.verity: $(dest)
> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
> - > build/rootfs.verity.roothash.tmp
> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
> - > $@
> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
> -build/rootfs.verity.roothash: build/rootfs.verity
> - head -n 1 build/rootfs.verity > $@
> -build/rootfs.verity.superblock: build/rootfs.verity
> - tail -n +2 build/rootfs.verity > $@
>
> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
> ../../scripts/make-gpt.sh $@.tmp \
> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
> + $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
> mv $@.tmp $@
>
> debug:
> @@ -110,7 +96,7 @@ debug:
> $(VMLINUX)
> .PHONY: debug
>
> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
> +run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
> @set -x && \
> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
> truncate -s 10G "$$ext" && \
> @@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
> -device virtconsole,chardev=virtiocon0 \
> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
> -drive file=/proc/self/fd/3,if=virtio,format=raw \
> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
> + -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
> -device virtio-keyboard \
> -device virtio-mouse \
> -device virtio-gpu \
> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
> index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
> --- a/host/rootfs/shell.nix
> +++ b/host/rootfs/shell.nix
> @@ -5,6 +5,7 @@
> import ../../lib/call-package.nix (
> { callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
> , btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
> +, verity
> }:
>
> rootfs.overrideAttrs (
> @@ -20,5 +21,7 @@ rootfs.overrideAttrs (
> KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> LINUX_SRC = srcOnly passthru.kernel.configfile;
> VMLINUX = "${passthru.kernel.dev}/vmlinux";
> + ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
> + ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
> };
> })) (_: {})
Surely this would break interactive development of the rootfs?
If I'm in a Nix shell, and make a change to any part of the rootfs, the
verity data in the environment will be out of date. I'd have to leave
and re-enter the Nix shell after /any/ change, waiting for an evaluation
each time, as opposed to the current situation where that's only
necessary when modifying Nix code or other Spectrum components.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 1/2] Create Nix derivation for building verity images
2025-11-06 10:20 ` Alyssa Ross
@ 2025-11-06 10:55 ` Demi Marie Obenour
2025-11-06 11:44 ` Alyssa Ross
0 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-06 10:55 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 5495 bytes --]
On 11/6/25 05:20, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> This gets rid of a lot of duplicated code and allows building the verity
>> roothash and superblock only when needed. It also removes a hack used
>> to work around make limitations. Furthermore,
>> 'veritysetup --root-hash-file' is used to avoid an awk script.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> nix-shell --pure --run 'make run' in host/initramfs fails. This is a
>> preexisting bug and I will send a separate patch for it.
>> ---
>> host/initramfs/Makefile | 25 +++++--------------------
>> host/initramfs/shell.nix | 4 +++-
>> host/rootfs/Makefile | 24 +++++-------------------
>> host/rootfs/shell.nix | 3 +++
>> host/verity.nix | 19 +++++++++++++++++++
>> lib/common.mk | 1 -
>> pkgs/default.nix | 1 +
>> release/live/Makefile | 26 +++++---------------------
>> release/live/default.nix | 4 +++-
>> 9 files changed, 44 insertions(+), 63 deletions(-)
>
>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>> index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
>> --- a/host/rootfs/Makefile
>> +++ b/host/rootfs/Makefile
>> @@ -82,25 +82,11 @@ clean:
>> rm -rf build
>> .PHONY: clean
>>
>> -# veritysetup format produces two files, but Make only (portably)
>> -# supports one output per rule, so we combine the two outputs then
>> -# define two more rules to separate them again.
>> -build/rootfs.verity: $(dest)
>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>> - > build/rootfs.verity.roothash.tmp
>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>> - > $@
>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>> -build/rootfs.verity.roothash: build/rootfs.verity
>> - head -n 1 build/rootfs.verity > $@
>> -build/rootfs.verity.superblock: build/rootfs.verity
>> - tail -n +2 build/rootfs.verity > $@
>>
>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
>> ../../scripts/make-gpt.sh $@.tmp \
>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>> + $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
>> mv $@.tmp $@
>>
>> debug:
>> @@ -110,7 +96,7 @@ debug:
>> $(VMLINUX)
>> .PHONY: debug
>>
>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>> +run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
>> @set -x && \
>> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
>> truncate -s 10G "$$ext" && \
>> @@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>> -device virtconsole,chardev=virtiocon0 \
>> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
>> -drive file=/proc/self/fd/3,if=virtio,format=raw \
>> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
>> + -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
>> -device virtio-keyboard \
>> -device virtio-mouse \
>> -device virtio-gpu \
>> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
>> index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
>> --- a/host/rootfs/shell.nix
>> +++ b/host/rootfs/shell.nix
>> @@ -5,6 +5,7 @@
>> import ../../lib/call-package.nix (
>> { callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
>> , btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
>> +, verity
>> }:
>>
>> rootfs.overrideAttrs (
>> @@ -20,5 +21,7 @@ rootfs.overrideAttrs (
>> KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>> LINUX_SRC = srcOnly passthru.kernel.configfile;
>> VMLINUX = "${passthru.kernel.dev}/vmlinux";
>> + ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
>> + ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
>> };
>> })) (_: {})
>
> Surely this would break interactive development of the rootfs?
> If I'm in a Nix shell, and make a change to any part of the rootfs, the
> verity data in the environment will be out of date. I'd have to leave
> and re-enter the Nix shell after /any/ change, waiting for an evaluation
> each time, as opposed to the current situation where that's only
> necessary when modifying Nix code or other Spectrum components.
It would. Are there alternatives you can recommend? I don't want the
updater and the installer to have to use two different copies.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 1/2] Create Nix derivation for building verity images
2025-11-06 10:55 ` Demi Marie Obenour
@ 2025-11-06 11:44 ` Alyssa Ross
2025-11-07 19:24 ` Demi Marie Obenour
0 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-06 11:44 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 5838 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> On 11/6/25 05:20, Alyssa Ross wrote:
>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>
>>> This gets rid of a lot of duplicated code and allows building the verity
>>> roothash and superblock only when needed. It also removes a hack used
>>> to work around make limitations. Furthermore,
>>> 'veritysetup --root-hash-file' is used to avoid an awk script.
>>>
>>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>>> ---
>>> nix-shell --pure --run 'make run' in host/initramfs fails. This is a
>>> preexisting bug and I will send a separate patch for it.
>>> ---
>>> host/initramfs/Makefile | 25 +++++--------------------
>>> host/initramfs/shell.nix | 4 +++-
>>> host/rootfs/Makefile | 24 +++++-------------------
>>> host/rootfs/shell.nix | 3 +++
>>> host/verity.nix | 19 +++++++++++++++++++
>>> lib/common.mk | 1 -
>>> pkgs/default.nix | 1 +
>>> release/live/Makefile | 26 +++++---------------------
>>> release/live/default.nix | 4 +++-
>>> 9 files changed, 44 insertions(+), 63 deletions(-)
>>
>>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>>> index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
>>> --- a/host/rootfs/Makefile
>>> +++ b/host/rootfs/Makefile
>>> @@ -82,25 +82,11 @@ clean:
>>> rm -rf build
>>> .PHONY: clean
>>>
>>> -# veritysetup format produces two files, but Make only (portably)
>>> -# supports one output per rule, so we combine the two outputs then
>>> -# define two more rules to separate them again.
>>> -build/rootfs.verity: $(dest)
>>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>>> - > build/rootfs.verity.roothash.tmp
>>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>>> - > $@
>>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>>> -build/rootfs.verity.roothash: build/rootfs.verity
>>> - head -n 1 build/rootfs.verity > $@
>>> -build/rootfs.verity.superblock: build/rootfs.verity
>>> - tail -n +2 build/rootfs.verity > $@
>>>
>>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
>>> ../../scripts/make-gpt.sh $@.tmp \
>>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>>> + $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
>>> mv $@.tmp $@
>>>
>>> debug:
>>> @@ -110,7 +96,7 @@ debug:
>>> $(VMLINUX)
>>> .PHONY: debug
>>>
>>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>> +run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
>>> @set -x && \
>>> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
>>> truncate -s 10G "$$ext" && \
>>> @@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>> -device virtconsole,chardev=virtiocon0 \
>>> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
>>> -drive file=/proc/self/fd/3,if=virtio,format=raw \
>>> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
>>> + -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
>>> -device virtio-keyboard \
>>> -device virtio-mouse \
>>> -device virtio-gpu \
>>> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
>>> index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
>>> --- a/host/rootfs/shell.nix
>>> +++ b/host/rootfs/shell.nix
>>> @@ -5,6 +5,7 @@
>>> import ../../lib/call-package.nix (
>>> { callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
>>> , btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
>>> +, verity
>>> }:
>>>
>>> rootfs.overrideAttrs (
>>> @@ -20,5 +21,7 @@ rootfs.overrideAttrs (
>>> KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>>> LINUX_SRC = srcOnly passthru.kernel.configfile;
>>> VMLINUX = "${passthru.kernel.dev}/vmlinux";
>>> + ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
>>> + ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
>>> };
>>> })) (_: {})
>>
>> Surely this would break interactive development of the rootfs?
>> If I'm in a Nix shell, and make a change to any part of the rootfs, the
>> verity data in the environment will be out of date. I'd have to leave
>> and re-enter the Nix shell after /any/ change, waiting for an evaluation
>> each time, as opposed to the current situation where that's only
>> necessary when modifying Nix code or other Spectrum components.
>
> It would. Are there alternatives you can recommend? I don't want the
> updater and the installer to have to use two different copies.
Have the host/rootfs derivation install the verity files alongside the
rootfs image. Then host/rootfs/Makefile is the single place we generate
the verity images, and it will still be regenerated by make when in a
Nix shell.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH 1/2] Create Nix derivation for building verity images
2025-11-06 11:44 ` Alyssa Ross
@ 2025-11-07 19:24 ` Demi Marie Obenour
2025-11-13 11:32 ` Alyssa Ross
0 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-07 19:24 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 6269 bytes --]
On 11/6/25 06:44, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> On 11/6/25 05:20, Alyssa Ross wrote:
>>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>>
>>>> This gets rid of a lot of duplicated code and allows building the verity
>>>> roothash and superblock only when needed. It also removes a hack used
>>>> to work around make limitations. Furthermore,
>>>> 'veritysetup --root-hash-file' is used to avoid an awk script.
>>>>
>>>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>>>> ---
>>>> nix-shell --pure --run 'make run' in host/initramfs fails. This is a
>>>> preexisting bug and I will send a separate patch for it.
>>>> ---
>>>> host/initramfs/Makefile | 25 +++++--------------------
>>>> host/initramfs/shell.nix | 4 +++-
>>>> host/rootfs/Makefile | 24 +++++-------------------
>>>> host/rootfs/shell.nix | 3 +++
>>>> host/verity.nix | 19 +++++++++++++++++++
>>>> lib/common.mk | 1 -
>>>> pkgs/default.nix | 1 +
>>>> release/live/Makefile | 26 +++++---------------------
>>>> release/live/default.nix | 4 +++-
>>>> 9 files changed, 44 insertions(+), 63 deletions(-)
>>>
>>>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>>>> index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
>>>> --- a/host/rootfs/Makefile
>>>> +++ b/host/rootfs/Makefile
>>>> @@ -82,25 +82,11 @@ clean:
>>>> rm -rf build
>>>> .PHONY: clean
>>>>
>>>> -# veritysetup format produces two files, but Make only (portably)
>>>> -# supports one output per rule, so we combine the two outputs then
>>>> -# define two more rules to separate them again.
>>>> -build/rootfs.verity: $(dest)
>>>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>>>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>>>> - > build/rootfs.verity.roothash.tmp
>>>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>>>> - > $@
>>>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>>>> -build/rootfs.verity.roothash: build/rootfs.verity
>>>> - head -n 1 build/rootfs.verity > $@
>>>> -build/rootfs.verity.superblock: build/rootfs.verity
>>>> - tail -n +2 build/rootfs.verity > $@
>>>>
>>>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>>>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
>>>> ../../scripts/make-gpt.sh $@.tmp \
>>>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>>>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>>>> + $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
>>>> mv $@.tmp $@
>>>>
>>>> debug:
>>>> @@ -110,7 +96,7 @@ debug:
>>>> $(VMLINUX)
>>>> .PHONY: debug
>>>>
>>>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>>> +run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
>>>> @set -x && \
>>>> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
>>>> truncate -s 10G "$$ext" && \
>>>> @@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>>> -device virtconsole,chardev=virtiocon0 \
>>>> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
>>>> -drive file=/proc/self/fd/3,if=virtio,format=raw \
>>>> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
>>>> + -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
>>>> -device virtio-keyboard \
>>>> -device virtio-mouse \
>>>> -device virtio-gpu \
>>>> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
>>>> index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
>>>> --- a/host/rootfs/shell.nix
>>>> +++ b/host/rootfs/shell.nix
>>>> @@ -5,6 +5,7 @@
>>>> import ../../lib/call-package.nix (
>>>> { callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
>>>> , btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
>>>> +, verity
>>>> }:
>>>>
>>>> rootfs.overrideAttrs (
>>>> @@ -20,5 +21,7 @@ rootfs.overrideAttrs (
>>>> KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>>>> LINUX_SRC = srcOnly passthru.kernel.configfile;
>>>> VMLINUX = "${passthru.kernel.dev}/vmlinux";
>>>> + ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
>>>> + ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
>>>> };
>>>> })) (_: {})
>>>
>>> Surely this would break interactive development of the rootfs?
>>> If I'm in a Nix shell, and make a change to any part of the rootfs, the
>>> verity data in the environment will be out of date. I'd have to leave
>>> and re-enter the Nix shell after /any/ change, waiting for an evaluation
>>> each time, as opposed to the current situation where that's only
>>> necessary when modifying Nix code or other Spectrum components.
>>
>> It would. Are there alternatives you can recommend? I don't want the
>> updater and the installer to have to use two different copies.
>
> Have the host/rootfs derivation install the verity files alongside the
> rootfs image. Then host/rootfs/Makefile is the single place we generate
> the verity images, and it will still be regenerated by make when in a
> Nix shell.
Is it okay to instead remove dm-verity protection for the verity images?
Given that we discussed using virtiofs for live development, I don't think
the verity protection is necessary. It also slows down live development.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-05 22:33 [PATCH 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-05 22:33 ` [PATCH 1/2] Create Nix derivation for building verity images Demi Marie Obenour
2025-11-05 22:33 ` [PATCH 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-08 4:47 ` Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
` (2 more replies)
2 siblings, 3 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-08 4:47 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 44 +++++++++++++++++++++-----------------------
host/rootfs/default.nix | 2 +-
host/rootfs/shell.nix | 2 +-
pkgs/default.nix | 1 +
release/live/Makefile | 37 +++++--------------------------------
release/live/default.nix | 23 ++++++++---------------
9 files changed, 91 insertions(+), 94 deletions(-)
---
base-commit: 464d69599922a2b233804559c93ccea10fa3dc44
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v2 1/2] Build verity images in rootfs Nix derivation
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-08 4:47 ` Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-08 4:47 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 44 +++++++++++++++++++++-----------------------
host/rootfs/default.nix | 2 +-
host/rootfs/shell.nix | 2 +-
release/live/Makefile | 26 +++++---------------------
release/live/default.nix | 4 +++-
7 files changed, 39 insertions(+), 69 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..102870ecba4456303414e2531ea592473ddfc1cf 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
+ $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index 8b47aa53bc19a818ebf563e281f22e82202a8ea5..fef8198685564bef2d8d673e0dc9403ee9c9a444 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -17,6 +17,8 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS = "${rootfs}/rootfs";
+ ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 00d125774bb7b98736d0928c69cb307740cee034..d7764d9b796f1773b4bebd0d50eec52b9be29e42 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -6,7 +6,7 @@
include ../../lib/common.mk
include file-list.mk
-dest = build/rootfs.erofs
+dest = build
DIRS = \
dev \
@@ -46,14 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+$(dest)/timestamp: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk $(dest)
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(DIRS) ;\
printf 'build/fifo\n%s\n' $(FIFOS) ;\
- } | ../../scripts/make-erofs.sh $@
+ } | ../../scripts/make-erofs.sh $(dest)/rootfs
+ $(VERITYSETUP) format \
+ --root-hash-file $(dest)/rootfs.verity.roothash \
+ -- $(dest)/rootfs $(dest)/rootfs.verity.superblock
+ # Add trailing newline
+ echo >> $(dest)/rootfs.verity.roothash
+ touch -- $(dest)/timestamp
+
+$(dest):
+ mkdir -p $(dest)
build/fifo:
mkdir -p build
@@ -82,25 +95,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(dest)/timestamp
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(dest)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(dest)/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
+ $(dest)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(dest)/rootfs.verity.roothash)")
mv $@.tmp $@
debug:
@@ -110,7 +108,7 @@ debug:
$(VMLINUX)
.PHONY: debug
-run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
+run: build/live.img
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
truncate -s 10G "$$ext" && \
@@ -131,7 +129,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(dest)/rootfs.verity.roothash) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index 0d79f7ca54ccc86eb0fa6e743f2011237d365f24..453629d03d4b2b7e6bc49de5419321fc6b27f431 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -145,7 +145,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..191b44944af0adf965e1d5f2785719b236bfd99c 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY":verity:$$(../../scripts/format-uuid.sh "$$(dd if="$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..9a62d4da9cfea11d94d2a1d5764d41587efd5ad5 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -46,7 +46,9 @@ stdenv.mkDerivation {
env = {
INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS = "${rootfs}/rootfs";
+ ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
EFINAME = "BOOT${toUpper efiArch}.EFI";
} // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v2 2/2] Move UKI creation to a separate derivation
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-08 4:47 ` Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-08 4:47 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
pkgs/default.nix | 1 +
release/live/Makefile | 15 ++-------------
release/live/default.nix | 19 +++++--------------
4 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..a2b47fd050fbf00050473a0d5a1373eb96c341b5
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ bash, callSpectrumPackage, cryptsetup, runCommand
+, stdenv, systemdUkify, rootfs
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd bash ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit systemd; };
+ env = {
+ DTBS = "${rootfs.kernel}/dtbs";
+ KERNEL = kernel;
+ INITRAMFS = initramfs;
+ ROOTFS = rootfs;
+ };
+} ''
+ read -r roothash < "$ROOTFS/rootfs.verity.roothash"
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d "$DTBS" ]; then
+ find "$DTBS" -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux "$KERNEL" \
+ --initrd "$INITRAMFS" \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/pkgs/default.nix b/pkgs/default.nix
index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..c9f6dcfad9369567468b30d1c5697e3551a7b236 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -36,6 +36,7 @@ let
path: (import path { inherit (self) callPackage; }).override;
rootfs = self.callSpectrumPackage ../host/rootfs {};
+ efi = self.callSpectrumPackage ../host/efi.nix {};
spectrum-build-tools = self.callSpectrumPackage ../tools {
appSupport = false;
buildSupport = true;
diff --git a/release/live/Makefile b/release/live/Makefile
index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
+ ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
diff --git a/release/live/default.nix b/release/live/default.nix
index 9a62d4da9cfea11d94d2a1d5764d41587efd5ad5..c234d87e62cc9ae65ba60f94bab6e58b43beddbc 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
{ callSpectrumPackage, spectrum-build-tools, rootfs, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
+, systemdUkify, efi
}:
let
@@ -14,13 +14,6 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
in
@@ -40,19 +33,17 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = "${rootfs}/rootfs";
ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
- SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -65,6 +56,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit rootfs; };
}
) (_: {})
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-12 0:59 ` Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
` (2 more replies)
2 siblings, 3 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-12 0:59 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v3:
- Rebase on main
- Link to v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251107-refactor-verity-v2-0-2af58b1a4a87@gmail.com
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 45 +++++++++++++++++++++------------------------
host/rootfs/default.nix | 2 +-
host/rootfs/shell.nix | 2 +-
pkgs/default.nix | 1 +
release/live/Makefile | 37 +++++--------------------------------
release/live/default.nix | 23 ++++++++---------------
9 files changed, 91 insertions(+), 95 deletions(-)
---
base-commit: 50f8db9cec022a60ea978bfdde0904a18718d161
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v3 1/2] Build verity images in rootfs Nix derivation
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-12 0:59 ` Demi Marie Obenour
2025-11-13 11:46 ` Alyssa Ross
2025-11-12 0:59 ` [PATCH v3 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-12 0:59 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/shell.nix | 4 +++-
host/rootfs/Makefile | 45 +++++++++++++++++++++------------------------
host/rootfs/default.nix | 2 +-
host/rootfs/shell.nix | 2 +-
release/live/Makefile | 26 +++++---------------------
release/live/default.nix | 4 +++-
7 files changed, 39 insertions(+), 70 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..102870ecba4456303414e2531ea592473ddfc1cf 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
+ $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index 8b47aa53bc19a818ebf563e281f22e82202a8ea5..fef8198685564bef2d8d673e0dc9403ee9c9a444 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -17,6 +17,8 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS = "${rootfs}/rootfs";
+ ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index f107ca44fcf1ad85af5788d87f6c772910d40072..d7764d9b796f1773b4bebd0d50eec52b9be29e42 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -6,7 +6,7 @@
include ../../lib/common.mk
include file-list.mk
-dest = build/rootfs.erofs
+dest = build
DIRS = \
dev \
@@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
- set -euo pipefail; \
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+$(dest)/timestamp: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk $(dest)
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(DIRS) ;\
printf 'build/fifo\n%s\n' $(FIFOS) ;\
- } | ../../scripts/make-erofs.sh $@
+ } | ../../scripts/make-erofs.sh $(dest)/rootfs
+ $(VERITYSETUP) format \
+ --root-hash-file $(dest)/rootfs.verity.roothash \
+ -- $(dest)/rootfs $(dest)/rootfs.verity.superblock
+ # Add trailing newline
+ echo >> $(dest)/rootfs.verity.roothash
+ touch -- $(dest)/timestamp
+
+$(dest):
+ mkdir -p $(dest)
build/fifo:
mkdir -p build
@@ -83,25 +95,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(dest)/timestamp
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(dest)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(dest)/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
+ $(dest)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(dest)/rootfs.verity.roothash)")
mv $@.tmp $@
debug:
@@ -111,7 +108,7 @@ debug:
$(VMLINUX)
.PHONY: debug
-run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
+run: build/live.img
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
truncate -s 10G "$$ext" && \
@@ -132,7 +129,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(dest)/rootfs.verity.roothash) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..eb6c64067091ef3802596ce581f82f322f5bfe34 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..191b44944af0adf965e1d5f2785719b236bfd99c 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ "$$ROOT_FS_VERITY":verity:$$(../../scripts/format-uuid.sh "$$(dd if="$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..9a62d4da9cfea11d94d2a1d5764d41587efd5ad5 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -46,7 +46,9 @@ stdenv.mkDerivation {
env = {
INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS = "${rootfs}/rootfs";
+ ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
+ ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
EFINAME = "BOOT${toUpper efiArch}.EFI";
} // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v3 2/2] Move UKI creation to a separate derivation
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-12 0:59 ` Demi Marie Obenour
2025-11-13 11:57 ` Alyssa Ross
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-12 0:59 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
pkgs/default.nix | 1 +
release/live/Makefile | 15 ++-------------
release/live/default.nix | 19 +++++--------------
4 files changed, 54 insertions(+), 27 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..a2b47fd050fbf00050473a0d5a1373eb96c341b5
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: EUPL-1.2+
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ bash, callSpectrumPackage, cryptsetup, runCommand
+, stdenv, systemdUkify, rootfs
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd bash ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit systemd; };
+ env = {
+ DTBS = "${rootfs.kernel}/dtbs";
+ KERNEL = kernel;
+ INITRAMFS = initramfs;
+ ROOTFS = rootfs;
+ };
+} ''
+ read -r roothash < "$ROOTFS/rootfs.verity.roothash"
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d "$DTBS" ]; then
+ find "$DTBS" -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux "$KERNEL" \
+ --initrd "$INITRAMFS" \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/pkgs/default.nix b/pkgs/default.nix
index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..c9f6dcfad9369567468b30d1c5697e3551a7b236 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -36,6 +36,7 @@ let
path: (import path { inherit (self) callPackage; }).override;
rootfs = self.callSpectrumPackage ../host/rootfs {};
+ efi = self.callSpectrumPackage ../host/efi.nix {};
spectrum-build-tools = self.callSpectrumPackage ../tools {
appSupport = false;
buildSupport = true;
diff --git a/release/live/Makefile b/release/live/Makefile
index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
+ ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
diff --git a/release/live/default.nix b/release/live/default.nix
index 9a62d4da9cfea11d94d2a1d5764d41587efd5ad5..c234d87e62cc9ae65ba60f94bab6e58b43beddbc 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
{ callSpectrumPackage, spectrum-build-tools, rootfs, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
+, systemdUkify, efi
}:
let
@@ -14,13 +14,6 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
in
@@ -40,19 +33,17 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
ROOT_FS = "${rootfs}/rootfs";
ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
- SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -65,6 +56,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit rootfs; };
}
) (_: {})
--
2.51.2
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH 1/2] Create Nix derivation for building verity images
2025-11-07 19:24 ` Demi Marie Obenour
@ 2025-11-13 11:32 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-13 11:32 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 6589 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> On 11/6/25 06:44, Alyssa Ross wrote:
>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>
>>> On 11/6/25 05:20, Alyssa Ross wrote:
>>>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>>>
>>>>> This gets rid of a lot of duplicated code and allows building the verity
>>>>> roothash and superblock only when needed. It also removes a hack used
>>>>> to work around make limitations. Furthermore,
>>>>> 'veritysetup --root-hash-file' is used to avoid an awk script.
>>>>>
>>>>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>>>>> ---
>>>>> nix-shell --pure --run 'make run' in host/initramfs fails. This is a
>>>>> preexisting bug and I will send a separate patch for it.
>>>>> ---
>>>>> host/initramfs/Makefile | 25 +++++--------------------
>>>>> host/initramfs/shell.nix | 4 +++-
>>>>> host/rootfs/Makefile | 24 +++++-------------------
>>>>> host/rootfs/shell.nix | 3 +++
>>>>> host/verity.nix | 19 +++++++++++++++++++
>>>>> lib/common.mk | 1 -
>>>>> pkgs/default.nix | 1 +
>>>>> release/live/Makefile | 26 +++++---------------------
>>>>> release/live/default.nix | 4 +++-
>>>>> 9 files changed, 44 insertions(+), 63 deletions(-)
>>>>
>>>>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>>>>> index 00d125774bb7b98736d0928c69cb307740cee034..bb602e2745fb5873204f453b35fc529c5c96f64a 100644
>>>>> --- a/host/rootfs/Makefile
>>>>> +++ b/host/rootfs/Makefile
>>>>> @@ -82,25 +82,11 @@ clean:
>>>>> rm -rf build
>>>>> .PHONY: clean
>>>>>
>>>>> -# veritysetup format produces two files, but Make only (portably)
>>>>> -# supports one output per rule, so we combine the two outputs then
>>>>> -# define two more rules to separate them again.
>>>>> -build/rootfs.verity: $(dest)
>>>>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>>>>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>>>>> - > build/rootfs.verity.roothash.tmp
>>>>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>>>>> - > $@
>>>>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>>>>> -build/rootfs.verity.roothash: build/rootfs.verity
>>>>> - head -n 1 build/rootfs.verity > $@
>>>>> -build/rootfs.verity.superblock: build/rootfs.verity
>>>>> - tail -n +2 build/rootfs.verity > $@
>>>>>
>>>>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>>>>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(dest)
>>>>> ../../scripts/make-gpt.sh $@.tmp \
>>>>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>>>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>>>>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>>>>> + $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 "$$ROOT_FS_VERITY_ROOTHASH")")
>>>>> mv $@.tmp $@
>>>>>
>>>>> debug:
>>>>> @@ -110,7 +96,7 @@ debug:
>>>>> $(VMLINUX)
>>>>> .PHONY: debug
>>>>>
>>>>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>>>> +run: build/live.img $(EXT_FS) $(ROOT_FS_VERITY_ROOTHASH)
>>>>> @set -x && \
>>>>> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
>>>>> truncate -s 10G "$$ext" && \
>>>>> @@ -131,7 +117,7 @@ run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>>>> -device virtconsole,chardev=virtiocon0 \
>>>>> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
>>>>> -drive file=/proc/self/fd/3,if=virtio,format=raw \
>>>>> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
>>>>> + -append "earlycon console=hvc0 roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") intel_iommu=on nokaslr" \
>>>>> -device virtio-keyboard \
>>>>> -device virtio-mouse \
>>>>> -device virtio-gpu \
>>>>> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
>>>>> index 1bf61bebf418333624e799cc8ca231f5783206f4..f16e4905adfbc8faebde19d0a1364ad9df90219b 100644
>>>>> --- a/host/rootfs/shell.nix
>>>>> +++ b/host/rootfs/shell.nix
>>>>> @@ -5,6 +5,7 @@
>>>>> import ../../lib/call-package.nix (
>>>>> { callSpectrumPackage, rootfs, pkgsStatic, srcOnly, stdenv
>>>>> , btrfs-progs, cryptsetup, jq, netcat, qemu_kvm, reuse, util-linux
>>>>> +, verity
>>>>> }:
>>>>>
>>>>> rootfs.overrideAttrs (
>>>>> @@ -20,5 +21,7 @@ rootfs.overrideAttrs (
>>>>> KERNEL = "${passthru.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>>>>> LINUX_SRC = srcOnly passthru.kernel.configfile;
>>>>> VMLINUX = "${passthru.kernel.dev}/vmlinux";
>>>>> + ROOT_FS_VERITY = "${verity}/rootfs.verity.superblock";
>>>>> + ROOT_FS_VERITY_ROOTHASH = "${verity}/rootfs.verity.roothash";
>>>>> };
>>>>> })) (_: {})
>>>>
>>>> Surely this would break interactive development of the rootfs?
>>>> If I'm in a Nix shell, and make a change to any part of the rootfs, the
>>>> verity data in the environment will be out of date. I'd have to leave
>>>> and re-enter the Nix shell after /any/ change, waiting for an evaluation
>>>> each time, as opposed to the current situation where that's only
>>>> necessary when modifying Nix code or other Spectrum components.
>>>
>>> It would. Are there alternatives you can recommend? I don't want the
>>> updater and the installer to have to use two different copies.
>>
>> Have the host/rootfs derivation install the verity files alongside the
>> rootfs image. Then host/rootfs/Makefile is the single place we generate
>> the verity images, and it will still be regenerated by make when in a
>> Nix shell.
>
> Is it okay to instead remove dm-verity protection for the verity images?
> Given that we discussed using virtiofs for live development, I don't think
> the verity protection is necessary. It also slows down live development.
If you can do it in a way that doesn't require modifying the rootfs
image. I don't want it to have to do anything special to support
development builds that don't work like the real thing.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 1/2] Build verity images in rootfs Nix derivation
2025-11-12 0:59 ` [PATCH v3 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-13 11:46 ` Alyssa Ross
2025-11-13 22:33 ` Demi Marie Obenour
0 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-13 11:46 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 7369 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> Avoid redundant rebuilds of the rootfs verity superblock and roothash.
> Remove duplicate code. Clean up Makefile to avoid temporary files.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> host/initramfs/Makefile | 26 +++++---------------------
> host/initramfs/shell.nix | 4 +++-
> host/rootfs/Makefile | 45 +++++++++++++++++++++------------------------
> host/rootfs/default.nix | 2 +-
> host/rootfs/shell.nix | 2 +-
> release/live/Makefile | 26 +++++---------------------
> release/live/default.nix | 4 +++-
> 7 files changed, 39 insertions(+), 70 deletions(-)
Looking good!
> diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
> index cb13fbb35f065b67d291d4a35591d6f12720060c..102870ecba4456303414e2531ea592473ddfc1cf 100644
> --- a/host/initramfs/Makefile
> +++ b/host/initramfs/Makefile
> @@ -35,26 +35,10 @@ build/mountpoints:
> cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
> find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
>
> -# veritysetup format produces two files, but Make only (portably)
> -# supports one output per rule, so we combine the two outputs then
> -# define two more rules to separate them again.
> -build/rootfs.verity: $(ROOT_FS)
> - mkdir -p build
> - $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
> - > build/rootfs.verity.roothash.tmp
> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
> - > $@
> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
> -build/rootfs.verity.roothash: build/rootfs.verity
> - head -n 1 build/rootfs.verity > $@
> -build/rootfs.verity.superblock: build/rootfs.verity
> - tail -n +2 build/rootfs.verity > $@
> -
> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
> ../../scripts/make-gpt.sh $@.tmp \
> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> - $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
Indentation got messed up here.
Given rootfs has a well-defined output structure, maybe we could just
write $(ROOT_FS)/rootfs.verity.roothash, so we don't need to define lots
of different environment variables in each component that uses the
verity data.
I think we should consistently use Make variable expansion rather than
shell variable expansion when we're using the variable in a Make
dependency line too, to avoid the possibility of them being different.
> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
> index f107ca44fcf1ad85af5788d87f6c772910d40072..d7764d9b796f1773b4bebd0d50eec52b9be29e42 100644
> --- a/host/rootfs/Makefile
> +++ b/host/rootfs/Makefile
> @@ -6,7 +6,7 @@
> include ../../lib/common.mk
> include file-list.mk
>
> -dest = build/rootfs.erofs
> +dest = build
>
> DIRS = \
> dev \
> @@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>
> BUILD_FILES = build/etc/s6-rc
>
> -$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> - set -euo pipefail; \
> +# This rule produces three files but Make only (portably)
> +# supports one output per rule. Instead of resorting to temporary
> +# files, a timestamp file is created as the last step. The actual
> +# outputs are produced as side-effects.
> +$(dest)/timestamp: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk $(dest)
Semes a bit odd to install the timestamp in $(dest).
> { \
> cat $(PACKAGES_FILE) ;\
> for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
> for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
> printf 'build/empty\n%s\n' $(DIRS) ;\
> printf 'build/fifo\n%s\n' $(FIFOS) ;\
> - } | ../../scripts/make-erofs.sh $@
> + } | ../../scripts/make-erofs.sh $(dest)/rootfs
> + $(VERITYSETUP) format \
> + --root-hash-file $(dest)/rootfs.verity.roothash \
> + -- $(dest)/rootfs $(dest)/rootfs.verity.superblock
> + # Add trailing newline
> + echo >> $(dest)/rootfs.verity.roothash
> + touch -- $(dest)/timestamp
I prefer smaller independent Make rules where possible. Can't the
verity data stay in a separate rule from make-erofs.sh?
Either way, change deserves a copyright header IMO. :)
> +
> +$(dest):
> + mkdir -p $(dest)
Would rather this was inlined into every target in $(dest), because
directories can be a bit confusing to me as Make targets. "Does the
target just create the directory, or does it create the directory and
everything in it?" sort of thing.
>
> build/fifo:
> mkdir -p build
> @@ -83,25 +95,10 @@ clean:
> rm -rf build
> .PHONY: clean
>
> -# veritysetup format produces two files, but Make only (portably)
> -# supports one output per rule, so we combine the two outputs then
> -# define two more rules to separate them again.
> -build/rootfs.verity: $(dest)
> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
> - > build/rootfs.verity.roothash.tmp
> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
> - > $@
> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
> -build/rootfs.verity.roothash: build/rootfs.verity
> - head -n 1 build/rootfs.verity > $@
> -build/rootfs.verity.superblock: build/rootfs.verity
> - tail -n +2 build/rootfs.verity > $@
> -
> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(dest)/timestamp
> ../../scripts/make-gpt.sh $@.tmp \
> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
> + $(dest)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(dest)/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> + $(dest)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(dest)/rootfs.verity.roothash)")
> mv $@.tmp $@
>
> debug:
> @@ -111,7 +108,7 @@ debug:
> $(VMLINUX)
> .PHONY: debug
>
> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
> +run: build/live.img
What happened to $(EXT_FS)?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 2/2] Move UKI creation to a separate derivation
2025-11-12 0:59 ` [PATCH v3 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-13 11:57 ` Alyssa Ross
2025-11-13 22:42 ` Demi Marie Obenour
0 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-13 11:57 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 6511 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> It will be used by the update code later.
>
> No functional change intended, other than a trivial shell script
> refactoring.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> pkgs/default.nix | 1 +
> release/live/Makefile | 15 ++-------------
> release/live/default.nix | 19 +++++--------------
> 4 files changed, 54 insertions(+), 27 deletions(-)
>
> diff --git a/host/efi.nix b/host/efi.nix
> new file mode 100644
> index 0000000000000000000000000000000000000000..a2b47fd050fbf00050473a0d5a1373eb96c341b5
> --- /dev/null
> +++ b/host/efi.nix
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: EUPL-1.2+
MIT for Nix files please. (Fine to take my stuff from the EUPL-1.2+
Makefile and use it in a MIT-licensed Nix file.)
> +# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
> +
> +import ../lib/call-package.nix (
> +{ bash, callSpectrumPackage, cryptsetup, runCommand
> +, stdenv, systemdUkify, rootfs
> +}:
> +let
> + initramfs = callSpectrumPackage ./initramfs {};
> + kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> + systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
> + # The default limit is too low to build a generic aarch64 distro image:
> + # https://github.com/systemd/systemd/pull/37417
> + mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
> + });
> +in
> +
> +runCommand "spectrum-efi" {
> + nativeBuildInputs = [ cryptsetup systemd bash ];
bash?
> + __structuredAttrs = true;
> + unsafeDiscardReferences = { out = true; };
> + dontFixup = true;
> + passthru = { inherit systemd; };
> + env = {
> + DTBS = "${rootfs.kernel}/dtbs";
> + KERNEL = kernel;
> + INITRAMFS = initramfs;
> + ROOTFS = rootfs;
> + };
Usually we'd just inline these via string interpolation, rather than
passing them through as environment variables.
> diff --git a/pkgs/default.nix b/pkgs/default.nix
> index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..c9f6dcfad9369567468b30d1c5697e3551a7b236 100644
> --- a/pkgs/default.nix
> +++ b/pkgs/default.nix
> @@ -36,6 +36,7 @@ let
> path: (import path { inherit (self) callPackage; }).override;
>
> rootfs = self.callSpectrumPackage ../host/rootfs {};
> + efi = self.callSpectrumPackage ../host/efi.nix {};
> spectrum-build-tools = self.callSpectrumPackage ../tools {
> appSupport = false;
> buildSupport = true;
Generally images don't need entries here, and can just be loaded by
callSpectrumPackage. There was a specific reason to make an exception
for rootfs (which I've now forgotten).
> diff --git a/release/live/Makefile b/release/live/Makefile
> index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
> --- a/release/live/Makefile
> +++ b/release/live/Makefile
> @@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
> build/empty:
> mkdir -p $@
>
> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
> - { \
> - printf "[UKI]\nDeviceTreeAuto=" && \
> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
> - } | $(UKIFY) build \
> - --output $@ \
> - --config /dev/stdin \
> - --linux $(KERNEL) \
> - --initrd $(INITRAMFS) \
> - --os-release $$'NAME="Spectrum"\n' \
> - --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
> -
> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
> + ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
> $(TRUNCATE) -s 440401920 $@
> $(MKFS_FAT) $@
> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
Why a symlink? Why not just replace the path we copy from?
> diff --git a/release/live/default.nix b/release/live/default.nix
> index 9a62d4da9cfea11d94d2a1d5764d41587efd5ad5..c234d87e62cc9ae65ba60f94bab6e58b43beddbc 100644
> --- a/release/live/default.nix
> +++ b/release/live/default.nix
> @@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
> { callSpectrumPackage, spectrum-build-tools, rootfs, src
> , lib, pkgsStatic, stdenvNoCC
> , cryptsetup, dosfstools, jq, mtools, util-linux
> -, systemdUkify
> +, systemdUkify, efi
> }:
>
> let
> @@ -14,13 +14,6 @@ let
>
> stdenv = stdenvNoCC;
>
> - systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
> - # The default limit is too low to build a generic aarch64 distro image:
> - # https://github.com/systemd/systemd/pull/37417
> - mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
> - });
> -
> - initramfs = callSpectrumPackage ../../host/initramfs {};
> efiArch = stdenv.hostPlatform.efiArch;
> in
>
> @@ -40,19 +33,17 @@ stdenv.mkDerivation {
> sourceRoot = "source/release/live";
>
> nativeBuildInputs = [
> - cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
> + cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
> ];
>
> env = {
> - INITRAMFS = initramfs;
> KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> ROOT_FS = "${rootfs}/rootfs";
> ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
> ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
Since efi is tied to a specific rootfs, maybe it would be nice to use
efi.rootfs here?
> - SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
> + SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
We can just get this from the default systemd package. Doesn't need to
be efi's special overridden one.
> + EFI_IMAGE = efi;
> EFINAME = "BOOT${toUpper efiArch}.EFI";
> - } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
> - DTBS = "${rootfs.kernel}/dtbs";
> };
>
> buildFlags = [ "dest=$(out)" ];
> @@ -65,6 +56,6 @@ stdenv.mkDerivation {
> unsafeDiscardReferences = { out = true; };
> dontFixup = true;
>
> - passthru = { inherit initramfs rootfs; };
> + passthru = { inherit rootfs; };
> }
> ) (_: {})
>
> --
> 2.51.2
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 1/2] Build verity images in rootfs Nix derivation
2025-11-13 11:46 ` Alyssa Ross
@ 2025-11-13 22:33 ` Demi Marie Obenour
2025-11-14 11:53 ` Alyssa Ross
0 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-13 22:33 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 7944 bytes --]
On 11/13/25 06:46, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> Avoid redundant rebuilds of the rootfs verity superblock and roothash.
>> Remove duplicate code. Clean up Makefile to avoid temporary files.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> host/initramfs/Makefile | 26 +++++---------------------
>> host/initramfs/shell.nix | 4 +++-
>> host/rootfs/Makefile | 45 +++++++++++++++++++++------------------------
>> host/rootfs/default.nix | 2 +-
>> host/rootfs/shell.nix | 2 +-
>> release/live/Makefile | 26 +++++---------------------
>> release/live/default.nix | 4 +++-
>> 7 files changed, 39 insertions(+), 70 deletions(-)
>
> Looking good!
Thank you!
>> diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
>> index cb13fbb35f065b67d291d4a35591d6f12720060c..102870ecba4456303414e2531ea592473ddfc1cf 100644
>> --- a/host/initramfs/Makefile
>> +++ b/host/initramfs/Makefile
>> @@ -35,26 +35,10 @@ build/mountpoints:
>> cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
>> find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
>>
>> -# veritysetup format produces two files, but Make only (portably)
>> -# supports one output per rule, so we combine the two outputs then
>> -# define two more rules to separate them again.
>> -build/rootfs.verity: $(ROOT_FS)
>> - mkdir -p build
>> - $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>> - > build/rootfs.verity.roothash.tmp
>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>> - > $@
>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>> -build/rootfs.verity.roothash: build/rootfs.verity
>> - head -n 1 build/rootfs.verity > $@
>> -build/rootfs.verity.superblock: build/rootfs.verity
>> - tail -n +2 build/rootfs.verity > $@
>> -
>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
>> ../../scripts/make-gpt.sh $@.tmp \
>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>> - $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>
> Indentation got messed up here.
>
> Given rootfs has a well-defined output structure, maybe we could just
> write $(ROOT_FS)/rootfs.verity.roothash, so we don't need to define lots
> of different environment variables in each component that uses the
> verity data.
>
> I think we should consistently use Make variable expansion rather than
> shell variable expansion when we're using the variable in a Make
> dependency line too, to avoid the possibility of them being different.
Make expansion followed by shell expansion and just Make expansion aren't
even consistent with each other.
>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>> index f107ca44fcf1ad85af5788d87f6c772910d40072..d7764d9b796f1773b4bebd0d50eec52b9be29e42 100644
>> --- a/host/rootfs/Makefile
>> +++ b/host/rootfs/Makefile
>> @@ -6,7 +6,7 @@
>> include ../../lib/common.mk
>> include file-list.mk
>>
>> -dest = build/rootfs.erofs
>> +dest = build
>>
>> DIRS = \
>> dev \
>> @@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>>
>> BUILD_FILES = build/etc/s6-rc
>>
>> -$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
>> - set -euo pipefail; \
>> +# This rule produces three files but Make only (portably)
>> +# supports one output per rule. Instead of resorting to temporary
>> +# files, a timestamp file is created as the last step. The actual
>> +# outputs are produced as side-effects.
>> +$(dest)/timestamp: ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk $(dest)
>
> Semes a bit odd to install the timestamp in $(dest).
>
>> { \
>> cat $(PACKAGES_FILE) ;\
>> for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
>> for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
>> printf 'build/empty\n%s\n' $(DIRS) ;\
>> printf 'build/fifo\n%s\n' $(FIFOS) ;\
>> - } | ../../scripts/make-erofs.sh $@
>> + } | ../../scripts/make-erofs.sh $(dest)/rootfs
>> + $(VERITYSETUP) format \
>> + --root-hash-file $(dest)/rootfs.verity.roothash \
>> + -- $(dest)/rootfs $(dest)/rootfs.verity.superblock
>> + # Add trailing newline
>> + echo >> $(dest)/rootfs.verity.roothash
>> + touch -- $(dest)/timestamp
>
> I prefer smaller independent Make rules where possible. Can't the
> verity data stay in a separate rule from make-erofs.sh?
>
> Either way, change deserves a copyright header IMO. :)
>
>> +
>> +$(dest):
>> + mkdir -p $(dest)
>
> Would rather this was inlined into every target in $(dest), because
> directories can be a bit confusing to me as Make targets. "Does the
> target just create the directory, or does it create the directory and
> everything in it?" sort of thing.
Will fix.
>> build/fifo:
>> mkdir -p build
>> @@ -83,25 +95,10 @@ clean:
>> rm -rf build
>> .PHONY: clean
>>
>> -# veritysetup format produces two files, but Make only (portably)
>> -# supports one output per rule, so we combine the two outputs then
>> -# define two more rules to separate them again.
>> -build/rootfs.verity: $(dest)
>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>> - > build/rootfs.verity.roothash.tmp
>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>> - > $@
>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>> -build/rootfs.verity.roothash: build/rootfs.verity
>> - head -n 1 build/rootfs.verity > $@
>> -build/rootfs.verity.superblock: build/rootfs.verity
>> - tail -n +2 build/rootfs.verity > $@
>> -
>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(dest)/timestamp
>> ../../scripts/make-gpt.sh $@.tmp \
>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>> + $(dest)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(dest)/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>> + $(dest)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(dest)/rootfs.verity.roothash)")
>> mv $@.tmp $@
>>
>> debug:
>> @@ -111,7 +108,7 @@ debug:
>> $(VMLINUX)
>> .PHONY: debug
>>
>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>> +run: build/live.img
>
> What happened to $(EXT_FS)?
Since commit 12b64009d9cde56b5629a832086d2c2311908ebe
("host/initramfs/extfs.nix: remove") it has been unused.
I deleted it while changing other stuff in this line.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 2/2] Move UKI creation to a separate derivation
2025-11-13 11:57 ` Alyssa Ross
@ 2025-11-13 22:42 ` Demi Marie Obenour
2025-11-14 11:58 ` Alyssa Ross
0 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-13 22:42 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 7416 bytes --]
On 11/13/25 06:57, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> It will be used by the update code later.
>>
>> No functional change intended, other than a trivial shell script
>> refactoring.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>> pkgs/default.nix | 1 +
>> release/live/Makefile | 15 ++-------------
>> release/live/default.nix | 19 +++++--------------
>> 4 files changed, 54 insertions(+), 27 deletions(-)
>>
>> diff --git a/host/efi.nix b/host/efi.nix
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..a2b47fd050fbf00050473a0d5a1373eb96c341b5
>> --- /dev/null
>> +++ b/host/efi.nix
>> @@ -0,0 +1,46 @@
>> +# SPDX-License-Identifier: EUPL-1.2+
>
> MIT for Nix files please. (Fine to take my stuff from the EUPL-1.2+
> Makefile and use it in a MIT-licensed Nix file.)
I think it would be best to relicense the Makefiles under MIT if we can,
so that we can move code back and forth even after neither of us knows every
single copyright holder. Feel free to relicense my contributions to them.
>> +# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
>> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
>> +
>> +import ../lib/call-package.nix (
>> +{ bash, callSpectrumPackage, cryptsetup, runCommand
>> +, stdenv, systemdUkify, rootfs
>> +}:
>> +let
>> + initramfs = callSpectrumPackage ./initramfs {};
>> + kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>> + systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
>> + # The default limit is too low to build a generic aarch64 distro image:
>> + # https://github.com/systemd/systemd/pull/37417
>> + mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
>> + });
>> +in
>> +
>> +runCommand "spectrum-efi" {
>> + nativeBuildInputs = [ cryptsetup systemd bash ];
>
> bash?
Will remove.
>> + __structuredAttrs = true;
>> + unsafeDiscardReferences = { out = true; };
>> + dontFixup = true;
>> + passthru = { inherit systemd; };
>> + env = {
>> + DTBS = "${rootfs.kernel}/dtbs";
>> + KERNEL = kernel;
>> + INITRAMFS = initramfs;
>> + ROOTFS = rootfs;
>> + };
>
> Usually we'd just inline these via string interpolation, rather than
> passing them through as environment variables.
Done, except for DTBS which is used more than once.
>> diff --git a/pkgs/default.nix b/pkgs/default.nix
>> index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..c9f6dcfad9369567468b30d1c5697e3551a7b236 100644
>> --- a/pkgs/default.nix
>> +++ b/pkgs/default.nix
>> @@ -36,6 +36,7 @@ let
>> path: (import path { inherit (self) callPackage; }).override;
>>
>> rootfs = self.callSpectrumPackage ../host/rootfs {};
>> + efi = self.callSpectrumPackage ../host/efi.nix {};
>> spectrum-build-tools = self.callSpectrumPackage ../tools {
>> appSupport = false;
>> buildSupport = true;
>
> Generally images don't need entries here, and can just be loaded by
> callSpectrumPackage. There was a specific reason to make an exception
> for rootfs (which I've now forgotten).
What is the general rule for what should go in pkgs/default.nix?
If you could add it to the docs that would be great.
>> diff --git a/release/live/Makefile b/release/live/Makefile
>> index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
>> --- a/release/live/Makefile
>> +++ b/release/live/Makefile
>> @@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
>> build/empty:
>> mkdir -p $@
>>
>> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
>> - { \
>> - printf "[UKI]\nDeviceTreeAuto=" && \
>> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
>> - } | $(UKIFY) build \
>> - --output $@ \
>> - --config /dev/stdin \
>> - --linux $(KERNEL) \
>> - --initrd $(INITRAMFS) \
>> - --os-release $$'NAME="Spectrum"\n' \
>> - --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
>> -
>> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
>> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
>> + ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
>> $(TRUNCATE) -s 440401920 $@
>> $(MKFS_FAT) $@
>> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
>
> Why a symlink? Why not just replace the path we copy from?
The basename of the path is actually important. I tried using
$(EFI_IMAGE) and the system didn't boot.
>> diff --git a/release/live/default.nix b/release/live/default.nix
>> index 9a62d4da9cfea11d94d2a1d5764d41587efd5ad5..c234d87e62cc9ae65ba60f94bab6e58b43beddbc 100644
>> --- a/release/live/default.nix
>> +++ b/release/live/default.nix
>> @@ -6,7 +6,7 @@ import ../../lib/call-package.nix (
>> { callSpectrumPackage, spectrum-build-tools, rootfs, src
>> , lib, pkgsStatic, stdenvNoCC
>> , cryptsetup, dosfstools, jq, mtools, util-linux
>> -, systemdUkify
>> +, systemdUkify, efi
>> }:
>>
>> let
>> @@ -14,13 +14,6 @@ let
>>
>> stdenv = stdenvNoCC;
>>
>> - systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
>> - # The default limit is too low to build a generic aarch64 distro image:
>> - # https://github.com/systemd/systemd/pull/37417
>> - mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
>> - });
>> -
>> - initramfs = callSpectrumPackage ../../host/initramfs {};
>> efiArch = stdenv.hostPlatform.efiArch;
>> in
>>
>> @@ -40,19 +33,17 @@ stdenv.mkDerivation {
>> sourceRoot = "source/release/live";
>>
>> nativeBuildInputs = [
>> - cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
>> + cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
>> ];
>>
>> env = {
>> - INITRAMFS = initramfs;
>> KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>> ROOT_FS = "${rootfs}/rootfs";
>> ROOT_FS_VERITY = "${rootfs}/rootfs.verity.superblock";
>> ROOT_FS_VERITY_ROOTHASH = "${rootfs}/rootfs.verity.roothash";
>
> Since efi is tied to a specific rootfs, maybe it would be nice to use
> efi.rootfs here?
Will change in v4.
>> - SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
>> + SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
>
> We can just get this from the default systemd package. Doesn't need to
> be efi's special overridden one.
Would it be better to have the override in a Spectrum-wide overlay?
>> + EFI_IMAGE = efi;
>> EFINAME = "BOOT${toUpper efiArch}.EFI";
>> - } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
>> - DTBS = "${rootfs.kernel}/dtbs";
>> };
>>
>> buildFlags = [ "dest=$(out)" ];
>> @@ -65,6 +56,6 @@ stdenv.mkDerivation {
>> unsafeDiscardReferences = { out = true; };
>> dontFixup = true;
>>
>> - passthru = { inherit initramfs rootfs; };
>> + passthru = { inherit rootfs; };
>> }
>> ) (_: {})
>>
>> --
>> 2.51.2
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 1/2] Build verity images in rootfs Nix derivation
2025-11-13 22:33 ` Demi Marie Obenour
@ 2025-11-14 11:53 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-14 11:53 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 5142 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> On 11/13/25 06:46, Alyssa Ross wrote:
>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>
>>> diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
>>> index cb13fbb35f065b67d291d4a35591d6f12720060c..102870ecba4456303414e2531ea592473ddfc1cf 100644
>>> --- a/host/initramfs/Makefile
>>> +++ b/host/initramfs/Makefile
>>> @@ -35,26 +35,10 @@ build/mountpoints:
>>> cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
>>> find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
>>>
>>> -# veritysetup format produces two files, but Make only (portably)
>>> -# supports one output per rule, so we combine the two outputs then
>>> -# define two more rules to separate them again.
>>> -build/rootfs.verity: $(ROOT_FS)
>>> - mkdir -p build
>>> - $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
>>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>>> - > build/rootfs.verity.roothash.tmp
>>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>>> - > $@
>>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>>> -build/rootfs.verity.roothash: build/rootfs.verity
>>> - head -n 1 build/rootfs.verity > $@
>>> -build/rootfs.verity.superblock: build/rootfs.verity
>>> - tail -n +2 build/rootfs.verity > $@
>>> -
>>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
>>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_VERITY) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS)
>>> ../../scripts/make-gpt.sh $@.tmp \
>>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>> - $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>>> + "$$ROOT_FS_VERITY:verity:$$(../../scripts/format-uuid.sh "$$(dd "if=$$ROOT_FS_VERITY_ROOTHASH" bs=32 skip=1 count=1 status=none)")" \
>>
>> Indentation got messed up here.
>>
>> Given rootfs has a well-defined output structure, maybe we could just
>> write $(ROOT_FS)/rootfs.verity.roothash, so we don't need to define lots
>> of different environment variables in each component that uses the
>> verity data.
>>
>> I think we should consistently use Make variable expansion rather than
>> shell variable expansion when we're using the variable in a Make
>> dependency line too, to avoid the possibility of them being different.
>
> Make expansion followed by shell expansion and just Make expansion aren't
> even consistent with each other.
Can you elaborate?
> >> build/fifo:
>>> mkdir -p build
>>> @@ -83,25 +95,10 @@ clean:
>>> rm -rf build
>>> .PHONY: clean
>>>
>>> -# veritysetup format produces two files, but Make only (portably)
>>> -# supports one output per rule, so we combine the two outputs then
>>> -# define two more rules to separate them again.
>>> -build/rootfs.verity: $(dest)
>>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>>> - > build/rootfs.verity.roothash.tmp
>>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>>> - > $@
>>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>>> -build/rootfs.verity.roothash: build/rootfs.verity
>>> - head -n 1 build/rootfs.verity > $@
>>> -build/rootfs.verity.superblock: build/rootfs.verity
>>> - tail -n +2 build/rootfs.verity > $@
>>> -
>>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(dest)/timestamp
>>> ../../scripts/make-gpt.sh $@.tmp \
>>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>>> + $(dest)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(dest)/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>>> + $(dest)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(dest)/rootfs.verity.roothash)")
>>> mv $@.tmp $@
>>>
>>> debug:
>>> @@ -111,7 +108,7 @@ debug:
>>> $(VMLINUX)
>>> .PHONY: debug
>>>
>>> -run: build/live.img $(EXT_FS) build/rootfs.verity.roothash
>>> +run: build/live.img
>>
>> What happened to $(EXT_FS)?
>
> Since commit 12b64009d9cde56b5629a832086d2c2311908ebe
> ("host/initramfs/extfs.nix: remove") it has been unused.
> I deleted it while changing other stuff in this line.
Got it. I'll just push a drop of $(EXT_FS) now then.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v3 2/2] Move UKI creation to a separate derivation
2025-11-13 22:42 ` Demi Marie Obenour
@ 2025-11-14 11:58 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-14 11:58 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 5098 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> On 11/13/25 06:57, Alyssa Ross wrote:
>> Demi Marie Obenour <demiobenour@gmail.com> writes:
>>
>>> It will be used by the update code later.
>>>
>>> No functional change intended, other than a trivial shell script
>>> refactoring.
>>>
>>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>>> ---
>>> host/efi.nix | 46 ++++++++++++++++++++++++++++++++++++++++++++++
>>> pkgs/default.nix | 1 +
>>> release/live/Makefile | 15 ++-------------
>>> release/live/default.nix | 19 +++++--------------
>>> 4 files changed, 54 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/host/efi.nix b/host/efi.nix
>>> new file mode 100644
>>> index 0000000000000000000000000000000000000000..a2b47fd050fbf00050473a0d5a1373eb96c341b5
>>> --- /dev/null
>>> +++ b/host/efi.nix
>>> @@ -0,0 +1,46 @@
>>> +# SPDX-License-Identifier: EUPL-1.2+
>>
>> MIT for Nix files please. (Fine to take my stuff from the EUPL-1.2+
>> Makefile and use it in a MIT-licensed Nix file.)
>
> I think it would be best to relicense the Makefiles under MIT if we can,
> so that we can move code back and forth even after neither of us knows every
> single copyright holder. Feel free to relicense my contributions to them.
Yes, perhaps worth considering. I'll think about it.
>>> + __structuredAttrs = true;
>>> + unsafeDiscardReferences = { out = true; };
>>> + dontFixup = true;
>>> + passthru = { inherit systemd; };
>>> + env = {
>>> + DTBS = "${rootfs.kernel}/dtbs";
>>> + KERNEL = kernel;
>>> + INITRAMFS = initramfs;
>>> + ROOTFS = rootfs;
>>> + };
>>
>> Usually we'd just inline these via string interpolation, rather than
>> passing them through as environment variables.
>
> Done, except for DTBS which is used more than once.
Even so it's very short.
>>> diff --git a/pkgs/default.nix b/pkgs/default.nix
>>> index cc60228a10cddcb70e5ab9faa1bab7d74f3ebb35..c9f6dcfad9369567468b30d1c5697e3551a7b236 100644
>>> --- a/pkgs/default.nix
>>> +++ b/pkgs/default.nix
>>> @@ -36,6 +36,7 @@ let
>>> path: (import path { inherit (self) callPackage; }).override;
>>>
>>> rootfs = self.callSpectrumPackage ../host/rootfs {};
>>> + efi = self.callSpectrumPackage ../host/efi.nix {};
>>> spectrum-build-tools = self.callSpectrumPackage ../tools {
>>> appSupport = false;
>>> buildSupport = true;
>>
>> Generally images don't need entries here, and can just be loaded by
>> callSpectrumPackage. There was a specific reason to make an exception
>> for rootfs (which I've now forgotten).
>
> What is the general rule for what should go in pkgs/default.nix?
> If you could add it to the docs that would be great.
Uh, "packages" should go in pkgs/default.nix. I'd need to remember the
rationale for rootfs being in there to say more, and I don't right now.
>>> diff --git a/release/live/Makefile b/release/live/Makefile
>>> index 191b44944af0adf965e1d5f2785719b236bfd99c..4de8743f42dec65aa863c3020cd70124316a6118 100644
>>> --- a/release/live/Makefile
>>> +++ b/release/live/Makefile
>>> @@ -19,19 +19,8 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
>>> build/empty:
>>> mkdir -p $@
>>>
>>> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
>>> - { \
>>> - printf "[UKI]\nDeviceTreeAuto=" && \
>>> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
>>> - } | $(UKIFY) build \
>>> - --output $@ \
>>> - --config /dev/stdin \
>>> - --linux $(KERNEL) \
>>> - --initrd $(INITRAMFS) \
>>> - --os-release $$'NAME="Spectrum"\n' \
>>> - --cmdline "ro intel_iommu=on roothash=$$(cat "$$ROOT_FS_VERITY_ROOTHASH")"
>>> -
>>> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
>>> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
>>> + ln -sf -- "$$EFI_IMAGE" build/spectrum.efi
>>> $(TRUNCATE) -s 440401920 $@
>>> $(MKFS_FAT) $@
>>> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
>>
>> Why a symlink? Why not just replace the path we copy from?
>
> The basename of the path is actually important. I tried using
> $(EFI_IMAGE) and the system didn't boot.
So this doesn't work?
$(MCOPY) -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi
I'd be very curious to see the diff between that and a working image.
>>> - SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
>>> + SYSTEMD_BOOT_EFI = "${efi.systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
>>
>> We can just get this from the default systemd package. Doesn't need to
>> be efi's special overridden one.
>
> Would it be better to have the override in a Spectrum-wide overlay?
You'd end up doing a lot of rebuilding for everything that depends on
systemd. We could also have it so that Spectrum's "systemd" in
pkgs/default.nix differs from the systemd used inside Nixpkgs and
available as pkgs.systemd, but that would get /extremely/ confusing.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-19 8:15 ` Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
` (3 more replies)
2 siblings, 4 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-19 8:15 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v4:
- Many cleanups.
- Respond to suggestions from code review.
- Link to v3: https://spectrum-os.org/lists/archives/spectrum-devel/20251111-refactor-verity-v3-0-575726639f9e@gmail.com
Changes in v3:
- Rebase on main
- Link to v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251107-refactor-verity-v2-0-2af58b1a4a87@gmail.com
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 40 +++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++--------------------
host/initramfs/default.nix | 1 +
host/initramfs/shell.nix | 2 +-
host/rootfs/Makefile | 47 ++++++++++++++++++++++------------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 38 +++++--------------------------------
release/live/default.nix | 27 +++++++++++---------------
release/live/shell.nix | 9 ++++++++-
11 files changed, 102 insertions(+), 100 deletions(-)
---
base-commit: 99f09ab0a69f41eb14795c1cd047d5cd6ee5896e
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v4 1/2] Build verity images in rootfs Nix derivation
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-19 8:15 ` Demi Marie Obenour
2025-11-25 12:27 ` Alyssa Ross
2025-11-19 8:15 ` [PATCH v4 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
` (2 subsequent siblings)
3 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-19 8:15 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++--------------------
host/initramfs/default.nix | 1 +
host/initramfs/shell.nix | 2 +-
host/rootfs/Makefile | 47 ++++++++++++++++++++++------------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 26 +++++--------------------
release/live/default.nix | 2 +-
release/live/shell.nix | 3 ++-
10 files changed, 46 insertions(+), 73 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..13bb548d6146684a25dab1e31228c0b9a4ca8db7 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/default.nix b/host/initramfs/default.nix
index d35e1b514ec48015f5110e65e5ae944b28244c4f..88f9379444148a071ef0de45132415fba0f6c12e 100644
--- a/host/initramfs/default.nix
+++ b/host/initramfs/default.nix
@@ -105,6 +105,7 @@ stdenvNoCC.mkDerivation {
env = {
PACKAGES_CPIO = packagesCpio;
+ ROOT_FS_DIR = rootfs;
} // lib.optionalAttrs stdenvNoCC.hostPlatform.isx86_64 {
MICROCODE = microcode;
};
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index 8b47aa53bc19a818ebf563e281f22e82202a8ea5..ff067354881b480656fae9b339a0a9068475d85f 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -17,6 +17,6 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS_DIR = rootfs;
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 27a7c689c39bf9bc93b5ba33ce661be7e47b67f1..055185064d84d9450c2076fdeb410b21d00f1d40 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -1,12 +1,12 @@
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
.POSIX:
include ../../lib/common.mk
include file-list.mk
-
-dest = build/rootfs.erofs
+ROOT_FS_DIR = build
DIRS = \
dev \
@@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
- set -euo pipefail; \
+build/verity-timestamp: $(ROOT_FS)
+ $(VERITYSETUP) format \
+ --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
+ -- $(ROOT_FS) $(ROOT_FS_VERITY)
+ # Add trailing newline
+ echo >> $(ROOT_FS_VERITY_ROOTHASH)
+ touch -- $(ROOT_FS_DIR)/verity-timestamp
+
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
+ mkdir -p $(ROOT_FS_DIR) && \
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(DIRS) ;\
printf 'build/fifo\n%s\n' $(FIFOS) ;\
- } | ../../scripts/make-erofs.sh $@
+ } | ../../scripts/make-erofs.sh $(ROOT_FS)
build/fifo:
mkdir -p build
@@ -83,25 +95,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_DIR)/verity-timestamp $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH)")
mv $@.tmp $@
debug:
@@ -111,7 +108,7 @@ debug:
$(VMLINUX)
.PHONY: debug
-run: build/live.img build/rootfs.verity.roothash
+run: build/live.img
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
truncate -s 10G "$$ext" && \
@@ -132,7 +129,7 @@ run: build/live.img build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..1578155fa0fb9a4df3fb4884e21ed7d8d8f821dc 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
@@ -147,7 +147,9 @@ stdenvNoCC.mkDerivation {
'';
};
- makeFlags = [ "dest=$(out)" ];
+ # The Makefile uses $(ROOT_FS_DIR), not $(dest), so it can share code
+ # with other Makefiles that also use this variable.
+ makeFlags = [ "ROOT_FS_DIR=$(out)" ];
dontInstall = true;
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..d1cc4d0514070cc3f418c4d1b7e929abd40d985c 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -11,6 +11,10 @@ GDB = gdb
MCOPY = mcopy
MKFS_FAT = mkfs.fat
MMD = mmd
+ROOT_FS = $(ROOT_FS_DIR)/rootfs
+ROOT_FS_IMAGES = $(ROOT_FS) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
+ROOT_FS_VERITY = $(ROOT_FS_DIR)/rootfs.verity.superblock
+ROOT_FS_VERITY_ROOTHASH = $(ROOT_FS_DIR)/rootfs.verity.roothash
S6_IPCSERVER_SOCKETBINDER = s6-ipcserver-socketbinder
TAR = tar
TRUNCATE = truncate
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..7372b41d94bfb10f7761955d9d1a246e9785b7f8 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..7adaefef330daf11372cff0d2d04cca400efba1f 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -46,7 +46,7 @@ stdenv.mkDerivation {
env = {
INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS_DIR = rootfs;
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
EFINAME = "BOOT${toUpper efiArch}.EFI";
} // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 5acaa8c5b113fd2789aaea9268487b193bab37af..c5db7b732ef048b4c0cb87a4c5ea614e993db516 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
+import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,6 +10,7 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
+ ROOT_FS_DIR = rootfs;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v4 2/2] Move UKI creation to a separate derivation
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-19 8:15 ` Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
3 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-19 8:15 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
I kept release/live/default.nix using the UKI's systemd because the old
code did it that way. Changing this would be better in a separate
commit.
---
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
host/rootfs/Makefile | 8 ++++----
release/live/Makefile | 16 ++--------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 10 ++++++++--
5 files changed, 65 insertions(+), 36 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..d0ce260bd908c186059b75a1b4f42258b0e62bff
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ callSpectrumPackage, config, cryptsetup, rootfs
+, runCommand, stdenv, systemdUkify
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit initramfs rootfs systemd; };
+} ''
+ read -r roothash < ${rootfs}/rootfs.verity.roothash
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d ${rootfs.kernel}/dtbs ]; then
+ find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux ${kernel} \
+ --initrd ${initramfs} \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 055185064d84d9450c2076fdeb410b21d00f1d40..4c14d3acfa8f7ffd276fdfb684d08bf58fd80a15 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -46,6 +46,10 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
build/verity-timestamp: $(ROOT_FS)
$(VERITYSETUP) format \
--root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
@@ -54,10 +58,6 @@ build/verity-timestamp: $(ROOT_FS)
echo >> $(ROOT_FS_VERITY_ROOTHASH)
touch -- $(ROOT_FS_DIR)/verity-timestamp
-# This rule produces three files but Make only (portably)
-# supports one output per rule. Instead of resorting to temporary
-# files, a timestamp file is created as the last step. The actual
-# outputs are produced as side-effects.
$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
mkdir -p $(ROOT_FS_DIR) && \
{ \
diff --git a/release/live/Makefile b/release/live/Makefile
index 7372b41d94bfb10f7761955d9d1a246e9785b7f8..d61248e94599adc5229d0ad38d54b9f649d66ca1 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,23 +19,11 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
- $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
+ $(MCOPY) -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
clean:
diff --git a/release/live/default.nix b/release/live/default.nix
index 7adaefef330daf11372cff0d2d04cca400efba1f..ac2d7a55fd4fe0c02108309ecea20e368000af0d 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -3,10 +3,9 @@
# SPDX-FileCopyrightText: 2022 Unikie
import ../../lib/call-package.nix (
-{ callSpectrumPackage, spectrum-build-tools, rootfs, src
+{ callSpectrumPackage, spectrum-build-tools, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
}:
let
@@ -14,14 +13,12 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
+
+ efi = callSpectrumPackage ../../host/efi.nix {};
+
+ # The initramfs and rootfs must match those used to build the UKI.
+ inherit (efi) initramfs rootfs systemd;
in
stdenv.mkDerivation {
@@ -40,17 +37,15 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
- KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS_DIR = rootfs;
+ KERNEL = "${efi.rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ ROOT_FS_DIR = "${efi.rootfs}";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -63,6 +58,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit efi initramfs rootfs; };
}
) (_: {})
diff --git a/release/live/shell.nix b/release/live/shell.nix
index c5db7b732ef048b4c0cb87a4c5ea614e993db516..ffaa9a571c662810348822a5952d479d251a25e5 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
+import ../../lib/call-package.nix (
+{ callSpectrumPackage, stdenv, qemu_kvm }:
+
+let
+ efi = callSpectrumPackage ../../host/efi.nix {};
+in
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,7 +15,8 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, root
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
- ROOT_FS_DIR = rootfs;
+ ROOT_FS_DIR = efi.rootfs;
+ EFI_IMAGE = efi;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-22 1:21 ` Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
` (2 more replies)
2025-11-26 18:58 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
3 siblings, 3 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-22 1:21 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v5:
- Rebase
- Link to v4: https://spectrum-os.org/lists/archives/spectrum-devel/20251119-refactor-verity-v4-0-9bc56d5216c0@gmail.com
Changes in v4:
- Many cleanups.
- Respond to suggestions from code review.
- Link to v3: https://spectrum-os.org/lists/archives/spectrum-devel/20251111-refactor-verity-v3-0-575726639f9e@gmail.com
Changes in v3:
- Rebase on main
- Link to v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251107-refactor-verity-v2-0-2af58b1a4a87@gmail.com
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 40 +++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++--------------------
host/initramfs/default.nix | 1 +
host/initramfs/shell.nix | 2 +-
host/rootfs/Makefile | 47 ++++++++++++++++++++++------------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 38 +++++--------------------------------
release/live/default.nix | 27 +++++++++++---------------
release/live/shell.nix | 9 ++++++++-
11 files changed, 102 insertions(+), 100 deletions(-)
---
base-commit: f41b4ab1e6dace7ee3c184f3154cda76f34be7db
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v5 1/2] Build verity images in rootfs Nix derivation
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-22 1:21 ` Demi Marie Obenour
2025-11-25 12:34 ` Alyssa Ross
2025-11-22 1:21 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-26 19:10 ` [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-22 1:21 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++--------------------
host/initramfs/default.nix | 1 +
host/initramfs/shell.nix | 2 +-
host/rootfs/Makefile | 47 ++++++++++++++++++++++------------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 26 +++++--------------------
release/live/default.nix | 2 +-
release/live/shell.nix | 3 ++-
10 files changed, 46 insertions(+), 73 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..13bb548d6146684a25dab1e31228c0b9a4ca8db7 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< "$$ROOT_FS_VERITY_ROOTHASH") nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/default.nix b/host/initramfs/default.nix
index d35e1b514ec48015f5110e65e5ae944b28244c4f..88f9379444148a071ef0de45132415fba0f6c12e 100644
--- a/host/initramfs/default.nix
+++ b/host/initramfs/default.nix
@@ -105,6 +105,7 @@ stdenvNoCC.mkDerivation {
env = {
PACKAGES_CPIO = packagesCpio;
+ ROOT_FS_DIR = rootfs;
} // lib.optionalAttrs stdenvNoCC.hostPlatform.isx86_64 {
MICROCODE = microcode;
};
diff --git a/host/initramfs/shell.nix b/host/initramfs/shell.nix
index 8b47aa53bc19a818ebf563e281f22e82202a8ea5..ff067354881b480656fae9b339a0a9068475d85f 100644
--- a/host/initramfs/shell.nix
+++ b/host/initramfs/shell.nix
@@ -17,6 +17,6 @@ initramfs.overrideAttrs ({ nativeBuildInputs ? [], env ? {}, ... }: {
env = env // {
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS_DIR = rootfs;
};
})) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 4067be0c45cc83ce4670ed76e956db58f8e93e02..5e3c9238f0e00f86aa5943212b8fc8fd896ce54a 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -1,12 +1,12 @@
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
.POSIX:
include ../../lib/common.mk
include file-list.mk
-
-dest = build/rootfs.erofs
+ROOT_FS_DIR = build
DIRS = \
dev \
@@ -40,15 +40,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
- set -euo pipefail; \
+build/verity-timestamp: $(ROOT_FS)
+ $(VERITYSETUP) format \
+ --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
+ -- $(ROOT_FS) $(ROOT_FS_VERITY)
+ # Add trailing newline
+ echo >> $(ROOT_FS_VERITY_ROOTHASH)
+ touch -- $(ROOT_FS_DIR)/verity-timestamp
+
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
+ mkdir -p $(ROOT_FS_DIR) && \
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
printf 'build/empty\n%s\n' $(DIRS) ;\
printf 'build/fifo\n%s\n' $(FIFOS) ;\
- } | ../../scripts/make-erofs.sh $@
+ } | ../../scripts/make-erofs.sh $(ROOT_FS)
build/fifo:
mkdir -p build
@@ -77,25 +89,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_DIR)/verity-timestamp $(ROOT_FS)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH)")
mv $@.tmp $@
debug:
@@ -105,7 +102,7 @@ debug:
$(VMLINUX)
.PHONY: debug
-run: build/live.img build/rootfs.verity.roothash
+run: build/live.img
@set -x && \
ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
truncate -s 10G "$$ext" && \
@@ -126,7 +123,7 @@ run: build/live.img build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..1578155fa0fb9a4df3fb4884e21ed7d8d8f821dc 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
@@ -147,7 +147,9 @@ stdenvNoCC.mkDerivation {
'';
};
- makeFlags = [ "dest=$(out)" ];
+ # The Makefile uses $(ROOT_FS_DIR), not $(dest), so it can share code
+ # with other Makefiles that also use this variable.
+ makeFlags = [ "ROOT_FS_DIR=$(out)" ];
dontInstall = true;
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..d1cc4d0514070cc3f418c4d1b7e929abd40d985c 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -11,6 +11,10 @@ GDB = gdb
MCOPY = mcopy
MKFS_FAT = mkfs.fat
MMD = mmd
+ROOT_FS = $(ROOT_FS_DIR)/rootfs
+ROOT_FS_IMAGES = $(ROOT_FS) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
+ROOT_FS_VERITY = $(ROOT_FS_DIR)/rootfs.verity.superblock
+ROOT_FS_VERITY_ROOTHASH = $(ROOT_FS_DIR)/rootfs.verity.roothash
S6_IPCSERVER_SOCKETBINDER = s6-ipcserver-socketbinder
TAR = tar
TRUNCATE = truncate
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..7372b41d94bfb10f7761955d9d1a246e9785b7f8 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..7adaefef330daf11372cff0d2d04cca400efba1f 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -46,7 +46,7 @@ stdenv.mkDerivation {
env = {
INITRAMFS = initramfs;
KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ ROOT_FS_DIR = rootfs;
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
EFINAME = "BOOT${toUpper efiArch}.EFI";
} // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 5acaa8c5b113fd2789aaea9268487b193bab37af..c5db7b732ef048b4c0cb87a4c5ea614e993db516 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
+import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,6 +10,7 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
+ ROOT_FS_DIR = rootfs;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v5 2/2] Move UKI creation to a separate derivation
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-22 1:21 ` Demi Marie Obenour
2025-11-25 12:41 ` Alyssa Ross
2025-11-26 19:10 ` [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2 siblings, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-22 1:21 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
I kept release/live/default.nix using the UKI's systemd because the old
code did it that way. Changing this would be better in a separate
commit.
---
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
host/rootfs/Makefile | 8 ++++----
release/live/Makefile | 16 ++--------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 10 ++++++++--
5 files changed, 65 insertions(+), 36 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..d0ce260bd908c186059b75a1b4f42258b0e62bff
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ callSpectrumPackage, config, cryptsetup, rootfs
+, runCommand, stdenv, systemdUkify
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit initramfs rootfs systemd; };
+} ''
+ read -r roothash < ${rootfs}/rootfs.verity.roothash
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d ${rootfs.kernel}/dtbs ]; then
+ find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux ${kernel} \
+ --initrd ${initramfs} \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 5e3c9238f0e00f86aa5943212b8fc8fd896ce54a..aac915ffb2781aee0997c169e86e3fd1983aa3b3 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -40,6 +40,10 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
build/verity-timestamp: $(ROOT_FS)
$(VERITYSETUP) format \
--root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
@@ -48,10 +52,6 @@ build/verity-timestamp: $(ROOT_FS)
echo >> $(ROOT_FS_VERITY_ROOTHASH)
touch -- $(ROOT_FS_DIR)/verity-timestamp
-# This rule produces three files but Make only (portably)
-# supports one output per rule. Instead of resorting to temporary
-# files, a timestamp file is created as the last step. The actual
-# outputs are produced as side-effects.
$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
mkdir -p $(ROOT_FS_DIR) && \
{ \
diff --git a/release/live/Makefile b/release/live/Makefile
index 7372b41d94bfb10f7761955d9d1a246e9785b7f8..d61248e94599adc5229d0ad38d54b9f649d66ca1 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,23 +19,11 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
- $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
+ $(MCOPY) -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
clean:
diff --git a/release/live/default.nix b/release/live/default.nix
index 7adaefef330daf11372cff0d2d04cca400efba1f..ac2d7a55fd4fe0c02108309ecea20e368000af0d 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -3,10 +3,9 @@
# SPDX-FileCopyrightText: 2022 Unikie
import ../../lib/call-package.nix (
-{ callSpectrumPackage, spectrum-build-tools, rootfs, src
+{ callSpectrumPackage, spectrum-build-tools, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
}:
let
@@ -14,14 +13,12 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
+
+ efi = callSpectrumPackage ../../host/efi.nix {};
+
+ # The initramfs and rootfs must match those used to build the UKI.
+ inherit (efi) initramfs rootfs systemd;
in
stdenv.mkDerivation {
@@ -40,17 +37,15 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
- KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS_DIR = rootfs;
+ KERNEL = "${efi.rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ ROOT_FS_DIR = "${efi.rootfs}";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -63,6 +58,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit efi initramfs rootfs; };
}
) (_: {})
diff --git a/release/live/shell.nix b/release/live/shell.nix
index c5db7b732ef048b4c0cb87a4c5ea614e993db516..ffaa9a571c662810348822a5952d479d251a25e5 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
+import ../../lib/call-package.nix (
+{ callSpectrumPackage, stdenv, qemu_kvm }:
+
+let
+ efi = callSpectrumPackage ../../host/efi.nix {};
+in
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,7 +15,8 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, root
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
- ROOT_FS_DIR = rootfs;
+ ROOT_FS_DIR = efi.rootfs;
+ EFI_IMAGE = efi;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH v4 1/2] Build verity images in rootfs Nix derivation
2025-11-19 8:15 ` [PATCH v4 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-25 12:27 ` Alyssa Ross
2025-11-25 12:31 ` Alyssa Ross
0 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-25 12:27 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 7402 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
> index 27a7c689c39bf9bc93b5ba33ce661be7e47b67f1..055185064d84d9450c2076fdeb410b21d00f1d40 100644
> --- a/host/rootfs/Makefile
> +++ b/host/rootfs/Makefile
> @@ -1,12 +1,12 @@
> # SPDX-License-Identifier: EUPL-1.2+
> # SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
>
> .POSIX:
>
> include ../../lib/common.mk
> include file-list.mk
> -
> -dest = build/rootfs.erofs
> +ROOT_FS_DIR = build
>
> DIRS = \
> dev \
> @@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>
> BUILD_FILES = build/etc/s6-rc
>
> -$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> - set -euo pipefail; \
> +build/verity-timestamp: $(ROOT_FS)
> + $(VERITYSETUP) format \
> + --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
> + -- $(ROOT_FS) $(ROOT_FS_VERITY)
> + # Add trailing newline
> + echo >> $(ROOT_FS_VERITY_ROOTHASH)
Why do we need to do this?
(Emacs would also rather your comments were not indented, so they're
interpreted by Make as comments rather than being passed on to the
shell.)
> + touch -- $(ROOT_FS_DIR)/verity-timestamp
This should be build/verity-timestamp (like the rule), or even better $@.
> +
> +# This rule produces three files but Make only (portably)
> +# supports one output per rule. Instead of resorting to temporary
> +# files, a timestamp file is created as the last step. The actual
> +# outputs are produced as side-effects.
Is this comment supposed to be on the previous rule?
> +$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> + mkdir -p $(ROOT_FS_DIR) && \
> { \
> cat $(PACKAGES_FILE) ;\
> for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
> for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
> printf 'build/empty\n%s\n' $(DIRS) ;\
> printf 'build/fifo\n%s\n' $(FIFOS) ;\
> - } | ../../scripts/make-erofs.sh $@
> + } | ../../scripts/make-erofs.sh $(ROOT_FS)
Why change this?
>
> build/fifo:
> mkdir -p build
> @@ -83,25 +95,10 @@ clean:
> rm -rf build
> .PHONY: clean
>
> -# veritysetup format produces two files, but Make only (portably)
> -# supports one output per rule, so we combine the two outputs then
> -# define two more rules to separate them again.
> -build/rootfs.verity: $(dest)
> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
> - > build/rootfs.verity.roothash.tmp
> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
> - > $@
> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
> -build/rootfs.verity.roothash: build/rootfs.verity
> - head -n 1 build/rootfs.verity > $@
> -build/rootfs.verity.superblock: build/rootfs.verity
> - tail -n +2 build/rootfs.verity > $@
> -
> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_DIR)/verity-timestamp $(ROOT_FS)
Here you're also still referring to $(ROOT_FS_DIR)/verity-timestamp
rather than build/verity-timestamp.
> ../../scripts/make-gpt.sh $@.tmp \
> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
> + $(ROOT_FS)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
> + $(ROOT_FS)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH)")
This can't be right, can it? $(ROOT_FS) is a file.
> mv $@.tmp $@
>
> debug:
> @@ -111,7 +108,7 @@ debug:
> $(VMLINUX)
> .PHONY: debug
>
> -run: build/live.img build/rootfs.verity.roothash
> +run: build/live.img
I'd still prefer we kept the explicit dependency, even though we will
get it via build/live.img as well.
> @set -x && \
> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
> truncate -s 10G "$$ext" && \
> @@ -132,7 +129,7 @@ run: build/live.img build/rootfs.verity.roothash
> -device virtconsole,chardev=virtiocon0 \
> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
> -drive file=/proc/self/fd/3,if=virtio,format=raw \
> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
> + -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
> -device virtio-keyboard \
> -device virtio-mouse \
> -device virtio-gpu \
> diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
> index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..1578155fa0fb9a4df3fb4884e21ed7d8d8f821dc 100644
> --- a/host/rootfs/default.nix
> +++ b/host/rootfs/default.nix
> @@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
> };
> sourceRoot = "source/host/rootfs";
>
> - nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
> + nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
>
> env = {
> PACKAGES = runCommand "packages" {} ''
> @@ -147,7 +147,9 @@ stdenvNoCC.mkDerivation {
> '';
> };
>
> - makeFlags = [ "dest=$(out)" ];
> + # The Makefile uses $(ROOT_FS_DIR), not $(dest), so it can share code
> + # with other Makefiles that also use this variable.
> + makeFlags = [ "ROOT_FS_DIR=$(out)" ];
>
> dontInstall = true;
>
> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
> index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
> --- a/host/rootfs/shell.nix
> +++ b/host/rootfs/shell.nix
> @@ -12,7 +12,7 @@ rootfs.overrideAttrs (
>
> {
> nativeBuildInputs = nativeBuildInputs ++ [
> - btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
> + btrfs-progs jq netcat qemu_kvm reuse util-linux
> ];
>
> env = env // {
> diff --git a/lib/common.mk b/lib/common.mk
> index 277c3544036d9a9057f8ba4ad37fe2207548cc59..d1cc4d0514070cc3f418c4d1b7e929abd40d985c 100644
> --- a/lib/common.mk
> +++ b/lib/common.mk
> @@ -11,6 +11,10 @@ GDB = gdb
> MCOPY = mcopy
> MKFS_FAT = mkfs.fat
> MMD = mmd
> +ROOT_FS = $(ROOT_FS_DIR)/rootfs
Would be nice for this to keep its file extension.
> +ROOT_FS_IMAGES = $(ROOT_FS) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
I'm not sure "IMAGES" makes sense as a name for this. A verity roothash
is not an image. ROOT_FS_FILES?
Alternative naming scheme idea, that avoids mistaking ROOT_FS for the
directory like has happened above:
ROOT_FS (for the directory), ROOT_FS_IMAGE, ROOT_FS_VERITY,
ROOT_FS_VERITY_ROOTHASH.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v4 1/2] Build verity images in rootfs Nix derivation
2025-11-25 12:27 ` Alyssa Ross
@ 2025-11-25 12:31 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-25 12:31 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 7781 bytes --]
Whoops, just realised I replied to v4 and not v5. You can ignore this,
and I'll resend any comments that are still relevant to v5.
Alyssa Ross <hi@alyssa.is> writes:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
>> index 27a7c689c39bf9bc93b5ba33ce661be7e47b67f1..055185064d84d9450c2076fdeb410b21d00f1d40 100644
>> --- a/host/rootfs/Makefile
>> +++ b/host/rootfs/Makefile
>> @@ -1,12 +1,12 @@
>> # SPDX-License-Identifier: EUPL-1.2+
>> # SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
>> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
>>
>> .POSIX:
>>
>> include ../../lib/common.mk
>> include file-list.mk
>> -
>> -dest = build/rootfs.erofs
>> +ROOT_FS_DIR = build
>>
>> DIRS = \
>> dev \
>> @@ -46,15 +46,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>>
>> BUILD_FILES = build/etc/s6-rc
>>
>> -$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
>> - set -euo pipefail; \
>> +build/verity-timestamp: $(ROOT_FS)
>> + $(VERITYSETUP) format \
>> + --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
>> + -- $(ROOT_FS) $(ROOT_FS_VERITY)
>> + # Add trailing newline
>> + echo >> $(ROOT_FS_VERITY_ROOTHASH)
>
> Why do we need to do this?
>
> (Emacs would also rather your comments were not indented, so they're
> interpreted by Make as comments rather than being passed on to the
> shell.)
>
>> + touch -- $(ROOT_FS_DIR)/verity-timestamp
>
> This should be build/verity-timestamp (like the rule), or even better $@.
>
>> +
>> +# This rule produces three files but Make only (portably)
>> +# supports one output per rule. Instead of resorting to temporary
>> +# files, a timestamp file is created as the last step. The actual
>> +# outputs are produced as side-effects.
>
> Is this comment supposed to be on the previous rule?
>
>> +$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
>> + mkdir -p $(ROOT_FS_DIR) && \
>> { \
>> cat $(PACKAGES_FILE) ;\
>> for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
>> for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
>> printf 'build/empty\n%s\n' $(DIRS) ;\
>> printf 'build/fifo\n%s\n' $(FIFOS) ;\
>> - } | ../../scripts/make-erofs.sh $@
>> + } | ../../scripts/make-erofs.sh $(ROOT_FS)
>
> Why change this?
>
>>
>> build/fifo:
>> mkdir -p build
>> @@ -83,25 +95,10 @@ clean:
>> rm -rf build
>> .PHONY: clean
>>
>> -# veritysetup format produces two files, but Make only (portably)
>> -# supports one output per rule, so we combine the two outputs then
>> -# define two more rules to separate them again.
>> -build/rootfs.verity: $(dest)
>> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
>> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
>> - > build/rootfs.verity.roothash.tmp
>> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
>> - > $@
>> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
>> -build/rootfs.verity.roothash: build/rootfs.verity
>> - head -n 1 build/rootfs.verity > $@
>> -build/rootfs.verity.superblock: build/rootfs.verity
>> - tail -n +2 build/rootfs.verity > $@
>> -
>> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
>> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_DIR)/verity-timestamp $(ROOT_FS)
>
> Here you're also still referring to $(ROOT_FS_DIR)/verity-timestamp
> rather than build/verity-timestamp.
>
>> ../../scripts/make-gpt.sh $@.tmp \
>> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
>> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
>> + $(ROOT_FS)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
>> + $(ROOT_FS)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH)")
>
> This can't be right, can it? $(ROOT_FS) is a file.
>
>> mv $@.tmp $@
>>
>> debug:
>> @@ -111,7 +108,7 @@ debug:
>> $(VMLINUX)
>> .PHONY: debug
>>
>> -run: build/live.img build/rootfs.verity.roothash
>> +run: build/live.img
>
> I'd still prefer we kept the explicit dependency, even though we will
> get it via build/live.img as well.
>
>> @set -x && \
>> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
>> truncate -s 10G "$$ext" && \
>> @@ -132,7 +129,7 @@ run: build/live.img build/rootfs.verity.roothash
>> -device virtconsole,chardev=virtiocon0 \
>> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
>> -drive file=/proc/self/fd/3,if=virtio,format=raw \
>> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
>> + -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
>> -device virtio-keyboard \
>> -device virtio-mouse \
>> -device virtio-gpu \
>> diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
>> index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..1578155fa0fb9a4df3fb4884e21ed7d8d8f821dc 100644
>> --- a/host/rootfs/default.nix
>> +++ b/host/rootfs/default.nix
>> @@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
>> };
>> sourceRoot = "source/host/rootfs";
>>
>> - nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
>> + nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
>>
>> env = {
>> PACKAGES = runCommand "packages" {} ''
>> @@ -147,7 +147,9 @@ stdenvNoCC.mkDerivation {
>> '';
>> };
>>
>> - makeFlags = [ "dest=$(out)" ];
>> + # The Makefile uses $(ROOT_FS_DIR), not $(dest), so it can share code
>> + # with other Makefiles that also use this variable.
>> + makeFlags = [ "ROOT_FS_DIR=$(out)" ];
>>
>> dontInstall = true;
>>
>> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
>> index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
>> --- a/host/rootfs/shell.nix
>> +++ b/host/rootfs/shell.nix
>> @@ -12,7 +12,7 @@ rootfs.overrideAttrs (
>>
>> {
>> nativeBuildInputs = nativeBuildInputs ++ [
>> - btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
>> + btrfs-progs jq netcat qemu_kvm reuse util-linux
>> ];
>>
>> env = env // {
>> diff --git a/lib/common.mk b/lib/common.mk
>> index 277c3544036d9a9057f8ba4ad37fe2207548cc59..d1cc4d0514070cc3f418c4d1b7e929abd40d985c 100644
>> --- a/lib/common.mk
>> +++ b/lib/common.mk
>> @@ -11,6 +11,10 @@ GDB = gdb
>> MCOPY = mcopy
>> MKFS_FAT = mkfs.fat
>> MMD = mmd
>> +ROOT_FS = $(ROOT_FS_DIR)/rootfs
>
> Would be nice for this to keep its file extension.
>
>> +ROOT_FS_IMAGES = $(ROOT_FS) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
>
> I'm not sure "IMAGES" makes sense as a name for this. A verity roothash
> is not an image. ROOT_FS_FILES?
>
> Alternative naming scheme idea, that avoids mistaking ROOT_FS for the
> directory like has happened above:
>
> ROOT_FS (for the directory), ROOT_FS_IMAGE, ROOT_FS_VERITY,
> ROOT_FS_VERITY_ROOTHASH.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v5 1/2] Build verity images in rootfs Nix derivation
2025-11-22 1:21 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-25 12:34 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-25 12:34 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 7516 bytes --]
Okay, resending relevant comments from my accidental review of v4:
Demi Marie Obenour <demiobenour@gmail.com> writes:
> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
> index 4067be0c45cc83ce4670ed76e956db58f8e93e02..5e3c9238f0e00f86aa5943212b8fc8fd896ce54a 100644
> --- a/host/rootfs/Makefile
> +++ b/host/rootfs/Makefile
> @@ -1,12 +1,12 @@
> # SPDX-License-Identifier: EUPL-1.2+
> # SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
>
> .POSIX:
>
> include ../../lib/common.mk
> include file-list.mk
> -
> -dest = build/rootfs.erofs
> +ROOT_FS_DIR = build
>
> DIRS = \
> dev \
> @@ -40,15 +40,27 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>
> BUILD_FILES = build/etc/s6-rc
>
> -$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> - set -euo pipefail; \
> +build/verity-timestamp: $(ROOT_FS)
> + $(VERITYSETUP) format \
> + --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
> + -- $(ROOT_FS) $(ROOT_FS_VERITY)
> + # Add trailing newline
> + echo >> $(ROOT_FS_VERITY_ROOTHASH)
Why do we need to do this?
(Emacs would also rather your comments were not indented, so they're
interpreted by Make as comments rather than being passed on to the
shell.)
> + touch -- $(ROOT_FS_DIR)/verity-timestamp
This should be build/verity-timestamp (like the rule), or even better $@.
> +
> +# This rule produces three files but Make only (portably)
> +# supports one output per rule. Instead of resorting to temporary
> +# files, a timestamp file is created as the last step. The actual
> +# outputs are produced as side-effects.
Is this comment supposed to be on the previous rule?
> +$(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> + mkdir -p $(ROOT_FS_DIR) && \
> { \
> cat $(PACKAGES_FILE) ;\
> for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
> for file in $(BUILD_FILES); do printf '%s\n%s\n' $$file $${file#build/}; done ;\
> printf 'build/empty\n%s\n' $(DIRS) ;\
> printf 'build/fifo\n%s\n' $(FIFOS) ;\
> - } | ../../scripts/make-erofs.sh $@
> + } | ../../scripts/make-erofs.sh $(ROOT_FS)
Why change this to something more likely to get out of sync?
>
> build/fifo:
> mkdir -p build
> @@ -77,25 +89,10 @@ clean:
> rm -rf build
> .PHONY: clean
>
> -# veritysetup format produces two files, but Make only (portably)
> -# supports one output per rule, so we combine the two outputs then
> -# define two more rules to separate them again.
> -build/rootfs.verity: $(dest)
> - $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
> - | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
> - > build/rootfs.verity.roothash.tmp
> - cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
> - > $@
> - rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
> -build/rootfs.verity.roothash: build/rootfs.verity
> - head -n 1 build/rootfs.verity > $@
> -build/rootfs.verity.superblock: build/rootfs.verity
> - tail -n +2 build/rootfs.verity > $@
> -
> -build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
> +build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_DIR)/verity-timestamp $(ROOT_FS)
Here you're also still referring to $(ROOT_FS_DIR)/verity-timestamp
rather than build/verity-timestamp.
> ../../scripts/make-gpt.sh $@.tmp \
> - build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
> - $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
> + $(ROOT_FS)/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
> + $(ROOT_FS)/rootfs:root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH)")
This can't be right, can it? $(ROOT_FS) is a file.
> mv $@.tmp $@
>
> debug:
> @@ -105,7 +102,7 @@ debug:
> $(VMLINUX)
> .PHONY: debug
>
> -run: build/live.img build/rootfs.verity.roothash
> +run: build/live.img
I'd still prefer we kept the explicit dependency, even though we will
get it via build/live.img as well.
> @set -x && \
> ext="$$(mktemp build/spectrum-rootfs-extfs.XXXXXXXXXX.img)" && \
> truncate -s 10G "$$ext" && \
> @@ -126,7 +123,7 @@ run: build/live.img build/rootfs.verity.roothash
> -device virtconsole,chardev=virtiocon0 \
> -drive file=build/live.img,if=virtio,format=raw,readonly=on \
> -drive file=/proc/self/fd/3,if=virtio,format=raw \
> - -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
> + -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
> -device virtio-keyboard \
> -device virtio-mouse \
> -device virtio-gpu \
> diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
> index 0ac70c7c077c0656c5820a5d8b3c7ce0e7c78e54..1578155fa0fb9a4df3fb4884e21ed7d8d8f821dc 100644
> --- a/host/rootfs/default.nix
> +++ b/host/rootfs/default.nix
> @@ -138,7 +138,7 @@ stdenvNoCC.mkDerivation {
> };
> sourceRoot = "source/host/rootfs";
>
> - nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
> + nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
>
> env = {
> PACKAGES = runCommand "packages" {} ''
> @@ -147,7 +147,9 @@ stdenvNoCC.mkDerivation {
> '';
> };
>
> - makeFlags = [ "dest=$(out)" ];
> + # The Makefile uses $(ROOT_FS_DIR), not $(dest), so it can share code
> + # with other Makefiles that also use this variable.
> + makeFlags = [ "ROOT_FS_DIR=$(out)" ];
>
> dontInstall = true;
>
> diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
> index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
> --- a/host/rootfs/shell.nix
> +++ b/host/rootfs/shell.nix
> @@ -12,7 +12,7 @@ rootfs.overrideAttrs (
>
> {
> nativeBuildInputs = nativeBuildInputs ++ [
> - btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
> + btrfs-progs jq netcat qemu_kvm reuse util-linux
> ];
>
> env = env // {
> diff --git a/lib/common.mk b/lib/common.mk
> index 277c3544036d9a9057f8ba4ad37fe2207548cc59..d1cc4d0514070cc3f418c4d1b7e929abd40d985c 100644
> --- a/lib/common.mk
> +++ b/lib/common.mk
> @@ -11,6 +11,10 @@ GDB = gdb
> MCOPY = mcopy
> MKFS_FAT = mkfs.fat
> MMD = mmd
> +ROOT_FS = $(ROOT_FS_DIR)/rootfs
Would be nice for this to keep its file extension.
> +ROOT_FS_IMAGES = $(ROOT_FS) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
I'm not sure "IMAGES" makes sense as a name for this. A verity roothash
is not an image. ROOT_FS_FILES?
Alternative naming scheme idea, that avoids mistaking ROOT_FS for the
directory like has happened above:
ROOT_FS (for the directory), ROOT_FS_IMAGE, ROOT_FS_VERITY,
ROOT_FS_VERITY_ROOTHASH.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v5 2/2] Move UKI creation to a separate derivation
2025-11-22 1:21 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-25 12:41 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-25 12:41 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 7132 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> It will be used by the update code later.
>
> No functional change intended, other than a trivial shell script
> refactoring.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> I kept release/live/default.nix using the UKI's systemd because the old
> code did it that way. Changing this would be better in a separate
> commit.
> ---
> host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
> host/rootfs/Makefile | 8 ++++----
> release/live/Makefile | 16 ++--------------
> release/live/default.nix | 27 +++++++++++----------------
> release/live/shell.nix | 10 ++++++++--
> 5 files changed, 65 insertions(+), 36 deletions(-)
Looking good. Just some style notes.
> diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
> index 5e3c9238f0e00f86aa5943212b8fc8fd896ce54a..aac915ffb2781aee0997c169e86e3fd1983aa3b3 100644
> --- a/host/rootfs/Makefile
> +++ b/host/rootfs/Makefile
> @@ -40,6 +40,10 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
>
> BUILD_FILES = build/etc/s6-rc
>
> +# This rule produces three files but Make only (portably)
> +# supports one output per rule. Instead of resorting to temporary
> +# files, a timestamp file is created as the last step. The actual
> +# outputs are produced as side-effects.
> build/verity-timestamp: $(ROOT_FS)
> $(VERITYSETUP) format \
> --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
> @@ -48,10 +52,6 @@ build/verity-timestamp: $(ROOT_FS)
> echo >> $(ROOT_FS_VERITY_ROOTHASH)
> touch -- $(ROOT_FS_DIR)/verity-timestamp
>
> -# This rule produces three files but Make only (portably)
> -# supports one output per rule. Instead of resorting to temporary
> -# files, a timestamp file is created as the last step. The actual
> -# outputs are produced as side-effects.
> $(ROOT_FS): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
> mkdir -p $(ROOT_FS_DIR) && \
> { \
> diff --git a/release/live/Makefile b/release/live/Makefile
> index 7372b41d94bfb10f7761955d9d1a246e9785b7f8..d61248e94599adc5229d0ad38d54b9f649d66ca1 100644
> --- a/release/live/Makefile
> +++ b/release/live/Makefile
> @@ -19,23 +19,11 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
> build/empty:
> mkdir -p $@
>
> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
> - { \
> - printf "[UKI]\nDeviceTreeAuto=" && \
> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
> - } | $(UKIFY) build \
> - --output $@ \
> - --config /dev/stdin \
> - --linux $(KERNEL) \
> - --initrd $(INITRAMFS) \
> - --os-release $$'NAME="Spectrum"\n' \
> - --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
> -
> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
I'd call "EFI_IMAGE" "SPECTRUM_EFI", so we aren't using two different
naming schemes for the two different EFI executables.
> $(TRUNCATE) -s 440401920 $@
> $(MKFS_FAT) $@
> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
> - $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
> + $(MCOPY) -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi
> $(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
>
> clean:
> diff --git a/release/live/default.nix b/release/live/default.nix
> index 7adaefef330daf11372cff0d2d04cca400efba1f..ac2d7a55fd4fe0c02108309ecea20e368000af0d 100644
> --- a/release/live/default.nix
> +++ b/release/live/default.nix
> @@ -3,10 +3,9 @@
> # SPDX-FileCopyrightText: 2022 Unikie
>
> import ../../lib/call-package.nix (
> -{ callSpectrumPackage, spectrum-build-tools, rootfs, src
> +{ callSpectrumPackage, spectrum-build-tools, src
> , lib, pkgsStatic, stdenvNoCC
> , cryptsetup, dosfstools, jq, mtools, util-linux
> -, systemdUkify
> }:
>
> let
> @@ -14,14 +13,12 @@ let
>
> stdenv = stdenvNoCC;
>
> - systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
> - # The default limit is too low to build a generic aarch64 distro image:
> - # https://github.com/systemd/systemd/pull/37417
> - mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
> - });
> -
> - initramfs = callSpectrumPackage ../../host/initramfs {};
> efiArch = stdenv.hostPlatform.efiArch;
> +
> + efi = callSpectrumPackage ../../host/efi.nix {};
> +
> + # The initramfs and rootfs must match those used to build the UKI.
> + inherit (efi) initramfs rootfs systemd;
> in
>
> stdenv.mkDerivation {
> @@ -40,17 +37,15 @@ stdenv.mkDerivation {
> sourceRoot = "source/release/live";
>
> nativeBuildInputs = [
> - cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
> + cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
> ];
>
> env = {
> - INITRAMFS = initramfs;
> - KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> - ROOT_FS_DIR = rootfs;
> + KERNEL = "${efi.rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> + ROOT_FS_DIR = "${efi.rootfs}";
Why inherit these from efi above if you're going to refer to them
through efi here anyway?
> SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
> + EFI_IMAGE = efi;
> EFINAME = "BOOT${toUpper efiArch}.EFI";
> - } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
> - DTBS = "${rootfs.kernel}/dtbs";
> };
>
> buildFlags = [ "dest=$(out)" ];
> @@ -63,6 +58,6 @@ stdenv.mkDerivation {
> unsafeDiscardReferences = { out = true; };
> dontFixup = true;
>
> - passthru = { inherit initramfs rootfs; };
> + passthru = { inherit efi initramfs rootfs; };
> }
> ) (_: {})
> diff --git a/release/live/shell.nix b/release/live/shell.nix
> index c5db7b732ef048b4c0cb87a4c5ea614e993db516..ffaa9a571c662810348822a5952d479d251a25e5 100644
> --- a/release/live/shell.nix
> +++ b/release/live/shell.nix
> @@ -1,7 +1,12 @@
> # SPDX-License-Identifier: MIT
> # SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
>
> -import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
> +import ../../lib/call-package.nix (
> +{ callSpectrumPackage, stdenv, qemu_kvm }:
This has reduced in length, so it doesn't need to be broken on to a
separate line.
> +
> +let
> + efi = callSpectrumPackage ../../host/efi.nix {};
> +in
>
> (callSpectrumPackage ./. {}).overrideAttrs (
> { nativeBuildInputs ? [], env ? {}, ... }:
> @@ -10,7 +15,8 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, root
>
> env = env // {
> OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
> - ROOT_FS_DIR = rootfs;
> + ROOT_FS_DIR = efi.rootfs;
> + EFI_IMAGE = efi;
> };
> }
> )) (_: {})
>
> --
> 2.52.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
` (2 preceding siblings ...)
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-26 18:58 ` Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
3 siblings, 2 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 18:58 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v5:
- Rebase
- Fix shell.nix files
- Link to v4: https://spectrum-os.org/lists/archives/spectrum-devel/20251119-refactor-verity-v4-0-9bc56d5216c0@gmail.com
Changes in v4:
- Many cleanups.
- Respond to suggestions from code review.
- Link to v3: https://spectrum-os.org/lists/archives/spectrum-devel/20251111-refactor-verity-v3-0-575726639f9e@gmail.com
Changes in v3:
- Rebase on main
- Link to v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251107-refactor-verity-v2-0-2af58b1a4a87@gmail.com
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/default.nix | 1 +
host/rootfs/Makefile | 44 ++++++++++++++++++++++----------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 39 +++++++--------------------------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 9 ++++++++-
10 files changed, 103 insertions(+), 95 deletions(-)
---
base-commit: c3d53b92c32636736c6585cd934210e29613e38e
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v5 1/2] Build verity images in rootfs Nix derivation
2025-11-26 18:58 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-26 18:58 ` Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
1 sibling, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 18:58 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes since v5:
- Use consistent naming scheme for Make variables: ROOT_FS is the
directory containing the artifacts. ROOT_FS_IMAGE is the root
filesystem image, ROOT_FS_VERITY is the verity image, and
ROOT_FS_VERITY_ROOTHASH is its root filesystem hash.
- Do not try to use a file as a directory.
- Use $@ where possible.
- Use consistent indentation.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/default.nix | 1 +
host/rootfs/Makefile | 44 ++++++++++++++++++++++----------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 26 +++++---------------------
release/live/shell.nix | 3 ++-
8 files changed, 44 insertions(+), 68 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..f27f5e07c4707914962197b4fea8f385729370aa 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/default.nix b/host/initramfs/default.nix
index d35e1b514ec48015f5110e65e5ae944b28244c4f..16c932600c0ab54cf439dc7931fc12e863677e0e 100644
--- a/host/initramfs/default.nix
+++ b/host/initramfs/default.nix
@@ -105,6 +105,7 @@ stdenvNoCC.mkDerivation {
env = {
PACKAGES_CPIO = packagesCpio;
+ ROOT_FS = rootfs;
} // lib.optionalAttrs stdenvNoCC.hostPlatform.isx86_64 {
MICROCODE = microcode;
};
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 4067be0c45cc83ce4670ed76e956db58f8e93e02..4cb048ac08b3265b0435d6ff6fc612a58c169ce9 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -1,12 +1,13 @@
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
.POSIX:
include ../../lib/common.mk
include file-list.mk
-dest = build/rootfs.erofs
+ROOT_FS = build
DIRS = \
dev \
@@ -40,8 +41,22 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
- set -euo pipefail; \
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+build/verity-timestamp: $(ROOT_FS_IMAGE)
+ $(VERITYSETUP) format \
+ --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
+ -- $(ROOT_FS_IMAGE) $(ROOT_FS_VERITY)
+# Add trailing newline so that the read < $(ROOT_FS_VERITY_ROOTHASH) succeeds.
+# Without the trailing newline it assumes a premature EOF happened and returns
+# a nonzero status.
+ echo >> $(ROOT_FS_VERITY_ROOTHASH)
+ touch -- $@
+
+$(ROOT_FS_IMAGE): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
+ mkdir -p $(ROOT_FS) && \
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
@@ -77,25 +92,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/verity-timestamp $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
debug:
@@ -126,7 +126,7 @@ run: build/live.img build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index f7974a41052468f9782214f32355dda97af3cd60..941c04e619baa7652d1812f4eb50445c607d5884 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -118,7 +118,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
@@ -127,7 +127,9 @@ stdenvNoCC.mkDerivation {
'';
};
- makeFlags = [ "dest=$(out)" ];
+ # The Makefile uses $(ROOT_FS), not $(dest), so it can share code
+ # with other Makefiles that also use this variable.
+ makeFlags = [ "ROOT_FS=$(out)" ];
dontInstall = true;
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..84091a8dfd615b2aaa021c7477f34c4dff88ccde 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -11,6 +11,10 @@ GDB = gdb
MCOPY = mcopy
MKFS_FAT = mkfs.fat
MMD = mmd
+ROOT_FS_IMAGE = $(ROOT_FS)/rootfs
+ROOT_FS_IMAGES = $(ROOT_FS_IMAGE) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
+ROOT_FS_VERITY = $(ROOT_FS)/rootfs.verity.superblock
+ROOT_FS_VERITY_ROOTHASH = $(ROOT_FS)/rootfs.verity.roothash
S6_IPCSERVER_SOCKETBINDER = s6-ipcserver-socketbinder
TAR = tar
TRUNCATE = truncate
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..ba81c7e679429e045b24c1591a9f0b72f016cfab 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 5acaa8c5b113fd2789aaea9268487b193bab37af..799d575b4f6e6f3dad8ac1a0a8bc2e3fc46aab44 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
+import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,6 +10,7 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
+ ROOT_FS = rootfs;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v5 2/2] Move UKI creation to a separate derivation
2025-11-26 18:58 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-26 18:58 ` Demi Marie Obenour
1 sibling, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 18:58 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
I kept release/live/default.nix using the UKI's systemd because the old
code did it that way. Changing this would be better in a separate
commit.
Changes since v5:
- Create a temporary symlink named build/spectrum.efi and then run
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
the file with its original name. The latter results in an unbootable
image. I do not know the reason.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
release/live/Makefile | 17 ++++-------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 10 ++++++++--
4 files changed, 63 insertions(+), 31 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..ecedb6bea6bf29c7a7303dc9062fe12b5c7a9fbd
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ callSpectrumPackage, cryptsetup, rootfs
+, runCommand, stdenv, systemdUkify
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit initramfs rootfs systemd; };
+} ''
+ read -r roothash < ${rootfs}/rootfs.verity.roothash
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d ${rootfs.kernel}/dtbs ]; then
+ find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux ${kernel} \
+ --initrd ${initramfs} \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/release/live/Makefile b/release/live/Makefile
index ba81c7e679429e045b24c1591a9f0b72f016cfab..b37ccce42feb3ac7e8ce4faf96a67902b55be808 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,22 +19,13 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
+# This symlink is necessary. Copying $(EFI_IMAGE) directly
+# results in an unbootable image. TODO: figure out why.
+ ln -s $(EFI_IMAGE) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..ba9bb17e697a6ecfe81e52a4ffbc375ef443b6f3 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -3,10 +3,9 @@
# SPDX-FileCopyrightText: 2022 Unikie
import ../../lib/call-package.nix (
-{ callSpectrumPackage, spectrum-build-tools, rootfs, src
+{ callSpectrumPackage, spectrum-build-tools, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
}:
let
@@ -14,14 +13,12 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
+
+ efi = callSpectrumPackage ../../host/efi.nix {};
+
+ # The initramfs and rootfs must match those used to build the UKI.
+ inherit (efi) initramfs rootfs systemd;
in
stdenv.mkDerivation {
@@ -40,17 +37,15 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
- KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ KERNEL = "${efi.rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ ROOT_FS = "${efi.rootfs}";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -63,6 +58,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit efi initramfs rootfs; };
}
) (_: {})
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 799d575b4f6e6f3dad8ac1a0a8bc2e3fc46aab44..b0bf957c085d1581a24d8916925611da0a60ec8b 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
+import ../../lib/call-package.nix (
+{ callSpectrumPackage, stdenv, qemu_kvm }:
+
+let
+ efi = callSpectrumPackage ../../host/efi.nix {};
+in
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,7 +15,8 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, root
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
- ROOT_FS = rootfs;
+ ROOT_FS = efi.rootfs;
+ EFI_IMAGE = efi;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-26 19:10 ` Demi Marie Obenour
2025-11-26 19:10 ` [PATCH v6 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2 siblings, 2 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 19:10 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
This doesn't have any functional change, other than to use the read
builtin instead of a cat command in a shell script. However, it does
make the code much cleaner and more reusable. For instance, one can
easily build just the verity image or just the UKI.
This will be used by the Nix code that generates an update package. The
update package needs the root filesystem, the verity superblock, and the
UKI. It doesn't need the installer or the live image.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes in v6:
- Rebase
- Fix shell.nix files
- Link to v5: https://spectrum-os.org/lists/archives/spectrum-devel/20251121-refactor-verity-v5-0-938fc95f9752@gmail.com
Changes in v5:
- Rebase
- Fix shell.nix files
- Link to v4: https://spectrum-os.org/lists/archives/spectrum-devel/20251119-refactor-verity-v4-0-9bc56d5216c0@gmail.com
Changes in v4:
- Many cleanups.
- Respond to suggestions from code review.
- Link to v3: https://spectrum-os.org/lists/archives/spectrum-devel/20251111-refactor-verity-v3-0-575726639f9e@gmail.com
Changes in v3:
- Rebase on main
- Link to v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251107-refactor-verity-v2-0-2af58b1a4a87@gmail.com
Changes in v2:
- Do not break interactive rootfs development.
- Link to v1: https://spectrum-os.org/lists/archives/spectrum-devel/20251105-refactor-verity-v1-0-b8ba27dfdf06@gmail.com
---
Demi Marie Obenour (2):
Build verity images in rootfs Nix derivation
Move UKI creation to a separate derivation
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/default.nix | 1 +
host/rootfs/Makefile | 44 ++++++++++++++++++++++----------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 39 +++++++--------------------------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 9 ++++++++-
10 files changed, 103 insertions(+), 95 deletions(-)
---
base-commit: c3d53b92c32636736c6585cd934210e29613e38e
change-id: 20251105-refactor-verity-9c8ca37e021a
--
Sincerely,
Demi Marie Obenour (she/her/hers)
^ permalink raw reply [flat|nested] 42+ messages in thread
* [PATCH v6 1/2] Build verity images in rootfs Nix derivation
2025-11-26 19:10 ` [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
@ 2025-11-26 19:10 ` Demi Marie Obenour
2025-11-27 19:23 ` Alyssa Ross
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
1 sibling, 1 reply; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 19:10 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
Avoid redundant rebuilds of the rootfs verity superblock and roothash.
Remove duplicate code. Clean up Makefile to avoid temporary files.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
Changes since v5:
- Use consistent naming scheme for Make variables: ROOT_FS is the
directory containing the artifacts. ROOT_FS_IMAGE is the root
filesystem image, ROOT_FS_VERITY is the verity image, and
ROOT_FS_VERITY_ROOTHASH is its root filesystem hash.
- Do not try to use a file as a directory.
- Use $@ where possible.
- Use consistent indentation.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/initramfs/Makefile | 26 +++++---------------------
host/initramfs/default.nix | 1 +
host/rootfs/Makefile | 44 ++++++++++++++++++++++----------------------
host/rootfs/default.nix | 6 ++++--
host/rootfs/shell.nix | 2 +-
lib/common.mk | 4 ++++
release/live/Makefile | 26 +++++---------------------
release/live/shell.nix | 3 ++-
8 files changed, 44 insertions(+), 68 deletions(-)
diff --git a/host/initramfs/Makefile b/host/initramfs/Makefile
index cb13fbb35f065b67d291d4a35591d6f12720060c..f27f5e07c4707914962197b4fea8f385729370aa 100644
--- a/host/initramfs/Makefile
+++ b/host/initramfs/Makefile
@@ -35,26 +35,10 @@ build/mountpoints:
cd build/mountpoints && mkdir -p $(MOUNTPOINTS)
find build/mountpoints -mindepth 1 -exec touch -d @0 {} ';'
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/loop.tar: build/live.img
@@ -69,12 +53,12 @@ clean:
rm -rf build
.PHONY: clean
-run: $(dest) build/rootfs.verity.roothash $(RUN_IMAGE)
+run: $(dest) $(RUN_IMAGE) $(ROOT_FS_VERITY_ROOTHASH)
@../../scripts/run-qemu.sh -m 4G \
-machine virtualization=on \
-kernel $(KERNEL) \
-initrd $(dest) \
- -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< build/rootfs.verity.roothash) nokaslr" \
+ -append "ro earlycon console=hvc0 intel_iommu=on roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) nokaslr" \
-cpu max \
-gdb unix:build/gdb.sock,server,nowait \
-parallel none \
diff --git a/host/initramfs/default.nix b/host/initramfs/default.nix
index d35e1b514ec48015f5110e65e5ae944b28244c4f..16c932600c0ab54cf439dc7931fc12e863677e0e 100644
--- a/host/initramfs/default.nix
+++ b/host/initramfs/default.nix
@@ -105,6 +105,7 @@ stdenvNoCC.mkDerivation {
env = {
PACKAGES_CPIO = packagesCpio;
+ ROOT_FS = rootfs;
} // lib.optionalAttrs stdenvNoCC.hostPlatform.isx86_64 {
MICROCODE = microcode;
};
diff --git a/host/rootfs/Makefile b/host/rootfs/Makefile
index 4067be0c45cc83ce4670ed76e956db58f8e93e02..4cb048ac08b3265b0435d6ff6fc612a58c169ce9 100644
--- a/host/rootfs/Makefile
+++ b/host/rootfs/Makefile
@@ -1,12 +1,13 @@
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
.POSIX:
include ../../lib/common.mk
include file-list.mk
-dest = build/rootfs.erofs
+ROOT_FS = build
DIRS = \
dev \
@@ -40,8 +41,22 @@ FIFOS = etc/s6-linux-init/run-image/service/s6-svscan-log/fifo
BUILD_FILES = build/etc/s6-rc
-$(dest): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
- set -euo pipefail; \
+# This rule produces three files but Make only (portably)
+# supports one output per rule. Instead of resorting to temporary
+# files, a timestamp file is created as the last step. The actual
+# outputs are produced as side-effects.
+build/verity-timestamp: $(ROOT_FS_IMAGE)
+ $(VERITYSETUP) format \
+ --root-hash-file $(ROOT_FS_VERITY_ROOTHASH) \
+ -- $(ROOT_FS_IMAGE) $(ROOT_FS_VERITY)
+# Add trailing newline so that the read < $(ROOT_FS_VERITY_ROOTHASH) succeeds.
+# Without the trailing newline it assumes a premature EOF happened and returns
+# a nonzero status.
+ echo >> $(ROOT_FS_VERITY_ROOTHASH)
+ touch -- $@
+
+$(ROOT_FS_IMAGE): ../../scripts/make-erofs.sh $(PACKAGES_FILE) $(FILES) $(BUILD_FILES) build/empty build/fifo file-list.mk
+ mkdir -p $(ROOT_FS) && \
{ \
cat $(PACKAGES_FILE) ;\
for file in $(FILES) $(LINKS); do printf '%s\n%s\n' $$file "$${file#image/}"; done ;\
@@ -77,25 +92,10 @@ clean:
rm -rf build
.PHONY: clean
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(dest)
- $(VERITYSETUP) format $(dest) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
-build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/rootfs.verity.superblock build/rootfs.verity.roothash $(dest)
+build/live.img: ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/verity-timestamp $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(dest):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
debug:
@@ -126,7 +126,7 @@ run: build/live.img build/rootfs.verity.roothash
-device virtconsole,chardev=virtiocon0 \
-drive file=build/live.img,if=virtio,format=raw,readonly=on \
-drive file=/proc/self/fd/3,if=virtio,format=raw \
- -append "earlycon console=hvc0 roothash=$$(< build/rootfs.verity.roothash) intel_iommu=on nokaslr" \
+ -append "earlycon console=hvc0 roothash=$$(< $(ROOT_FS_VERITY_ROOTHASH)) intel_iommu=on nokaslr" \
-device virtio-keyboard \
-device virtio-mouse \
-device virtio-gpu \
diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index f7974a41052468f9782214f32355dda97af3cd60..941c04e619baa7652d1812f4eb50445c607d5884 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -118,7 +118,7 @@ stdenvNoCC.mkDerivation {
};
sourceRoot = "source/host/rootfs";
- nativeBuildInputs = [ erofs-utils spectrum-build-tools s6-rc ];
+ nativeBuildInputs = [ cryptsetup erofs-utils spectrum-build-tools s6-rc ];
env = {
PACKAGES = runCommand "packages" {} ''
@@ -127,7 +127,9 @@ stdenvNoCC.mkDerivation {
'';
};
- makeFlags = [ "dest=$(out)" ];
+ # The Makefile uses $(ROOT_FS), not $(dest), so it can share code
+ # with other Makefiles that also use this variable.
+ makeFlags = [ "ROOT_FS=$(out)" ];
dontInstall = true;
diff --git a/host/rootfs/shell.nix b/host/rootfs/shell.nix
index 1bf61bebf418333624e799cc8ca231f5783206f4..6df2f575fdfc7cdf8067ccfdb5fecaad9f6ea5e6 100644
--- a/host/rootfs/shell.nix
+++ b/host/rootfs/shell.nix
@@ -12,7 +12,7 @@ rootfs.overrideAttrs (
{
nativeBuildInputs = nativeBuildInputs ++ [
- btrfs-progs cryptsetup jq netcat qemu_kvm reuse util-linux
+ btrfs-progs jq netcat qemu_kvm reuse util-linux
];
env = env // {
diff --git a/lib/common.mk b/lib/common.mk
index 277c3544036d9a9057f8ba4ad37fe2207548cc59..84091a8dfd615b2aaa021c7477f34c4dff88ccde 100644
--- a/lib/common.mk
+++ b/lib/common.mk
@@ -11,6 +11,10 @@ GDB = gdb
MCOPY = mcopy
MKFS_FAT = mkfs.fat
MMD = mmd
+ROOT_FS_IMAGE = $(ROOT_FS)/rootfs
+ROOT_FS_IMAGES = $(ROOT_FS_IMAGE) $(ROOT_FS_VERITY_ROOTHASH) $(ROOT_FS_VERITY)
+ROOT_FS_VERITY = $(ROOT_FS)/rootfs.verity.superblock
+ROOT_FS_VERITY_ROOTHASH = $(ROOT_FS)/rootfs.verity.roothash
S6_IPCSERVER_SOCKETBINDER = s6-ipcserver-socketbinder
TAR = tar
TRUNCATE = truncate
diff --git a/release/live/Makefile b/release/live/Makefile
index 6dcbdeedda5d6ccf293f60dc62043f46c81ecf83..ba81c7e679429e045b24c1591a9f0b72f016cfab 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -9,17 +9,17 @@ DTBS ?= build/empty
dest = build/live.img
-$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat build/rootfs.verity.superblock build/rootfs.verity.roothash $(ROOT_FS)
+$(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sfdisk-field.awk build/boot.fat $(ROOT_FS_IMAGES)
../../scripts/make-gpt.sh $@.tmp \
build/boot.fat:c12a7328-f81f-11d2-ba4b-00a0c93ec93b \
- build/rootfs.verity.superblock:verity:$$(../../scripts/format-uuid.sh "$$(dd if=build/rootfs.verity.roothash bs=32 skip=1 count=1 status=none)") \
- $(ROOT_FS):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 build/rootfs.verity.roothash)")
+ $(ROOT_FS_VERITY):verity:$$(../../scripts/format-uuid.sh "$$(dd if=$(ROOT_FS_VERITY_ROOTHASH) bs=32 skip=1 count=1 status=none)") \
+ $(ROOT_FS_IMAGE):root:$$(../../scripts/format-uuid.sh "$$(head -c 32 $(ROOT_FS_VERITY_ROOTHASH))")
mv $@.tmp $@
build/empty:
mkdir -p $@
-build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
+build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
{ \
printf "[UKI]\nDeviceTreeAuto=" && \
find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
@@ -29,7 +29,7 @@ build/spectrum.efi: build/rootfs.verity.roothash $(DTBS) $(KERNEL) $(INITRAMFS)
--linux $(KERNEL) \
--initrd $(INITRAMFS) \
--os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat build/rootfs.verity.roothash)"
+ --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(TRUNCATE) -s 440401920 $@
@@ -38,22 +38,6 @@ build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
-# veritysetup format produces two files, but Make only (portably)
-# supports one output per rule, so we combine the two outputs then
-# define two more rules to separate them again.
-build/rootfs.verity: $(ROOT_FS)
- mkdir -p build
- $(VERITYSETUP) format $(ROOT_FS) build/rootfs.verity.superblock.tmp \
- | awk -F ':[[:blank:]]*' '$$1 == "Root hash" {print $$2; exit}' \
- > build/rootfs.verity.roothash.tmp
- cat build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp \
- > $@
- rm build/rootfs.verity.roothash.tmp build/rootfs.verity.superblock.tmp
-build/rootfs.verity.roothash: build/rootfs.verity
- head -n 1 build/rootfs.verity > $@
-build/rootfs.verity.superblock: build/rootfs.verity
- tail -n +2 build/rootfs.verity > $@
-
clean:
rm -rf build
.PHONY: clean
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 5acaa8c5b113fd2789aaea9268487b193bab37af..799d575b4f6e6f3dad8ac1a0a8bc2e3fc46aab44 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
+import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,6 +10,7 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm }:
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
+ ROOT_FS = rootfs;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-26 19:10 ` [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-26 19:10 ` [PATCH v6 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-26 19:10 ` Demi Marie Obenour
2025-11-28 10:47 ` Alyssa Ross
` (2 more replies)
1 sibling, 3 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-26 19:10 UTC (permalink / raw)
To: Spectrum OS Development; +Cc: Demi Marie Obenour, Alyssa Ross
It will be used by the update code later.
No functional change intended, other than a trivial shell script
refactoring.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
I kept release/live/default.nix using the UKI's systemd because the old
code did it that way. Changing this would be better in a separate
commit.
Changes since v5:
- Create a temporary symlink named build/spectrum.efi and then run
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
the file with its original name. The latter results in an unbootable
image. I do not know the reason.
Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
release/live/Makefile | 17 ++++-------------
release/live/default.nix | 27 +++++++++++----------------
release/live/shell.nix | 10 ++++++++--
4 files changed, 63 insertions(+), 31 deletions(-)
diff --git a/host/efi.nix b/host/efi.nix
new file mode 100644
index 0000000000000000000000000000000000000000..ecedb6bea6bf29c7a7303dc9062fe12b5c7a9fbd
--- /dev/null
+++ b/host/efi.nix
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: MIT
+# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
+
+import ../lib/call-package.nix (
+{ callSpectrumPackage, cryptsetup, rootfs
+, runCommand, stdenv, systemdUkify
+}:
+let
+ initramfs = callSpectrumPackage ./initramfs {};
+ kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
+ # The default limit is too low to build a generic aarch64 distro image:
+ # https://github.com/systemd/systemd/pull/37417
+ mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
+ });
+in
+
+runCommand "spectrum-efi" {
+ nativeBuildInputs = [ cryptsetup systemd ];
+ __structuredAttrs = true;
+ unsafeDiscardReferences = { out = true; };
+ dontFixup = true;
+ passthru = { inherit initramfs rootfs systemd; };
+} ''
+ read -r roothash < ${rootfs}/rootfs.verity.roothash
+ { \
+ printf "[UKI]\nDeviceTreeAuto="
+ if [ -d ${rootfs.kernel}/dtbs ]; then
+ find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
+ fi
+ } | ukify build \
+ --output "$out" \
+ --config /dev/stdin \
+ --linux ${kernel} \
+ --initrd ${initramfs} \
+ --os-release $'NAME="Spectrum"\n' \
+ --cmdline "ro intel_iommu=on roothash=$roothash"
+ ''
+) (_: {})
diff --git a/release/live/Makefile b/release/live/Makefile
index ba81c7e679429e045b24c1591a9f0b72f016cfab..b37ccce42feb3ac7e8ce4faf96a67902b55be808 100644
--- a/release/live/Makefile
+++ b/release/live/Makefile
@@ -19,22 +19,13 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
build/empty:
mkdir -p $@
-build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
- { \
- printf "[UKI]\nDeviceTreeAuto=" && \
- find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
- } | $(UKIFY) build \
- --output $@ \
- --config /dev/stdin \
- --linux $(KERNEL) \
- --initrd $(INITRAMFS) \
- --os-release $$'NAME="Spectrum"\n' \
- --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
-
-build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
+build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
$(TRUNCATE) -s 440401920 $@
$(MKFS_FAT) $@
$(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
+# This symlink is necessary. Copying $(EFI_IMAGE) directly
+# results in an unbootable image. TODO: figure out why.
+ ln -s $(EFI_IMAGE) build/spectrum.efi
$(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
$(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
diff --git a/release/live/default.nix b/release/live/default.nix
index 2a1dc3e1dd939f21edac582bf39737eb4d46eb0c..ba9bb17e697a6ecfe81e52a4ffbc375ef443b6f3 100644
--- a/release/live/default.nix
+++ b/release/live/default.nix
@@ -3,10 +3,9 @@
# SPDX-FileCopyrightText: 2022 Unikie
import ../../lib/call-package.nix (
-{ callSpectrumPackage, spectrum-build-tools, rootfs, src
+{ callSpectrumPackage, spectrum-build-tools, src
, lib, pkgsStatic, stdenvNoCC
, cryptsetup, dosfstools, jq, mtools, util-linux
-, systemdUkify
}:
let
@@ -14,14 +13,12 @@ let
stdenv = stdenvNoCC;
- systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
- # The default limit is too low to build a generic aarch64 distro image:
- # https://github.com/systemd/systemd/pull/37417
- mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
- });
-
- initramfs = callSpectrumPackage ../../host/initramfs {};
efiArch = stdenv.hostPlatform.efiArch;
+
+ efi = callSpectrumPackage ../../host/efi.nix {};
+
+ # The initramfs and rootfs must match those used to build the UKI.
+ inherit (efi) initramfs rootfs systemd;
in
stdenv.mkDerivation {
@@ -40,17 +37,15 @@ stdenv.mkDerivation {
sourceRoot = "source/release/live";
nativeBuildInputs = [
- cryptsetup dosfstools jq spectrum-build-tools mtools systemd util-linux
+ cryptsetup dosfstools jq spectrum-build-tools mtools util-linux
];
env = {
- INITRAMFS = initramfs;
- KERNEL = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
- ROOT_FS = rootfs;
+ KERNEL = "${efi.rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
+ ROOT_FS = "${efi.rootfs}";
SYSTEMD_BOOT_EFI = "${systemd}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi";
+ EFI_IMAGE = efi;
EFINAME = "BOOT${toUpper efiArch}.EFI";
- } // lib.optionalAttrs stdenv.hostPlatform.linux-kernel.DTB or false {
- DTBS = "${rootfs.kernel}/dtbs";
};
buildFlags = [ "dest=$(out)" ];
@@ -63,6 +58,6 @@ stdenv.mkDerivation {
unsafeDiscardReferences = { out = true; };
dontFixup = true;
- passthru = { inherit initramfs rootfs; };
+ passthru = { inherit efi initramfs rootfs; };
}
) (_: {})
diff --git a/release/live/shell.nix b/release/live/shell.nix
index 799d575b4f6e6f3dad8ac1a0a8bc2e3fc46aab44..b0bf957c085d1581a24d8916925611da0a60ec8b 100644
--- a/release/live/shell.nix
+++ b/release/live/shell.nix
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
-import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, rootfs }:
+import ../../lib/call-package.nix (
+{ callSpectrumPackage, stdenv, qemu_kvm }:
+
+let
+ efi = callSpectrumPackage ../../host/efi.nix {};
+in
(callSpectrumPackage ./. {}).overrideAttrs (
{ nativeBuildInputs ? [], env ? {}, ... }:
@@ -10,7 +15,8 @@ import ../../lib/call-package.nix ({ callSpectrumPackage, stdenv, qemu_kvm, root
env = env // {
OVMF_CODE = "${qemu_kvm}/share/qemu/edk2-${stdenv.hostPlatform.qemuArch}-code.fd";
- ROOT_FS = rootfs;
+ ROOT_FS = efi.rootfs;
+ EFI_IMAGE = efi;
};
}
)) (_: {})
--
2.52.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [PATCH v6 1/2] Build verity images in rootfs Nix derivation
2025-11-26 19:10 ` [PATCH v6 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
@ 2025-11-27 19:23 ` Alyssa Ross
0 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-27 19:23 UTC (permalink / raw)
To: Demi Marie Obenour, Spectrum OS Development
Cc: Demi Marie Obenour, Alyssa Ross
This patch has been committed as 96f4b9798d5069f6b502915270293dcaf0c6ad8c,
which can be viewed online at
https://spectrum-os.org/git/spectrum/commit/?id=96f4b9798d5069f6b502915270293dcaf0c6ad8c.
This is an automated message. Send comments/questions/requests to:
Alyssa Ross <hi@alyssa.is>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
@ 2025-11-28 10:47 ` Alyssa Ross
2025-11-28 19:27 ` Demi Marie Obenour
2025-11-28 11:02 ` Alyssa Ross
2025-11-28 20:12 ` Alyssa Ross
2 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-28 10:47 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 1266 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> It will be used by the update code later.
>
> No functional change intended, other than a trivial shell script
> refactoring.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> I kept release/live/default.nix using the UKI's systemd because the old
> code did it that way. Changing this would be better in a separate
> commit.
Yep, makes sense.
> Changes since v5:
>
> - Create a temporary symlink named build/spectrum.efi and then run
> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
> the file with its original name. The latter results in an unbootable
> image. I do not know the reason.
If I just mcopy -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi (explicitly
specifying the destination file name), then it works. It doesn't is something like
"/nix/store/3yqb8mfv6skp43yp2r7sn098zrj0hrjf-spectrum-efi".
This could be avoided by installing EFI_IMAGE to a subdirectory, so the
file name didn't get a hash prepended to it by Nix. Happy to just go
ahead with changing this and applying my style comments from last
time[1] if you agree.
[1]: https://spectrum-os.org/lists/archives/spectrum-devel/877bve2skh.fsf@alyssa.is/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-28 10:47 ` Alyssa Ross
@ 2025-11-28 11:02 ` Alyssa Ross
2025-11-28 19:25 ` Demi Marie Obenour
2025-11-28 20:12 ` Alyssa Ross
2 siblings, 1 reply; 42+ messages in thread
From: Alyssa Ross @ 2025-11-28 11:02 UTC (permalink / raw)
To: Demi Marie Obenour; +Cc: Spectrum OS Development
[-- Attachment #1: Type: text/plain, Size: 4303 bytes --]
Demi Marie Obenour <demiobenour@gmail.com> writes:
> It will be used by the update code later.
>
> No functional change intended, other than a trivial shell script
> refactoring.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> I kept release/live/default.nix using the UKI's systemd because the old
> code did it that way. Changing this would be better in a separate
> commit.
>
> Changes since v5:
>
> - Create a temporary symlink named build/spectrum.efi and then run
> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
> the file with its original name. The latter results in an unbootable
> image. I do not know the reason.
>
> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
> ---
> host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
> release/live/Makefile | 17 ++++-------------
> release/live/default.nix | 27 +++++++++++----------------
> release/live/shell.nix | 10 ++++++++--
> 4 files changed, 63 insertions(+), 31 deletions(-)
>
> diff --git a/host/efi.nix b/host/efi.nix
> new file mode 100644
> index 0000000000000000000000000000000000000000..ecedb6bea6bf29c7a7303dc9062fe12b5c7a9fbd
> --- /dev/null
> +++ b/host/efi.nix
> @@ -0,0 +1,40 @@
> +# SPDX-License-Identifier: MIT
> +# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
> +
> +import ../lib/call-package.nix (
> +{ callSpectrumPackage, cryptsetup, rootfs
> +, runCommand, stdenv, systemdUkify
> +}:
> +let
> + initramfs = callSpectrumPackage ./initramfs {};
> + kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
> + systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
> + # The default limit is too low to build a generic aarch64 distro image:
> + # https://github.com/systemd/systemd/pull/37417
> + mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
> + });
> +in
> +
> +runCommand "spectrum-efi" {
> + nativeBuildInputs = [ cryptsetup systemd ];
> + __structuredAttrs = true;
> + unsafeDiscardReferences = { out = true; };
> + dontFixup = true;
> + passthru = { inherit initramfs rootfs systemd; };
> +} ''
> + read -r roothash < ${rootfs}/rootfs.verity.roothash
> + { \
> + printf "[UKI]\nDeviceTreeAuto="
> + if [ -d ${rootfs.kernel}/dtbs ]; then
> + find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
> + fi
> + } | ukify build \
> + --output "$out" \
> + --config /dev/stdin \
> + --linux ${kernel} \
> + --initrd ${initramfs} \
> + --os-release $'NAME="Spectrum"\n' \
> + --cmdline "ro intel_iommu=on roothash=$roothash"
> + ''
> +) (_: {})
> diff --git a/release/live/Makefile b/release/live/Makefile
> index ba81c7e679429e045b24c1591a9f0b72f016cfab..b37ccce42feb3ac7e8ce4faf96a67902b55be808 100644
> --- a/release/live/Makefile
> +++ b/release/live/Makefile
> @@ -19,22 +19,13 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
> build/empty:
> mkdir -p $@
>
> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
> - { \
> - printf "[UKI]\nDeviceTreeAuto=" && \
> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
> - } | $(UKIFY) build \
> - --output $@ \
> - --config /dev/stdin \
> - --linux $(KERNEL) \
> - --initrd $(INITRAMFS) \
> - --os-release $$'NAME="Spectrum"\n' \
> - --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
> -
> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
Why add a build/empty dependency? It doesn't seem to be used for
anything any more? (Neither does the DTBS variable, actually.)
> $(TRUNCATE) -s 440401920 $@
> $(MKFS_FAT) $@
> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
> +# This symlink is necessary. Copying $(EFI_IMAGE) directly
> +# results in an unbootable image. TODO: figure out why.
> + ln -s $(EFI_IMAGE) build/spectrum.efi
> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
> $(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 227 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-28 11:02 ` Alyssa Ross
@ 2025-11-28 19:25 ` Demi Marie Obenour
0 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-28 19:25 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 4612 bytes --]
On 11/28/25 06:02, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> It will be used by the update code later.
>>
>> No functional change intended, other than a trivial shell script
>> refactoring.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> I kept release/live/default.nix using the UKI's systemd because the old
>> code did it that way. Changing this would be better in a separate
>> commit.
>>
>> Changes since v5:
>>
>> - Create a temporary symlink named build/spectrum.efi and then run
>> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
>> the file with its original name. The latter results in an unbootable
>> image. I do not know the reason.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> host/efi.nix | 40 ++++++++++++++++++++++++++++++++++++++++
>> release/live/Makefile | 17 ++++-------------
>> release/live/default.nix | 27 +++++++++++----------------
>> release/live/shell.nix | 10 ++++++++--
>> 4 files changed, 63 insertions(+), 31 deletions(-)
>>
>> diff --git a/host/efi.nix b/host/efi.nix
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..ecedb6bea6bf29c7a7303dc9062fe12b5c7a9fbd
>> --- /dev/null
>> +++ b/host/efi.nix
>> @@ -0,0 +1,40 @@
>> +# SPDX-License-Identifier: MIT
>> +# SPDX-FileCopyrightText: 2021-2024 Alyssa Ross <hi@alyssa.is>
>> +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>
>> +
>> +import ../lib/call-package.nix (
>> +{ callSpectrumPackage, cryptsetup, rootfs
>> +, runCommand, stdenv, systemdUkify
>> +}:
>> +let
>> + initramfs = callSpectrumPackage ./initramfs {};
>> + kernel = "${rootfs.kernel}/${stdenv.hostPlatform.linux-kernel.target}";
>> + systemd = systemdUkify.overrideAttrs ({ mesonFlags ? [], ... }: {
>> + # The default limit is too low to build a generic aarch64 distro image:
>> + # https://github.com/systemd/systemd/pull/37417
>> + mesonFlags = mesonFlags ++ [ "-Defi-stub-extra-sections=3000" ];
>> + });
>> +in
>> +
>> +runCommand "spectrum-efi" {
>> + nativeBuildInputs = [ cryptsetup systemd ];
>> + __structuredAttrs = true;
>> + unsafeDiscardReferences = { out = true; };
>> + dontFixup = true;
>> + passthru = { inherit initramfs rootfs systemd; };
>> +} ''
>> + read -r roothash < ${rootfs}/rootfs.verity.roothash
>> + { \
>> + printf "[UKI]\nDeviceTreeAuto="
>> + if [ -d ${rootfs.kernel}/dtbs ]; then
>> + find ${rootfs.kernel}/dtbs -name '*.dtb' -print0 | tr '\0' ' '
>> + fi
>> + } | ukify build \
>> + --output "$out" \
>> + --config /dev/stdin \
>> + --linux ${kernel} \
>> + --initrd ${initramfs} \
>> + --os-release $'NAME="Spectrum"\n' \
>> + --cmdline "ro intel_iommu=on roothash=$roothash"
>> + ''
>> +) (_: {})
>> diff --git a/release/live/Makefile b/release/live/Makefile
>> index ba81c7e679429e045b24c1591a9f0b72f016cfab..b37ccce42feb3ac7e8ce4faf96a67902b55be808 100644
>> --- a/release/live/Makefile
>> +++ b/release/live/Makefile
>> @@ -19,22 +19,13 @@ $(dest): ../../scripts/format-uuid.sh ../../scripts/make-gpt.sh ../../scripts/sf
>> build/empty:
>> mkdir -p $@
>>
>> -build/spectrum.efi: $(DTBS) $(KERNEL) $(INITRAMFS) $(ROOT_FS_VERITY_ROOTHASH)
>> - { \
>> - printf "[UKI]\nDeviceTreeAuto=" && \
>> - find $(DTBS) -name '*.dtb' -print0 | tr '\0' ' ' ;\
>> - } | $(UKIFY) build \
>> - --output $@ \
>> - --config /dev/stdin \
>> - --linux $(KERNEL) \
>> - --initrd $(INITRAMFS) \
>> - --os-release $$'NAME="Spectrum"\n' \
>> - --cmdline "ro intel_iommu=on roothash=$$(cat $(ROOT_FS_VERITY_ROOTHASH))"
>> -
>> -build/boot.fat: $(SYSTEMD_BOOT_EFI) build/spectrum.efi
>> +build/boot.fat: $(SYSTEMD_BOOT_EFI) $(EFI_IMAGE) build/empty
>
> Why add a build/empty dependency? It doesn't seem to be used for
> anything any more? (Neither does the DTBS variable, actually.)
The temporary symlink bodge below. build/empty isn't needed, but
build is. DTBS can just be deleted.
>> $(TRUNCATE) -s 440401920 $@
>> $(MKFS_FAT) $@
>> $(MMD) -i $@ ::/EFI ::/EFI/BOOT ::/EFI/Linux
>> +# This symlink is necessary. Copying $(EFI_IMAGE) directly
>> +# results in an unbootable image. TODO: figure out why.
>> + ln -s $(EFI_IMAGE) build/spectrum.efi
>> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux
>> $(MCOPY) -i $@ $(SYSTEMD_BOOT_EFI) ::/EFI/BOOT/$(EFINAME)
>>
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-28 10:47 ` Alyssa Ross
@ 2025-11-28 19:27 ` Demi Marie Obenour
0 siblings, 0 replies; 42+ messages in thread
From: Demi Marie Obenour @ 2025-11-28 19:27 UTC (permalink / raw)
To: Alyssa Ross; +Cc: Spectrum OS Development
[-- Attachment #1.1.1: Type: text/plain, Size: 1597 bytes --]
On 11/28/25 05:47, Alyssa Ross wrote:
> Demi Marie Obenour <demiobenour@gmail.com> writes:
>
>> It will be used by the update code later.
>>
>> No functional change intended, other than a trivial shell script
>> refactoring.
>>
>> Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
>> ---
>> I kept release/live/default.nix using the UKI's systemd because the old
>> code did it that way. Changing this would be better in a separate
>> commit.
>
> Yep, makes sense.
>
>> Changes since v5:
>>
>> - Create a temporary symlink named build/spectrum.efi and then run
>> $(MCOPY) -i $@ build/spectrum.efi ::/EFI/Linux, rather than copying
>> the file with its original name. The latter results in an unbootable
>> image. I do not know the reason.
>
> If I just mcopy -i $@ $(EFI_IMAGE) ::/EFI/Linux/spectrum.efi (explicitly
> specifying the destination file name), then it works. It doesn't is something like
> "/nix/store/3yqb8mfv6skp43yp2r7sn098zrj0hrjf-spectrum-efi".
I distinctly remember it *not* working for me, but I might have used the wrong
destination name. Perhaps I used Spectrum.efi (wrong case)?
> This could be avoided by installing EFI_IMAGE to a subdirectory, so the
> file name didn't get a hash prepended to it by Nix. Happy to just go
> ahead with changing this and applying my style comments from last
> time[1] if you agree.
>
> [1]: https://spectrum-os.org/lists/archives/spectrum-devel/877bve2skh.fsf@alyssa.is/
That would be great and an even better solution.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [PATCH v6 2/2] Move UKI creation to a separate derivation
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-28 10:47 ` Alyssa Ross
2025-11-28 11:02 ` Alyssa Ross
@ 2025-11-28 20:12 ` Alyssa Ross
2 siblings, 0 replies; 42+ messages in thread
From: Alyssa Ross @ 2025-11-28 20:12 UTC (permalink / raw)
To: Demi Marie Obenour, Spectrum OS Development
Cc: Demi Marie Obenour, Alyssa Ross
This patch has been committed as a11ec96aba792c573f670de6ec207a5eea4b0bbd,
which can be viewed online at
https://spectrum-os.org/git/spectrum/commit/?id=a11ec96aba792c573f670de6ec207a5eea4b0bbd.
This is an automated message. Send comments/questions/requests to:
Alyssa Ross <hi@alyssa.is>
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2025-11-28 20:12 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-05 22:33 [PATCH 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-05 22:33 ` [PATCH 1/2] Create Nix derivation for building verity images Demi Marie Obenour
2025-11-06 10:20 ` Alyssa Ross
2025-11-06 10:55 ` Demi Marie Obenour
2025-11-06 11:44 ` Alyssa Ross
2025-11-07 19:24 ` Demi Marie Obenour
2025-11-13 11:32 ` Alyssa Ross
2025-11-05 22:33 ` [PATCH 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-08 4:47 ` [PATCH v2 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-12 0:59 ` [PATCH v3 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-13 11:46 ` Alyssa Ross
2025-11-13 22:33 ` Demi Marie Obenour
2025-11-14 11:53 ` Alyssa Ross
2025-11-12 0:59 ` [PATCH v3 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-13 11:57 ` Alyssa Ross
2025-11-13 22:42 ` Demi Marie Obenour
2025-11-14 11:58 ` Alyssa Ross
2025-11-19 8:15 ` [PATCH v4 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-19 8:15 ` [PATCH v4 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-25 12:27 ` Alyssa Ross
2025-11-25 12:31 ` Alyssa Ross
2025-11-19 8:15 ` [PATCH v4 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-22 1:21 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-25 12:34 ` Alyssa Ross
2025-11-22 1:21 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-25 12:41 ` Alyssa Ross
2025-11-26 19:10 ` [PATCH v6 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-26 19:10 ` [PATCH v6 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-27 19:23 ` Alyssa Ross
2025-11-26 19:10 ` [PATCH v6 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
2025-11-28 10:47 ` Alyssa Ross
2025-11-28 19:27 ` Demi Marie Obenour
2025-11-28 11:02 ` Alyssa Ross
2025-11-28 19:25 ` Demi Marie Obenour
2025-11-28 20:12 ` Alyssa Ross
2025-11-26 18:58 ` [PATCH v5 0/2] Move verity and EFI creation to separate Nix derivations Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 1/2] Build verity images in rootfs Nix derivation Demi Marie Obenour
2025-11-26 18:58 ` [PATCH v5 2/2] Move UKI creation to a separate derivation Demi Marie Obenour
Code repositories for project(s) associated with this public inbox
https://spectrum-os.org/git/crosvm
https://spectrum-os.org/git/doc
https://spectrum-os.org/git/mktuntap
https://spectrum-os.org/git/nixpkgs
https://spectrum-os.org/git/spectrum
https://spectrum-os.org/git/ucspi-vsock
https://spectrum-os.org/git/www
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).