summary refs log tree commit diff
path: root/host/initramfs/scripts/make-gpt.sh
diff options
context:
space:
mode:
Diffstat (limited to 'host/initramfs/scripts/make-gpt.sh')
-rwxr-xr-xhost/initramfs/scripts/make-gpt.sh59
1 files changed, 59 insertions, 0 deletions
diff --git a/host/initramfs/scripts/make-gpt.sh b/host/initramfs/scripts/make-gpt.sh
new file mode 100755
index 0000000..6097d04
--- /dev/null
+++ b/host/initramfs/scripts/make-gpt.sh
@@ -0,0 +1,59 @@
+#!/bin/sh -eu
+#
+# SPDX-FileCopyrightText: 2021-2022 Alyssa Ross <hi@alyssa.is>
+# SPDX-License-Identifier: EUPL-1.2
+#
+# usage: make-gpt.sh GPT_PATH PATH:PARTTYPE[:PARTUUID]...
+
+ONE_MiB=1048576
+TWO_MiB=2097152
+
+# Prints the number of 1MiB blocks required to store the file named
+# $1.  We use 1MiB blocks because that's what sfdisk uses for
+# alignment.  It would be possible to get a slightly smaller image
+# using actual normal-sized 512-byte blocks, but it's probably not
+# worth it to configure sfdisk to do that.
+sizeMiB() {
+	wc -c "$1" | awk -v ONE_MiB=$ONE_MiB \
+		'{printf "%d\n", ($1 + ONE_MiB - 1) / ONE_MiB}'
+}
+
+# Copies from path $3 into partition number $2 in partition table $1.
+fillPartition() {
+	sfdisk -J "$1" | jq -r --argjson index "$2" \
+		'.partitiontable.partitions[$index] | "\(.start) \(.size)"' |
+		(read start size;
+		 dd if="$3" of="$1" seek="$start" count="$size" conv=notrunc)
+}
+
+# Prints the partition path from a PATH:PARTTYPE[:PARTUUID] string.
+partitionPath() {
+	awk -F: '{print $1}' <<EOF
+$1
+EOF
+}
+
+out="$1"
+shift
+
+nl=$'\n'
+table="label: gpt"
+
+# Keep 1MiB free at the start, and 1MiB free at the end.
+gptBytes=$TWO_MiB
+for partition; do
+	sizeMiB="$(sizeMiB "$(partitionPath "$partition")")"
+	table="$table${nl}size=${sizeMiB}MiB,$(awk -f scripts/sfdisk-field.awk -v partition="$partition")"
+	gptBytes="$(expr "$gptBytes" + "$sizeMiB" \* $ONE_MiB)"
+done
+
+truncate -s "$gptBytes" "$out"
+sfdisk "$out" <<EOF
+$table
+EOF
+
+n=0
+for partition; do
+	fillPartition "$out" "$n" "$(partitionPath "$partition")"
+	n="$(expr "$n" + 1)"
+done