12 KiB
Other neon customizations on hp-chell
Reconstructed on 2026-09-27 from ~matt/.bash_history (551 lines,
roughly early March 2026 onward), /root/.bash_history, and the live
system. Topics with their own docs:
AUDIO.md, ZRAM.md,
CHROMEOS-FLEX.md, and the kernel 7.x black-screen
fix in CLAUDE.md.
Keyboard: keyd remapping for the Chromebook layout
The Chromebook keyboard has no F-keys, Delete, Home/End, PgUp/PgDn or Caps Lock; there's a "Search" key where Caps Lock would be. keyd remaps it at the evdev level, so it works everywhere (console, X, Wayland, the login screen).
- Built from source, not from apt (apt has no keyd for noble):
~/github/keyd(https://github.com/rvaiya/keyd,7c0aecb, v2.6.0),make && sudo make install, which puts the binary at/usr/local/bin/keyd. Thensudo systemctl enable --now keyd. Neither apt nor unattended upgrades will ever update it; rebuild from the checkout to upgrade. - Config:
/etc/keyd/default.conf. Apply edits withsudo keyd reload; find key names and device IDs withsudo keyd monitor. Summary:[ids] 0001:0001: only the internal keyboard (AT Translated Set 2 keyboard); external USB keyboards are left alone (use*to include them).leftmeta = overload(meta, leftmeta): Search acts as Meta when held and taps as Meta (opens the KDE launcher).- Search + top row gives F1 to F10 (back, forward, refresh, zoom,
scale, brightness down/up, mute, volume down/up). Search +
-/=gives F11/F12. - The same top-row to F-key mapping with Alt, Ctrl or Shift held. The
A-/C-/S-prefixes re-apply the modifier, which keyd otherwise strips, so e.g. Alt+F4 works as Alt+Search+Zoom. - Search + Backspace = Delete; Search + arrows = Home/End/PgUp/PgDn.
- Alt + Backspace = Delete; Alt + Search = Caps Lock.
USB-C DisplayPort output: load the cros_ec Type-C drivers
/etc/modules-load.d/cros-video.conf (2026-03-12):
cros_ec_typec
typec_displayport
These don't autoload on chell, and without them the USB-C ports don't negotiate DisplayPort alt mode, so there's no video out over USB-C. Both are loaded as of 2026-09-27.
Kernel: HWE-edge meta package
linux-generic-hwe-24.04-edge is installed (alongside the plain
linux-generic-hwe-24.04), and it's why the machine is on 7.x kernels
(7.0.0-34 now), not noble's regular HWE line. Also installed
deliberately as a known-good fallback: linux-image-generic-6.17 /
linux-headers-generic-6.17 (6.17.0-42), which is the fallback kernel
named in the black-screen notes in CLAUDE.md. Old 7.x kernels
(7.0.0-30, 7.0.0-14) are still installed as well.
/etc/default/grub (edited by hand several times; both matt and root
history show nano /etc/default/grub + update-grub): GRUB_DEFAULT=0,
GRUB_TIMEOUT=5, GRUB_TIMEOUT_STYLE=menu,
GRUB_CMDLINE_LINUX_DEFAULT='splash' (see setup-i915-kernel7-fix.sh).
Storage / wear on the microSD root
neon's root is a microSD card in the built-in slot (sda; the slot's
reader is USB-attached internally), and microSD handles lots of small
writes poorly, so a few changes cut down writes and space use:
/tmpis tmpfs (in/etc/fstab:tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0). Not in the shell history, so it was probably added in the samenano /etc/fstabedit that disabled the swapfile.- The swapfile was replaced by zram (see
ZRAM.md). localepurgeis installed and configured (viadpkg-reconfigure localepurge) to keep onlyen,en_CA.UTF-8,en_US.UTF-8andfr_CA.UTF-8, and delete other locales' files on every package install (USE_DPKG,MANDELETE). If another language's translations or man pages are ever needed, add them withsudo dpkg-reconfigure localepurge.- Root mounted with
commit=30(2026-09-27): the root line in/etc/fstabisdefaults,commit=30; the pre-change copy is/etc/fstab.bak-2026-09-27. ext4 commits its journal every 30s instead of every 5s, so writes are batched into fewer, larger bursts. Trade-off: a crash or forced power-off can lose up to ~30s of recent changes that weren't fsync'd (apt/dpkg, editors and databases fsync, so they're unaffected). 30 rather than 60 because this machine has needed forced power-offs.relatimeis kept deliberately (notnoatime). - journald capped at 100MB (2026-09-27):
/etc/systemd/journald.conf.d/50-max-size.confsetsSystemMaxUse=100M(it was 455MB). smartmontoolsdisabled (2026-09-27,systemctl disable --now): it failed on every boot because neither the microSD card nor the eMMC supports SMART.- Marked non-rotational (2026-09-27): the Genesys reader reported
rotational=1(a spinning disk)./etc/udev/rules.d/61-microsd-nonrotational.rulessetsqueue/rotational=0forID_VENDOR_ID=05e3,ID_MODEL_ID=0747, solsblk -d -o NAME,ROTAshows0. - The card doesn't support discard/TRIM (
lsblk -Dshows 0), sofstrim.timerdoes nothing for it. That's harmless and was left alone.
Suspend: stay on s2idle; do NOT use S3 (deep)
Tested 2026-09-27. The firmware offers both s2idle (default) and deep
(ACPI S3) in /sys/power/mem_sleep.
- An RTC-woken 30s S3 test (
rtcwake -m mem -s 30withmem_sleep=deep) entered and left S3 cleanly, and the display came back. The i915 bug didn't show. - A real lid-close S3 suspend broke the root filesystem: on resume
the built-in microSD reader (USB, Genesys
05e3:0747) didn't come back in time, the kernel logged disk I/O errors, and ext4 remounted/read-only (errors=remount-ro). Nothing was logged because root was read-only (the previous boot's journal just stops). After a forced reboot, the initramfs fsck replayed the journal and reported the filesystem clean; no lasting damage was found. - In S3 the USB controller loses power, so the reader has to be
re-attached. USB "persist" (
power/persist=1, the kernel feature meant for root on USB storage) was already on and didn't save it. There's no dependable fix, so never setmem_sleep_default=deepwhile neon's root is on the microSD slot. s2idlekeeps USB powered and has worked for months. It does reach S0ix: in a 44s lid-close test (2026-09-28),/sys/kernel/debug/pmc_core/slp_s0_residency_usec(needs root) grew by ~42.2s, andpackage_cstate_showshowed Package C10 ~42.0s. So ~96% of the suspend was in the deepest idle state, and drain should be close to S3's. Root stayedrwwith no I/O errors.- Use the
pmc_corecounter above, not/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us. That one comes from ACPI LPIT, which isn't wired up properly under coreboot here: it read 270µs for the same suspend.
Suspend-then-hibernate (set up 2026-09-28)
A lid close suspends (s2idle, instant). If the machine is still asleep
after 3 hours, systemd wakes it (RTC), writes a hibernation image to
disk and powers off. This protects against a dead battery without
writing a multi-GB image on every lid close, which is why this was
chosen over hybrid sleep. It doesn't need S3.
Pieces:
- 16GB
/swapfile, used for the hibernation image (sized to RAM for the worst case; a typical image is ~4GB). fstab/swapfile none swap sw,pri=10 0 0: priority 10 < zram's 100, so normal swapping still goes to zram. Backup of the old fstab:/etc/fstab.bak-2026-09-28. - Resume location:
resume=UUID=3af45daa-b8c2-4053-9574-a958e0c3ea68 resume_offset=17674240inGRUB_CMDLINE_LINUX_DEFAULT(backup/etc/default/grub.bak-2026-09-28) and in/etc/initramfs-tools/conf.d/resume, thenupdate-initramfs -u -k allupdate-grub. If/swapfileis ever recreated, its offset changes. Get the new one withsudo filefrag -v /swapfile | awk '$1=="0:"{print $4}'(strip the trailing..), then update both places and rerun both commands.
/etc/systemd/sleep.conf.d/50-suspend-then-hibernate.conf:HibernateDelaySec=3h./etc/polkit-1/rules.d/10-enable-hibernate.rules: Ubuntu's/usr/share/polkit-1/rules.d/com.ubuntu.desktop.rulesreturnsNOfor alllogin1/upowerhibernate actions, so logind reportedCanHibernate/CanSuspendThenHibernate=noeven though its sleep checks passed (seen withsystemctl service-log-level systemd-logind debug). This rule sorts earlier and returnsYESfor local, active users.- Plasma: PowerDevil owns the lid, so each Power Management profile's sleep mode must be set to "Standby, then hibernate" in System Settings.
Tested 2026-09-28 with systemctl hibernate: a 3.8GB image, powered off,
and the session resumed intact (uptime carried over, root rw). Right
after resume, one readahead READ failed on sda ("device offline or
changed") while the microSD reader was being reset. That's harmless:
readahead failures are dropped, and ext4 logged no errors and stayed
clean. It's the same reader re-attach that breaks S3, but a hibernate
resume is a cold boot and the reader was back in time.
Networking
- Realtek USB Ethernet (
enx00e04c68003e, r8152-family 2.5G adapter): the out-of-tree driver from https://github.com/awesometic/realtek-r8152-dkms (~/github/realtek-r8152-dkms) was once installed with DKMS, together with unloadingcdc_ether/cdc_ncm/cdc_mbimand testing withiperf3againstpet630, MTU 9000 andethtool -Koffloads. It was later removed (sudo ./dkms-remove.sh) because it failed to build against the 7.x kernels (confirmed by matt, 2026-09-27).dkms statusis empty now, so the adapter gets the in-kernel driver. The MTU and offload tweaks were runtime-only and aren't persisted anywhere. - Tailscale is installed (repo in
tailscale.list) buttailscaledis disabled (systemctl disable tailscaled, around the time the agent account was created).
Firmware and access
- MrChromebox firmware utility run twice
(
curl -LOf https://mrchromebox.tech/firmware-util.sh && sudo bash firmware-util.sh); the second run was the 2026-09-03 update toMrChromebox-2606.1(seeCLAUDE.md). agent-usercreated withcreate-agent-user.shfromhttps://gist.ergosteur.com/ergosteur/41df939a435741bfac431ac3d4b888d0(a copy is in~matt).
Software and third-party apt repos
Not hardware-specific, but needed to rebuild the machine. The
repositories in /etc/apt/sources.list.d/ beyond neon's own:
| Source file | What | Set up via |
|---|---|---|
vscodium.sources |
VSCodium (codium) |
paulcarroty key into /usr/share/keyrings/vscodium-archive-keyring.gpg |
google-chrome.sources |
Google Chrome | installing the .deb from Downloads; set as x-www-browser / gnome-www-browser via update-alternatives |
docker.sources |
Docker CE | Docker's official apt instructions; matt added to the docker group |
ansible-ubuntu-ansible-noble.sources |
ansible-core |
ppa:ansible/ansible |
nodesource.sources |
Node.js 24 | deb.nodesource.com/setup_24.x; then npm i -g @google/gemini-cli |
tailscale.list |
Tailscale | (disabled, see above) |
Other tools installed by hand:
bws(Bitwarden Secrets Manager CLI) v2.0.0: unzipped into/opt/bitwarden/bws/, symlinked to/usr/local/bin/bws, with completions in/opt/bitwarden/bws/completions.bashsourced from~/.bashrc.- GlobalProtect VPN (
PanGPLinux-6.3.3-c31,gp_install.sh, from~/Downloads). pipx:mkdocsplus the injectedmkdocs-material.- Claude Code (
curl -fsSL https://claude.ai/install.sh | bash).
Notable apt packages installed on top of neon: codium ffmpeg yt-dlp imagemagick python3-pip python3-venv pipx python3-bs4 build-essential ncdu bwm-ng wireshark mpv filezilla rpi-imager ntfs-3g exfatprogs exfat-fuse hfsutils hfsprogs samba samba-vfs-modules krdc remmina ssh iperf3 netcat-openbsd htop btop git pavucontrol-qt bash-completion tesseract-ocr{,-eng,-fra,-kor} inxi lsscsi qrencode localepurge zram-tools dkms.
Git identities: ~/.gitconfig plus ~/.gitconfig.ergosteur and
~/.gitconfig.tfo, with SSH key aliases in ~/.ssh:
git_ssh_id_ergosteur → id_rsa, and git_ssh_id_myip4tfo →
id_ed25519.
Dead ends in the history (nothing left installed)
~/github/chell_audio(iofq's chell audio repo) was cloned andlinux-modules-extra/snd_soc_sklpoked at, before switching to WeirdTreeThing's scripts (seeAUDIO.md).ntfs2btrfs/ntfsfixagainst a/dev/sda1of the time. That was an external data card before this layout, not the current neon install, whosesda1is its ESP.