The dnf transaction is essentially the whole cost of a build — emulated rpm scriptlets for 502 packages on minimal, 1929 on workstation. Everything after it is minutes. Getting this laptop to boot will take several attempts at the kernel command line and the dracut driver list, and paying for a reinstall each time is not tenable. Stage the post-dnf tree under <work>/base, keyed on a hash of the package lists, release and variant, and copy it per build with --reflink=auto (a CoW clone on btrfs). Config and overlay edits now reuse it; package list edits invalidate it on their own, so --fresh is only needed to force the issue. Keep downloaded rpms in a cachedir outside the install root, so even --fresh re-runs the scriptlets without re-downloading. keepcache=0 was exactly the wrong setting for a build meant to be run repeatedly. Add --work so CI can put both outside the job workspace, which is wiped between runs, and default the build container to the gongfoo aarch64 build base so the assembly tooling is not installed under emulation every time. That image is a speedup, not a dependency: fall back to stock Fedora when it is unreachable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
128 lines
5.6 KiB
Markdown
128 lines
5.6 KiB
Markdown
# Fedora for the Lenovo Yoga C630 13Q50
|
|
|
|
Builds a ready-to-write Fedora aarch64 disk image for the Lenovo Yoga C630
|
|
(model 81JL, Qualcomm SDM850), using Gitea Actions.
|
|
|
|
The approach is borrowed from [aarch64-laptops/build][aal], but the heavy
|
|
lifting that project had to do in 2019 is now unnecessary: mainline Linux has
|
|
carried `sdm850-lenovo-yoga-c630.dts` since 5.5, and Fedora ships it in
|
|
`kernel-core`. There is no kernel to patch and no GRUB to compile. What is left
|
|
is assembling a disk image that boots on hardware whose firmware hands Linux no
|
|
device tree.
|
|
|
|
[aal]: https://github.com/aarch64-laptops/build
|
|
|
|
## What you get
|
|
|
|
`output/fedora-44-<variant>-lenovo-yoga-c630-<date>-<ref>.img.zst` — a GPT disk
|
|
image with an ESP, a `/boot` partition and an ext4 root. Decompress, write it to
|
|
a USB stick or microSD card, and boot. The root filesystem grows to fill the
|
|
medium on first boot.
|
|
|
|
Two variants:
|
|
|
|
| Variant | Size | Contents |
|
|
|---------------|-------|----------------------------------------------|
|
|
| `minimal` | 8 GiB | Console, sshd, and enough tools to debug the machine |
|
|
| `workstation` | 16 GiB| GNOME desktop |
|
|
|
|
Default login is `fedora` / `fedora`, and the password must be changed at first
|
|
login. Root is locked.
|
|
|
|
## Hardware status
|
|
|
|
| Works out of the box | Needs firmware from Windows | Not supported |
|
|
|---------------------------------|-----------------------------|---------------|
|
|
| UFS storage, USB, keyboard, touchpad, touchscreen | Audio | LTE modem |
|
|
| WiFi + Bluetooth (ath10k WCN3990) | Sensor hub — lid switch, accelerometer, auto-rotate | |
|
|
| Graphics (freedreno, Adreno 630) | Hardware video decode (venus) | |
|
|
| Battery and charging | | |
|
|
|
|
Qualcomm allows the Adreno and ath10k firmware to be redistributed, so Fedora
|
|
ships it and this image includes it. The SDM850 DSP and display blobs are signed
|
|
per model and exist only in your machine's Windows partition. Run
|
|
`sudo c630-firmware` once after installing — see [docs/firmware.md](docs/firmware.md).
|
|
|
|
## Building
|
|
|
|
CI does this on every push to `main`. To run it yourself:
|
|
|
|
```sh
|
|
./build/build-image.sh --variant minimal
|
|
```
|
|
|
|
You need `podman` and, on an x86_64 host, aarch64 emulation:
|
|
|
|
```sh
|
|
sudo dnf install -y qemu-user-static-aarch64
|
|
sudo systemctl restart systemd-binfmt
|
|
```
|
|
|
|
`build/build-image.sh` runs on the host and only sets up the container.
|
|
`build/stage2.sh` runs inside an aarch64 Fedora container and does everything
|
|
else: `dnf --installroot`, the overlay, dracut, and the disk assembly. It builds
|
|
filesystems from directory trees with `mke2fs -d` and `mcopy` rather than
|
|
mounting loop devices, so it does not need `/dev/loop-control` — which CI
|
|
runners generally will not hand out.
|
|
|
|
### Iterating
|
|
|
|
Every aarch64 binary runs under emulation, and the `dnf` transaction is
|
|
essentially all of the cost — 500-odd packages' worth of rpm scriptlets for
|
|
`minimal`, four times that for `workstation`. Everything after it takes
|
|
minutes. Since getting this machine to boot will take a few attempts, the build
|
|
is arranged so you only pay that once:
|
|
|
|
- The post-`dnf` root filesystem is staged under `<work>/base`, keyed on a hash
|
|
of the package lists, release and variant. Editing `config/device.env`,
|
|
`overlay/`, or the bootloader config reuses it. Editing `config/packages/`
|
|
invalidates it automatically.
|
|
- The working copy is made with `cp --reflink=auto`, so on btrfs or xfs it is
|
|
a copy-on-write clone rather than a real copy.
|
|
- Downloaded rpms live in `.cache/dnf`, outside the staged tree, so even
|
|
`--fresh` re-runs the scriptlets without re-downloading.
|
|
|
|
In practice a kernel-command-line change rebuilds in a few minutes.
|
|
|
|
```sh
|
|
./build/build-image.sh --variant minimal # reuses the staged base
|
|
./build/build-image.sh --variant minimal --fresh # forces a reinstall
|
|
./build/build-image.sh --variant minimal --keep-rootfs # keep the tree to poke at
|
|
```
|
|
|
|
CI points `--work` and `--cache` at `/var/tmp/c630-build` so both survive
|
|
between jobs. That is per-runner, so the first build on a given runner is cold.
|
|
|
|
The build container defaults to `git.lair.cafe/gongfoo/build-fedora-44-aarch64`,
|
|
which ships the assembly tooling so it does not have to be installed under
|
|
emulation on every run. If that image is not reachable the build falls back to
|
|
stock Fedora and installs the tooling itself — slower, but it works.
|
|
|
|
## Repository layout
|
|
|
|
```
|
|
config/device.env C630 parameters: DTB path, kernel command line, geometry
|
|
config/packages/*.pkgs Package lists — base plus one file per variant
|
|
overlay/ Files copied into the root filesystem (*.in are templated)
|
|
build/build-image.sh Host driver: emulation checks, podman invocation
|
|
build/stage2.sh The actual build, inside an aarch64 container
|
|
firmware/local/ Optional drop-in for firmware you extracted yourself (gitignored)
|
|
.gitea/workflows/ CI
|
|
docs/ Installation, firmware, runner setup
|
|
```
|
|
|
|
## Documentation
|
|
|
|
- [docs/install.md](docs/install.md) — writing the image and booting the laptop
|
|
- [docs/firmware.md](docs/firmware.md) — what needs extracting from Windows and why
|
|
- [docs/runner-setup.md](docs/runner-setup.md) — one-time Gitea runner preparation
|
|
|
|
## Caveats
|
|
|
|
The build has not yet been confirmed to boot on real hardware. The device tree,
|
|
kernel command line and firmware layout are taken from Fedora's Snapdragon WoA
|
|
documentation and the aarch64-laptops project; the parts specific to the C630's
|
|
older SDM850 are reasoned from those rather than tested. Expect to spend a boot
|
|
or two adjusting `DEVICE_CMDLINE` in `config/device.env`. Findings belong in
|
|
this README.
|