alarm-tegra-x1 / patches/patch-initramfs.sh

raw file 2725 bytes
#!/bin/sh
# Rebuild the patched switchroot L4T initramfs from the pristine original.
#
# The initramfs is the one boot component that had to change outside the
# alarm-build sources: it runs before the root filesystem exists, so it cannot
# be fixed from the Arch side. It is patched to
#
#   1. use `fsck.ext4 -yD` and `mount -t ext4` (the BusyBox-style `fsck`/`mount`
#      in the initramfs otherwise leave the filesystem in a bad state),
#   2. skip resize2fs (the root filesystem is already sized),
#   3. stop moving /proc, /sys and /dev into the new root (systemd does that),
#      and instead drop a small PID 1 at /sbin/init that execs
#      /etc/alarm-init.sh from the root filesystem, and
#   4. disable the initramfs's own getty on ttyGS0 (the PID 1 script owns it).
#
# Usage:
#   patches/patch-initramfs.sh [input] [output]
#
# Defaults:
#   input  switchroot/ubuntu-jammy/initramfs.orig
#   output switchroot/ubuntu-jammy/initramfs
set -eu

here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
root=$(dirname -- "$here")
in=${1:-$root/switchroot/ubuntu-jammy/initramfs.orig}
out=${2:-$root/switchroot/ubuntu-jammy/initramfs}

if [ ! -f "$in" ]; then
    echo "input initramfs not found: $in" >&2
    exit 1
fi

work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT

# 1. Unwrap the uImage (64-byte U-Boot header) and the gzip stream.
dd if="$in" bs=64 skip=1 status=none | gunzip > "$work/initramfs.cpio"
mkdir -p "$work/root"
(cd "$work/root" && cpio -idm --no-absolute-filenames < "$work/initramfs.cpio")

# 2. Apply the changes.
(cd "$work/root" && patch -p0 --no-backup-if-mismatch < "$here/initramfs.patch")

# 2b. Neutralise ply-image.
#
# The boot logos are pointless here -- the Switch's scanout surface is
# block-linear, so anything drawn into it renders as speckle -- and ply-image is
# a framebuffer client that can block forever waiting for a framebuffer that a
# mainline kernel may never provide (simple-framebuffer fails with -22). The
# initramfs calls it unconditionally at several points, including one straight
# after the USB gadget setup, so blocking there hangs the whole boot.
cat > "$work/root/bin/ply-image" <<'PLYEOF'
#!/bin/sh
# no-op stub installed by alarm-build; see patches/patch-initramfs.sh
exit 0
PLYEOF
chmod 0755 "$work/root/bin/ply-image"

# 3. Repack exactly as the kernel expects: `init` and the other entries must sit
#    at the top level of the archive. Repacking from the wrong directory
#    produces `./root/init` and the kernel reports "No working init found".
(cd "$work/root" && find . | cpio -o -H newc 2>/dev/null | gzip -9 > "$work/initramfs.cpio.gz")
mkimage -A arm64 -O linux -T ramdisk -C gzip -a 0 -e 0 \
    -d "$work/initramfs.cpio.gz" "$out"

echo "Wrote $out"