Build Fedora aarch64 images for the Lenovo Yoga C630

Assembles a ready-to-write disk image via Gitea Actions. Mainline has carried
sdm850-lenovo-yoga-c630.dts since 5.5 and Fedora ships it in kernel-core, so
unlike aarch64-laptops/build there is no kernel or GRUB to compile — what is
left is producing an image that boots on firmware which hands Linux no device
tree.

The build runs in an aarch64 container under qemu-user and builds filesystems
from directory trees with mke2fs -d and mcopy rather than mounting loop
devices, so it works on runners that will not hand out /dev/loop-control.

A kernel-install hook writes the devicetree line into each BLS entry; without
it the first `dnf update kernel` would produce an unbootable system.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
This commit is contained in:
2026-07-27 11:24:53 +03:00
commit 280874f564
21 changed files with 1294 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
#!/usr/bin/bash
#
# Pull the model-specific Qualcomm blobs off this machine's Windows partition.
#
# Fedora ships everything for the C630 that Qualcomm allows to be redistributed
# — Adreno 630 (graphics) and ath10k WCN3990 (WiFi/Bluetooth) both work out of
# the box. What it cannot ship is the per-model signed firmware: the ADSP, the
# compute DSP, and the display/UEFI blob. Those are signed against this
# machine's own keys and live only in its Windows install.
#
# Without them you lose audio, the sensor hub (lid switch, accelerometer,
# auto-rotate) and hardware video decode. Everything else still works.
set -euo pipefail
if [ "$(id -u)" -ne 0 ]; then
echo "c630-firmware: needs root — try: sudo c630-firmware" >&2
exit 1
fi
echo "Looking for a Windows installation to extract firmware from..."
echo
if ! command -v qcom-firmware-extract >/dev/null; then
echo "qcom-firmware-extract is not installed. Install it with:" >&2
echo " sudo dnf install qcom-firmware-extract" >&2
exit 1
fi
qcom-firmware-extract "$@"
echo
echo "Regenerating the initramfs so the DSP firmware is available early..."
dracut --force --regenerate-all
cat <<'EOF'
Done. Reboot to pick up the new firmware.
If qcom-firmware-extract could not find the Windows partition, mount it by hand
and point the tool at it:
sudo mkdir -p /mnt/windows
sudo mount /dev/disk/by-partlabel/Windows /mnt/windows # adjust as needed
sudo qcom-firmware-extract --windows-dir /mnt/windows
See docs/firmware.md in the c630 repo for the full file list and the manual
fallback if the tool does not recognise this model.
EOF

View File

@@ -0,0 +1,43 @@
#!/usr/bin/bash
#
# Grow the root partition and filesystem to fill the medium.
#
# The image is built at a fixed size so the artifact stays small; whatever it
# gets written to is almost always bigger. Runs once, then disables itself.
set -euo pipefail
STAMP=/var/lib/c630/growfs-done
root_src="$(findmnt -no SOURCE /)"
root_dev="$(basename "$root_src")"
part_num_file="/sys/class/block/${root_dev}/partition"
if [ ! -r "$part_num_file" ]; then
echo "c630-growfs: / is on ${root_src}, which is not a partition — nothing to grow"
mkdir -p "$(dirname "$STAMP")" && touch "$STAMP"
exit 0
fi
part_num="$(cat "$part_num_file")"
disk="/dev/$(lsblk -no pkname "$root_src")"
# The image was written with dd, so the secondary GPT header is still sitting
# where the end of the image used to be. growpart refuses to touch a disk in
# that state, so move it to the real end of the device first.
sgdisk --move-second-header "$disk" || true
if growpart "$disk" "$part_num"; then
echo "c630-growfs: grew ${disk}${part_num}"
else
# growpart exits non-zero with NOCHANGE when the partition already fills
# the disk. That is a success for our purposes.
echo "c630-growfs: partition already at full size"
fi
partprobe "$disk" || true
resize2fs "$root_src"
mkdir -p "$(dirname "$STAMP")"
touch "$STAMP"
echo "c630-growfs: done"