Move ChromeOS Flex notes into CHROMEOS-FLEX.md

Standalone doc covering install/reinstall via install-flex-emmc.sh, why a
raw dd boots as live media, chromeos-install-from-Linux gotchas, the
resulting layout, and boot selection. CLAUDE.md keeps a short quick
reference pointing to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ergosteur
2026-09-27 12:22:23 -04:00
co-authored by Claude Opus 5.5
parent 93f4eca05c
commit 08ae7257ca
2 changed files with 179 additions and 78 deletions
+14 -78
View File
@@ -119,82 +119,18 @@ power-off + power-on before assuming anything is actually broken.
## Dual boot: KDE neon (USB) + ChromeOS Flex (internal eMMC)
2026-09-04: installed ChromeOS Flex onto the internal eMMC
(`/dev/mmcblk0`), which was blank (see storage correction above — the
KDE neon system boots from an external USB/SD card on `sda`, not from
anything internal, so writing to the eMMC was safe to do live from the
running system with zero risk to the neon install).
ChromeOS Flex is installed on the internal eMMC (`/dev/mmcblk0`); neon
stays on the external `sda`. **Full details are in `CHROMEOS-FLEX.md`**,
covering install/reinstall via `install-flex-emmc.sh`, why a raw `dd` of
the recovery image boots as live media, `chromeos-install`-from-Linux
gotchas, the partition layout, and boot selection.
**How it was installed**: the Flex recovery image
(`chromeos_16640.57.0_reven_recovery_stable-channel_RevenMPKeys-v10.bin.zip`,
in `matt`'s `~/Downloads`) is a full raw GPT disk image — exactly what
the normal "boot from USB, then Install CloudReady/Chrome OS Flex" flow
`dd`s onto the target disk. Since neon's root already lives on external
media, that install flow was skipped entirely and the image was
streamed straight onto the eMMC instead:
```
sudo sh -c 'unzip -p "<path to .zip>" <path to .bin inside the zip> \
| dd of=/dev/mmcblk0 bs=4M status=progress conv=fsync'
```
Unzipped image is ~8.9GB; eMMC is 29GB. (Original note here claimed
ChromeOS auto-expands the stateful partition on first boot — **wrong**,
see the 2026-09-27 reinstall below.) eMMC write speed degraded over the transfer (~130MB/s at the start down
to ~9MB/s by the end, total ~18 min for 8.9GB) — looks like the eMMC's
SLC write cache exhausting partway through; expected/normal for eMMC of
this class, not a fault.
**2026-09-27: reinstalled properly with `install-flex-emmc.sh`.** The
raw `dd` above left the *installer* image layout: ROOT-B a 2MB
placeholder, STATE a fixed 6GB, ~20.7GB unallocated. Flex's
`/usr/sbin/is_running_from_installer` compares ROOT-A/ROOT-B sizes, so
it booted as live media ("Install ChromeOS Flex / Try it first") and
couldn't do A/B updates. There is no flag to flip; the fix is running
the image's own `chromeos-install` (what the Install button runs)
against the eMMC. `install-flex-emmc.sh` (in this repo) does that from
neon: loop-attaches the `.bin`, chroots into its ROOT-A inside a private
mount namespace with every other disk (incl. neon's `sda`) masked by
`/dev/null`, and runs `chromeos-install --dst /dev/mmcblk0
--payload_image ... --target_bios efi`. Gotchas it handles:
- `chromeos_postinst` needs a `cros_efi` flag on the kernel cmdline;
faked via a bind over `/proc/cmdline`, plus a wrapper on the image's
`chroot` because postinst re-chroots with a non-recursive `/proc` bind.
- Plasma/udisks auto-mounts new eMMC partitions mid-install, making
`sfdisk` refuse a busy disk — a temporary `UDISKS_IGNORE` udev rule
in `/run/udev/rules.d` prevents it.
- `chromeos-install` can exit 0 on failure and logs harmless `ERROR`
lines on success — judge by its final `Installation to ... complete.`
line. Log: `/var/log/flex-install.log`.
- Whole run is only ~2.5 min (partitions copied at eMMC speed).
Result: ROOT-A/ROOT-B 4GB each, STATE 20.6GB (fills disk), KERN-A
`successful=1`. The ESP is copied from the image so its FS UUID stays
`CBE4-703E` (script still re-points `40_custom` in case it changes);
UEFI boot entries/order untouched.
**Boot selection** — both OSes are reachable two ways:
1. **From GRUB** (neon's own boot menu, visible for 5s per
`GRUB_TIMEOUT`): a custom entry "ChromeOS Flex (internal eMMC)" was
added to `/etc/grub.d/40_custom`, which chainloads the eMMC's own EFI
bootloader:
```
menuentry "ChromeOS Flex (internal eMMC)" {
insmod part_gpt
insmod fat
insmod chain
search --no-floppy --fs-uuid --set=root CBE4-703E
chainloader /EFI/BOOT/BOOTX64.EFI
}
```
`CBE4-703E` is the FAT filesystem UUID of the eMMC's `EFI-SYSTEM`
partition (`mmcblk0p12`); `/EFI/BOOT/BOOTX64.EFI` is Chrome OS's
fallback UEFI loader (`crdyboot`) on that partition. Run
`sudo update-grub` after editing `40_custom` for changes to take
effect.
2. **From the firmware's own UEFI boot picker** (MrChromebox UEFI,
typically `Esc` during POST) — `efibootmgr -v` shows both `neon`
(Boot0005, on the USB stick) and `Internal eMMC` (Boot0001) as
registered entries, `BootOrder` currently `0005,0001,0000,0003,0002`
(neon first). If the USB stick is unplugged, firmware falls through
past the missing `neon` entry straight to `Internal eMMC` and boots
Flex automatically — no menu needed.
Quick reference:
- Reinstall: `sudo ./install-flex-emmc.sh <flex .bin.zip or .bin>` (wipes
the eMMC, masks every other disk, about 2.5 min, log in
`/var/log/flex-install.log`).
- Boot Flex from neon's GRUB menu with the "ChromeOS Flex (internal
eMMC)" entry (in `/etc/grub.d/40_custom`; chainloads the ESP with FS
UUID `CBE4-703E`), or from the firmware picker (`Esc` at POST, then
`Internal eMMC`). With the USB card unplugged, the firmware boots Flex
directly.