Four board fixes, in mt7986a-glinet-gl-mt6000-guix.dtsi (appended to OpenWrt's DTS, replacing the FIT script's fdtput edits) and the system: - secmon: GL's BL31 uses 256 KiB, not mainline's 192 KiB. - WED off and mainline's wo-ilm/wo-dlm/wo-boot no-map regions removed: with them the kernel resets within seconds under GL's firmware. - eMMC partitions in mainline's binding (gpt-partitions under card@0): OpenWrt's card@0/block/partitions isn't read by 6.13+, so `factory' had no NVMEM cells -- no WiFi calibration, and mtk_eth_soc deferred forever for its MAC address. - clk_ignore_unused: mtk_eth_soc, a module, loads after unused clocks are turned off, and its MDIO bus timed out. ramoops is built in, with a console record, so a failed boot's kernel log survives a warm reset. docs/PITFALLS.md #49-#52: these, GL U-Boot's TFTP recovery, and the image system's root UUID. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
115 lines
3.7 KiB
Bash
Executable File
115 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build the FIT image GL.iNet's U-Boot boots from the GL-MT6000's `kernel'
|
|
# partition (p6, 32 MiB), for one Guix system generation:
|
|
# kernel-1 the system's Image, LZMA-compressed, loaded at 0x48000000
|
|
# fdt-1 mt7986a-glinet-gl-mt6000.dtb with the Guix command line in
|
|
# /chosen/bootargs-append (GL's U-Boot passes empty bootargs;
|
|
# linux-mt6000 carries OpenWrt's bootargs-append patch)
|
|
# initrd-1 the system's initrd
|
|
# Same layout as OpenWrt's MT6000 FIT (kernel-1, fdt-1, config-1), plus the
|
|
# ramdisk OpenWrt's initramfs image also carries.
|
|
#
|
|
# Usage: scripts/mt6000-fit.sh /gnu/store/...-system OUTPUT.itb
|
|
set -euo pipefail
|
|
|
|
sys=${1:?usage: $0 SYSTEM OUTPUT.itb}
|
|
out=$(realpath -m "${2:?usage: $0 SYSTEM OUTPUT.itb}")
|
|
limit=$((32 * 1024 * 1024))
|
|
|
|
export PATH=$HOME/.local/bin:$PATH
|
|
# The package's main output: name-version, no -static/-doc suffix.
|
|
tool() { guix build "$1" 2>/dev/null | grep -E -- "-$1-[0-9][^-]*\$"; }
|
|
mkimage=$(tool u-boot-tools)/bin/mkimage
|
|
dtc=$(tool dtc)/bin
|
|
fdtput=$dtc/fdtput
|
|
xz=$(tool xz)/bin/xz
|
|
|
|
params=$(cat "$sys/parameters")
|
|
# root=LABEL or root=UUID, as Guix's bootloader configurations do. (`guix
|
|
# system image' gives the image's system its root partition's UUID.)
|
|
root=$(sed -n 's/.*(root-device (file-system-label "\([^"]*\)")).*/\1/p' <<<"$params")
|
|
if [ -z "$root" ]; then
|
|
bytes=$(sed -n 's/.*(root-device (uuid [a-z0-9]* #vu8(\([0-9 ]*\)))).*/\1/p' <<<"$params")
|
|
[ -n "$bytes" ] || { echo "$0: no label or UUID root in $sys/parameters" >&2; exit 1; }
|
|
hex=$(printf '%02x' $bytes)
|
|
root=${hex:0:8}-${hex:8:4}-${hex:12:4}-${hex:16:4}-${hex:20:12}
|
|
fi
|
|
kargs=$(sed -n 's/.*(kernel-arguments (\([^)]*\))).*/\1/p' <<<"$params" | tr -d '"')
|
|
cmdline="root=$root gnu.system=$sys gnu.load=$sys/boot $kargs"
|
|
|
|
kernel=$(readlink -f "$sys/kernel")
|
|
initrd=$(readlink -f "$sys/initrd")
|
|
dtb=$kernel/lib/dtbs/mediatek/mt7986a-glinet-gl-mt6000.dtb
|
|
[ -f "$dtb" ] || { echo "$0: $dtb missing" >&2; exit 1; }
|
|
|
|
work=$(mktemp -d)
|
|
trap 'rm -rf "$work"' EXIT
|
|
"$xz" --format=lzma -9 -c "$kernel/Image" > "$work/Image.lzma"
|
|
cp "$dtb" "$work/board.dtb"
|
|
chmod u+w "$work/board.dtb"
|
|
# Leading space: appended to whatever U-Boot passes (nothing, here).
|
|
"$fdtput" -t s "$work/board.dtb" /chosen bootargs-append " $cmdline"
|
|
# (Board fixes for GL's firmware and this kernel: in the DTB, from
|
|
# mt7986a-glinet-gl-mt6000-guix.dtsi.)
|
|
cp "$initrd" "$work/initrd"
|
|
|
|
cat > "$work/image.its" <<EOF
|
|
/dts-v1/;
|
|
|
|
/ {
|
|
description = "Guix System for the GL-MT6000";
|
|
#address-cells = <1>;
|
|
|
|
images {
|
|
kernel-1 {
|
|
description = "Linux ($(basename "$kernel"))";
|
|
data = /incbin/("Image.lzma");
|
|
type = "kernel";
|
|
arch = "arm64";
|
|
os = "linux";
|
|
compression = "lzma";
|
|
load = <0x48000000>;
|
|
entry = <0x48000000>;
|
|
hash-1 { algo = "crc32"; };
|
|
hash-2 { algo = "sha1"; };
|
|
};
|
|
fdt-1 {
|
|
description = "mt7986a-glinet-gl-mt6000";
|
|
data = /incbin/("board.dtb");
|
|
type = "flat_dt";
|
|
arch = "arm64";
|
|
compression = "none";
|
|
hash-1 { algo = "crc32"; };
|
|
};
|
|
initrd-1 {
|
|
description = "Guix initrd";
|
|
data = /incbin/("initrd");
|
|
type = "ramdisk";
|
|
arch = "arm64";
|
|
os = "linux";
|
|
compression = "none";
|
|
hash-1 { algo = "crc32"; };
|
|
};
|
|
};
|
|
|
|
configurations {
|
|
default = "config-1";
|
|
config-1 {
|
|
description = "$(basename "$sys")";
|
|
kernel = "kernel-1";
|
|
fdt = "fdt-1";
|
|
ramdisk = "initrd-1";
|
|
};
|
|
};
|
|
};
|
|
EOF
|
|
# mkimage runs dtc; /incbin paths are relative to the work directory.
|
|
(cd "$work" && PATH=$dtc:$PATH "$mkimage" -f image.its "$out" >/dev/null)
|
|
|
|
size=$(stat -c %s "$out")
|
|
if [ "$size" -gt "$limit" ]; then
|
|
echo "$0: $out is $size bytes, over the 32 MiB kernel partition" >&2
|
|
exit 1
|
|
fi
|
|
echo "$out: $size bytes; command line: $cmdline"
|