Some checks failed
build image / build (push) Has been cancelled
Validated by running it on the machine, twice, and inspecting the result. Two properties of this laptop rule out the obvious approach, and the script exists mainly to encode them. Its internal UFS reports 4096-byte logical sectors, so the image — built with 512-byte geometry — cannot be dd'd onto it; the GPT header and every partition offset would land in the wrong place. And there are no EFI runtime variables, so efibootmgr cannot register a boot entry and GRUB has to sit at the removable-media path where the firmware looks unprompted. Three things the validation runs caught that review would not have: rsync is not in the image. I had put it in the build container and never in the package list, so the first run died at the copy. It now falls back to tar (--xattrs-include='*', or SELinux labels are silently dropped and the result does not boot), and rsync is in base.pkgs for the progress output. Copying a live root makes tar exit non-zero — files change underneath it, and this machine's clock is wrong besides, so every mtime looks like it is in the future. With pipefail that aborted the install after the root filesystem and before /boot, leaving a half-installed disk that looked plausible. Warning-level exits are now tolerated and only a fatal exit 2 stops the run. systemd-machine-id-setup keeps an existing valid id, and one had just been copied off the stick, so the installed system was a clone. The file is removed first now. Also: msm_dpu probes ~6s in, while the initramfs is still root, and asks for qcom/a630_sqe.fw before the real filesystem carrying it is reachable. It never retries. Adding the Adreno firmware to the initramfs is a few tens of kilobytes. c630-firmware does the same for the DSP blobs once they exist, since dracut rejects install_items globs that match nothing. chrony, because the RTC reads 1970 and nothing was correcting it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
104 lines
4.3 KiB
Markdown
104 lines
4.3 KiB
Markdown
# Installing on the Yoga C630
|
|
|
|
## Before you start
|
|
|
|
Leave Windows in place. Lenovo ships firmware updates only through Windows, and
|
|
the per-model Qualcomm blobs Linux needs live in that partition — wiping it
|
|
means losing accelerated graphics, audio and the sensor hub permanently.
|
|
Update everything through Lenovo Vantage first.
|
|
|
|
Disable Secure Boot. The image is not signed for it:
|
|
|
|
- Press **Fn+F2** during startup, go to **Security → Secure Boot → Disabled**, or
|
|
- **Settings → Update & Security → Recovery → Advanced startup → UEFI Firmware Settings**
|
|
|
|
## Write the image
|
|
|
|
```sh
|
|
zstd -d fedora-44-minimal-lenovo-yoga-c630-*.img.zst
|
|
sudo dd if=fedora-44-minimal-lenovo-yoga-c630-*.img of=/dev/sdX bs=4M status=progress oflag=direct conv=fsync
|
|
```
|
|
|
|
Check `/dev/sdX` twice. An 8 GiB stick is enough for `minimal`, 16 GiB for
|
|
`workstation`; the root filesystem expands to fill whatever you use.
|
|
|
|
## First boot
|
|
|
|
Insert the stick and power on holding **Fn+F12** for the boot menu, or enter
|
|
setup with **Fn+F2** and put USB ahead of the internal drive.
|
|
|
|
GRUB should appear with one entry. It has already been told which device tree to
|
|
load — the C630's UEFI does not supply one, which is the whole reason the
|
|
`devicetree` line exists in the boot loader entry.
|
|
|
|
First boot does two slow things: it relabels the filesystem for SELinux and
|
|
grows the root partition. Several minutes on a USB stick is normal. Log in as
|
|
`fedora` / `fedora` and set a new password when prompted.
|
|
|
|
## Extract the Qualcomm firmware
|
|
|
|
Accelerated graphics, audio, the sensor hub and video decode do not work
|
|
until you do this:
|
|
|
|
```sh
|
|
sudo c630-firmware
|
|
sudo reboot
|
|
```
|
|
|
|
See [firmware.md](firmware.md) if it cannot find the Windows partition.
|
|
|
|
## Installing to internal storage
|
|
|
|
Once the USB image is behaving, copy it onto the internal UFS. Boot from the
|
|
USB stick and run, on the laptop:
|
|
|
|
```sh
|
|
sudo ./build/install-to-disk.sh --dry-run # show the plan, touch nothing
|
|
sudo ./build/install-to-disk.sh # do it
|
|
```
|
|
|
|
It partitions the disk, copies the running system across, and rewrites every
|
|
UUID that has to change. Reboot afterwards and pick the internal drive from the
|
|
boot menu (**Fn+F12**), or just pull the stick out.
|
|
|
|
**This wipes the target disk.** If you still have Windows and want to keep it,
|
|
do not run this — shrink the Windows partition from within Windows first and
|
|
adapt the steps by hand.
|
|
|
|
Two things about this machine make the obvious approaches fail, both of which
|
|
the script handles:
|
|
|
|
**You cannot `dd` the image onto the internal drive.** The UFS reports
|
|
**4096-byte logical sectors**; the disk image is built with 512-byte sector
|
|
geometry. Its GPT header and every partition offset would land in the wrong
|
|
place. The disk has to be partitioned on the machine, at its own sector size.
|
|
|
|
**`efibootmgr` does not work here.** There are no EFI runtime variables —
|
|
`efibootmgr` reports *"EFI variables are not supported on this system"* — so
|
|
nothing can register a boot entry. GRUB therefore goes at the removable-media
|
|
path, `EFI/BOOT/BOOTAA64.EFI`, where the firmware finds it unprompted.
|
|
|
|
If you would rather do it by hand, the sequence is: `sgdisk` an ESP, a `/boot`
|
|
and a root partition; `mkfs.vfat` and `mkfs.ext4 -O
|
|
^orphan_file,^metadata_csum_seed`; copy `/`, `/boot` and the ESP separately
|
|
(preserving xattrs, or SELinux labels are lost); then update `/etc/fstab`,
|
|
`/etc/kernel/cmdline`, `root=UUID=` in `/boot/loader/entries/*.conf`, and the
|
|
`--fs-uuid` in both `/boot/grub2/grub.cfg` and `EFI/fedora/grub.cfg`.
|
|
|
|
## If it does not boot
|
|
|
|
The kernel command line is the first thing to change. It lives in
|
|
`options` in `/boot/loader/entries/c630-*.conf`, and GRUB lets you edit it for
|
|
one boot by pressing **e**.
|
|
|
|
| Symptom | Try |
|
|
|---|---|
|
|
| Hangs immediately after GRUB, no kernel output | Wrong or missing device tree — check the `devicetree` line points at a file that exists in `/boot/dtb-*/qcom/` |
|
|
| Boots then freezes partway | Drop `efi=noruntime`, or add `pd_ignore_unused` if it is missing |
|
|
| USB dies during boot | Add `modprobe.blacklist=qcom_q6v5_pas` |
|
|
| Cannot find root filesystem | The initramfs is missing the UFS drivers — see `overlay/etc/dracut.conf.d/10-c630.conf` |
|
|
| 90-second stall early in boot | Add `systemd.tpm2_wait=0` |
|
|
|
|
Adding `earlycon` and `ignore_loglevel` will tell you a great deal more about
|
|
which of these it is.
|