🚀 NixOS su Lenovo IdeaPad Slim 3 Chromebook 14M868

Versione HTML Premium • Tema Catppuccin Mocha • Syntax Highlighting • Navigazione laterale

NixOS sul Lenovo IdeaPad Slim 3 Chromebook 14M868

Guida completa — MediaTek Kompanio 520 (MT8186 / google-corsola-magneton)

**⚠️ AVVERTENZE PRELIMINARI**
- Questa procedura **cancella ChromeOS** dalla eMMC interna in modo definitivo
- Il Depthcharge bootloader di ChromeOS **non avvia ISO standard** — richiede un kpart firmato con vboot keys
- Per questo motivo serve un **USB installer personalizzato** (costruito sull'host), non una ISO NixOS standard
- Il processo richiede di aprire fisicamente il case per disabilitare la write-protection hardware
- Board codename: **magneton** — tre varianti hardware (SKU 393216 / 393217 / 393218)
- Kernel mainline 6.12+ supporta corsola/magneton; GPU via driver **Panfrost**; audio parziale

---

Panoramica del flusso

[HOST LINUX]                        [CHROMEBOOK]
──────────────────────────────────────────────────────
1. Installa tool (vboot, mkimage)
2. Scarica kernel hexdump0815 stb-cbm
3. Crea FIT image + kpart firmato
4. Prepara USB installer             
   (GPT ChromeOS + kpart + rootfs Alpine)
                                    5. Attiva Developer Mode
                                    6. Disabilita WP hardware
                                    7. Imposta GBB Flags
                                    8. Avvia da USB (Ctrl+U)
                                    9. Dal live Alpine:
                                       - Partiziona eMMC con cgpt
                                       - Estrai NixOS tarball su eMMC
                                       - Scrivi kpart eMMC su KERN-A
                                    10. Riavvia da eMMC (Ctrl+D)
                                    11. nixos-install / configurazione

---

Indice

1. [Prerequisiti](#1-prerequisiti)

2. [Preparazione host Linux — tool e kernel](#2-preparazione-host-linux--tool-e-kernel)

3. [Creazione del kpart firmato](#3-creazione-del-kpart-firmato)

4. [Creazione dell'USB installer ChromeOS-compatibile](#4-creazione-dellUSB-installer-chromeos-compatibile)

5. [Attivazione Developer Mode sul Chromebook](#5-attivazione-developer-mode-sul-chromebook)

6. [Disabilitazione hardware write-protect (WP)](#6-disabilitazione-hardware-write-protect-wp)

7. [Impostazione GBB Flags](#7-impostazione-gbb-flags)

8. [Avvio dal USB installer (Ctrl+U)](#8-avvio-dal-usb-installer-ctrlu)

9. [Dal live Alpine — partizionamento eMMC e installazione NixOS](#9-dal-live-alpine--partizionamento-emmc-e-installazione-nixos)

10. [Scrittura del kpart sull'eMMC](#10-scrittura-del-kpart-sullemmc)

11. [Configurazione NixOS (configuration.nix)](#11-configurazione-nixos-configurationnix)

12. [nixos-install e primo avvio](#12-nixos-install-e-primo-avvio)

13. [Gestione degli aggiornamenti del kernel](#13-gestione-degli-aggiornamenti-del-kernel)

14. [Stato dell'hardware](#14-stato-dellhardware)

15. [Ripristino di ChromeOS](#15-ripristino-di-chromeos)

---

1. Prerequisiti

**Hardware necessario:**

- Lenovo IdeaPad Slim 3 Chromebook 14M868

- Cacciavite Phillips #0 (o Torx T5 a seconda del lotto di produzione)

- USB drive ≥ 4 GB (per l'installer)

- PC Linux (host) per costruire l'installer — qualsiasi distro x86_64 va bene

**Pacchetti sull'host Linux:**

# Debian / Ubuntu
sudo apt install vboot-utils u-boot-tools device-tree-compiler \
                 xz-utils wget curl e2fsprogs

# Arch Linux
sudo pacman -S vboot-utils uboot-tools dtc xz wget

# NixOS host — ambiente temporaneo
nix-shell -p vboot_utils ubootTools dtc xz wget

**Verifica che `cgpt` e `futility` siano disponibili:**

which cgpt futility mkimage

---

2. Preparazione host Linux — tool e kernel

Crea una directory di lavoro sull'host:

mkdir ~/magneton-build
cd ~/magneton-build

Scarica il kernel precompilato per corsola/MT8186

Il progetto [hexdump0815](https://github.com/hexdump0815/linux-mainline-mediatek-mt81xx-kernel)

fornisce kernel mainline patchati e testati esplicitamente su magneton.

Controlla la [pagina releases](https://github.com/hexdump0815/linux-mainline-mediatek-mt81xx-kernel/releases)

per la versione più recente; al momento della scrittura è **6.12.66-stb-cbm+**.

KVER="6.12.66-stb-cbm+"
BASE="https://github.com/hexdump0815/linux-mainline-mediatek-mt81xx-kernel/releases/download/${KVER}"

wget "${BASE}/linux-${KVER}-aarch64.tar.gz"
wget "${BASE}/linux-${KVER}-aarch64-modules.tar.gz"

# Estrai
tar xzf linux-${KVER}-aarch64.tar.gz
tar xzf linux-${KVER}-aarch64-modules.tar.gz

# Verifica presenza DTB magneton
ls boot/dtb-${KVER}/mt8186-corsola-magneton-*.dtb
# Deve mostrare: sku393216, sku393217, sku393218

Scarica il mini-rootfs Alpine AArch64 (per il live USB)

ALPINE_VER="3.21.3"
wget "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/aarch64/alpine-minirootfs-${ALPINE_VER}-aarch64.tar.gz"

---

3. Creazione del kpart firmato

Il kpart è l'unico formato che Depthcharge accetta. È un FIT image (kernel + DTB)

firmato con le vboot developer keys.

Servono **due kpart distinti** con command line diverse:

- `kpart-usb.bin` → `root=/dev/sda2` (per avviare dal live USB)

- `kpart-emmc.bin` → `root=/dev/mmcblk0p2` (per il sistema finale su eMMC)

Passo 3a — File di command line

# Per il live USB (root su sda2)
cat > cmdline-usb.txt << 'EOF'
console=tty1 root=/dev/sda2 rootwait rw quiet
EOF

# Per l'installazione finale su eMMC (root su mmcblk0p2)
cat > cmdline-emmc.txt << 'EOF'
console=tty1 root=/dev/mmcblk0p2 rootwait rw quiet
EOF

Passo 3b — FIT Image (.itb)

Crea il file `.its` che descrive il FIT con kernel e tutti e tre i DTB magneton

(Depthcharge sceglie automaticamente quello corretto in base al GPIO SKU strapping):

KVER="6.12.66-stb-cbm+"
KERNEL="boot/Image-${KVER}"
DTB="boot/dtb-${KVER}"

cat > magneton.its << EOF
/dts-v1/;

/ {
    description = "NixOS kernel FIT for MT8186 Magneton";
    #address-cells = <1>;

    images {
        kernel@1 {
            description = "Linux kernel ${KVER}";
            data = /incbin/("${KERNEL}");
            type = "kernel_noload";
            arch = "arm64";
            os = "linux";
            compression = "none";
            load = <0>;
            entry = <0>;
            hash@1 { algo = "sha256"; };
        };
        fdt@1 {
            description = "MT8186 Magneton SKU393216";
            data = /incbin/("${DTB}/mt8186-corsola-magneton-sku393216.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash@1 { algo = "sha256"; };
        };
        fdt@2 {
            description = "MT8186 Magneton SKU393217";
            data = /incbin/("${DTB}/mt8186-corsola-magneton-sku393217.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash@1 { algo = "sha256"; };
        };
        fdt@3 {
            description = "MT8186 Magneton SKU393218";
            data = /incbin/("${DTB}/mt8186-corsola-magneton-sku393218.dtb");
            type = "flat_dt";
            arch = "arm64";
            compression = "none";
            hash@1 { algo = "sha256"; };
        };
    };

    configurations {
        default = "conf@1";
        conf@1 {
            description = "Magneton SKU393216";
            kernel = "kernel@1";
            fdt = "fdt@1";
        };
        conf@2 {
            description = "Magneton SKU393217";
            kernel = "kernel@1";
            fdt = "fdt@2";
        };
        conf@3 {
            description = "Magneton SKU393218";
            kernel = "kernel@1";
            fdt = "fdt@3";
        };
    };
};
EOF

mkimage -f magneton.its magneton.itb

Passo 3c — Firma con futility (vboot dev keys)

DEVKEYS="/usr/share/vboot/devkeys"
# Su NixOS host: DEVKEYS="$(nix-build -A vboot_reference --no-out-link)/share/vboot/devkeys"

# kpart per USB installer
futility vbutil_kernel \
    --arch arm --version 1 \
    --keyblock    "${DEVKEYS}/kernel.keyblock" \
    --signprivate "${DEVKEYS}/kernel_data_key.vbprivk" \
    --bootloader  cmdline-usb.txt \
    --config      cmdline-usb.txt \
    --vmlinuz     magneton.itb \
    --pack        kpart-usb.bin

# kpart per installazione finale su eMMC
futility vbutil_kernel \
    --arch arm --version 1 \
    --keyblock    "${DEVKEYS}/kernel.keyblock" \
    --signprivate "${DEVKEYS}/kernel_data_key.vbprivk" \
    --bootloader  cmdline-emmc.txt \
    --config      cmdline-emmc.txt \
    --vmlinuz     magneton.itb \
    --pack        kpart-emmc.bin

# Verifica entrambi
futility vbutil_kernel --verify kpart-usb.bin
futility vbutil_kernel --verify kpart-emmc.bin
# Output atteso: "signatures VALID"

---

4. Creazione dell'USB installer ChromeOS-compatibile

Questo è il punto centrale: crei sull'host un USB con layout GPT ChromeOS,

partizione KERN-A con il kpart-usb.bin, e partizione root con un mini-rootfs

Alpine AArch64 + i moduli kernel + i tool necessari per l'installazione.

**Sostituisci `/dev/sdX` con il device reale del tuo USB.**
Controlla con `lsblk` prima di procedere. **Dati sul USB verranno cancellati.**
USB=/dev/sdX   # <-- CAMBIA CON IL TUO DEVICE USB

# Smonta eventuali partizioni montate
umount ${USB}* 2>/dev/null || true

Passo 4a — Partizionamento GPT ChromeOS

# Crea tabella GPT pulita
sudo cgpt create ${USB}

# Partizione 1: KERN-A (ChromeOS kernel, 64 MiB)
# Settore 8192 = 4 MiB offset dall'inizio (spazio per GPT)
sudo cgpt add -i 1 \
    -b 8192 -s 131072 \
    -t kernel \
    -l "KERN-A" \
    -P 15 -T 1 -S 1 \
    ${USB}

# Partizione 2: ROOT (ext4, resto del disco)
sudo cgpt add -i 2 \
    -b 139264 -s $(( $(sudo blockdev --getsz ${USB}) - 139264 - 33 )) \
    -t data \
    -l "ROOT" \
    ${USB}

# Protective MBR
sudo cgpt boot -p ${USB}

# Verifica layout
sudo cgpt show ${USB}

Output atteso:

       start        size    part  contents
           0           1          PMBR
           1           1          Pri GPT header
           2          32          Pri GPT table
        8192      131072       1  Label: "KERN-A"
                                  Type: ChromeOS kernel
                                  Attr: priority=15 tries=1 successful=1
      139264    <N settori>   2  Label: "ROOT"
                                  Type: Linux data

Passo 4b — Scrivi il kpart USB sulla partizione KERN-A

sudo dd if=kpart-usb.bin of=${USB}p1 bs=4M status=progress
sudo sync

Passo 4c — Crea filesystem ext4 sulla partizione root

sudo mkfs.ext4 -L alpine-live ${USB}p2
sudo mkdir -p /mnt/usb-root
sudo mount ${USB}p2 /mnt/usb-root

Passo 4d — Estrai il mini-rootfs Alpine AArch64

ALPINE_VER="3.21.3"
sudo tar xzf alpine-minirootfs-${ALPINE_VER}-aarch64.tar.gz -C /mnt/usb-root

# Crea device nodes essenziali
sudo mkdir -p /mnt/usb-root/{dev,proc,sys,tmp,mnt,run}
sudo mknod -m 666 /mnt/usb-root/dev/null    c 1 3
sudo mknod -m 666 /mnt/usb-root/dev/urandom c 1 9
sudo mknod -m 666 /mnt/usb-root/dev/random  c 1 8
sudo mknod -m 600 /mnt/usb-root/dev/console c 5 1
sudo mknod -m 666 /mnt/usb-root/dev/tty     c 5 0
sudo mknod -m 666 /mnt/usb-root/dev/tty1    c 4 1

Passo 4e — Installa i moduli kernel

KVER="6.12.66-stb-cbm+"

# Estrai i moduli nel rootfs
sudo tar xzf linux-${KVER}-aarch64-modules.tar.gz \
    -C /mnt/usb-root \
    --strip-components=0

# Copia il kernel nel rootfs (per eventuale uso da live)
sudo mkdir -p /mnt/usb-root/boot
sudo cp boot/Image-${KVER} /mnt/usb-root/boot/

Passo 4f — Copia i file necessari per l'installazione

# Copia i kpart nel rootfs live (serviranno in Sezione 10)
sudo mkdir -p /mnt/usb-root/root/install
sudo cp kpart-emmc.bin         /mnt/usb-root/root/install/
sudo cp cmdline-emmc.txt       /mnt/usb-root/root/install/
sudo cp magneton.itb           /mnt/usb-root/root/install/
sudo cp magneton.its           /mnt/usb-root/root/install/

# Copia i moduli compressi per installarli sull'eMMC
sudo cp linux-${KVER}-aarch64-modules.tar.gz /mnt/usb-root/root/install/

Passo 4g — Configura Alpine per l'avvio automatico

# DNS resolver
echo "nameserver 8.8.8.8" | sudo tee /mnt/usb-root/etc/resolv.conf

# inittab: avvia getty su tty1 (tastiera del Chromebook)
sudo tee /mnt/usb-root/etc/inittab << 'EOF'
::sysinit:/sbin/openrc sysinit
::sysinit:/sbin/openrc boot
::wait:/sbin/openrc default
tty1::respawn:/sbin/getty 115200 tty1
tty2::respawn:/sbin/getty 115200 tty2
::ctrlaltdel:/sbin/reboot
::shutdown:/sbin/openrc shutdown
EOF

# /etc/fstab minimale
sudo tee /mnt/usb-root/etc/fstab << 'EOF'
/dev/sda2   /       ext4    defaults    0 1
proc        /proc   proc    defaults    0 0
sysfs       /sys    sysfs   defaults    0 0
devpts      /dev/pts devpts defaults    0 0
EOF

# Script di benvenuto da eseguire al login
sudo tee /mnt/usb-root/root/.profile << 'PROFILE'
echo ""
echo "=== MAGNETON NIXOS INSTALLER ==="
echo "eMMC interna:  /dev/mmcblk0"
echo "microSD:       /dev/mmcblk1"
echo "File install:  /root/install/"
echo ""
echo "Passo successivo: esegui le istruzioni della Sezione 9 della guida"
echo ""
PROFILE

# Smonta
sudo umount /mnt/usb-root
sudo sync

L'USB installer è pronto. Espellilo dal PC host.

---

5. Attivazione Developer Mode sul Chromebook

**Attenzione:** l'attivazione cancella tutti i dati utente ChromeOS (powerwash).

1. Spegni completamente il Chromebook

2. Tieni premuto **Esc + Refresh (F3) + Power** simultaneamente → Recovery Mode

3. Sulla schermata di recovery, premi **Ctrl+D**

4. Conferma con **Invio**

5. Attendi il powerwash (2-5 minuti)

6. Al riavvio, sulla schermata con punto esclamativo: **NON premere barra spaziatrice**

7. Attendi 30 secondi o premi **Ctrl+D** per accelerare

Abilita il boot da USB (una sola volta, dentro ChromeOS)

Apri il terminale con **Ctrl+Alt+T**, digita `shell`, poi:

sudo su
enable_dev_usb_boot
crossystem dev_boot_usb=1
crossystem dev_boot_signed_only=0

---

6. Disabilitazione hardware write-protect (WP)

Sul magneton il chip di sicurezza è un **GSC (Google Security Chip / CR50/TI50)**.

Su questi dispositivi la write-protection hardware si disabilita

**scollegando la batteria mentre il sistema è alimentato via USB-C**.

Non c'è una vite WP separata come sui Chromebook più vecchi.

**Procedura:**

1. Spegni il Chromebook

2. Rimuovi le viti sul fondo del case (Phillips #0 o Torx T5)

3. Rimuovi delicatamente il back cover facendo leva dal bordo posteriore

4. **Scollega il connettore flat della batteria** dalla scheda madre

5. Collega il caricabatterie USB-C

6. Accendi: il dispositivo funzionerà solo con l'alimentatore esterno

**Verifica in ChromeOS shell:**

sudo flashrom --wp-status
# Output atteso: "WP: write protect is disabled"
Lascia la batteria scollegata fino a dopo la Sezione 7 (GBB Flags).
Puoi ricollegarla e rimontare il case dopo.

---

7. Impostazione GBB Flags

Le GBB (Google Binary Block) Flags sono salvate nella flash ROM del firmware.

Impostarle correttamente è **essenziale**: se la batteria si scarica completamente

con ChromeOS rimosso e i flag non sono settati, il dispositivo non potrà più

avviare da USB e sarà inutilizzabile senza un recovery.

Significato dei flag

| Bit | Valore | Effetto |

|-----|--------|---------|

| `GBB_FLAG_DEV_SCREEN_SHORT_DELAY` | `0x01` | Riduce countdown avvio da 30s a 2s |

| `GBB_FLAG_FORCE_DEV_SWITCH_ON` | `0x08` | Blocca Developer Mode permanentemente |

| `GBB_FLAG_FORCE_DEV_BOOT_USB` | `0x10` | Abilita boot USB permanentemente |

**Valore raccomandato: `0x19`** (= 0x01 + 0x08 + 0x10)

Scrittura in ChromeOS shell (come root, con WP disabilitata)

sudo su

# Metodo 1 — futility diretto (prova prima questo)
futility gbb --set --flash --flags=0x19

# Se ottieni "ERROR: unrecognized option (possibly '--flash')"
# usa gli script wrapper Google:
/usr/share/vboot/bin/set_gbb_flags.sh 0x19

# Verifica
/usr/share/vboot/bin/get_gbb_flags.sh
# Deve riportare: 0x00000019

**Dopo la verifica:** ricollega la batteria e rimonta il back cover.

---

8. Avvio dal USB installer (Ctrl+U)

1. Inserisci l'USB installer nel Chromebook

2. Riavvia il Chromebook

3. Alla schermata "OS verification is OFF": premi **Ctrl+U**

4. Il Chromebook avvierà il live Alpine AArch64 dal USB

Il boot può richiedere 30-60 secondi. Comparirà un prompt di login.

**Login:** `root` (nessuna password)

Verifica che il kernel sia carico correttamente:

uname -r
# Output atteso: 6.12.66-stb-cbm+ (o versione scaricata)

lsblk
# Deve mostrare:
# sda       (USB drive)
# mmcblk0   (eMMC interna, ~64 GB)
# mmcblk1   (microSD, se inserita)

---

9. Dal live Alpine — partizionamento eMMC e installazione NixOS

**Tutto quello che segue si esegue sul Chromebook, nel live Alpine.**

Passo 9a — Connetti alla rete WiFi

# Carica il modulo WiFi
modprobe mt7921e

# Verifica che l'interfaccia sia rilevata
ip link show
# Deve mostrare un'interfaccia wlan0 o simile

# Connessione con wpa_supplicant
wpa_passphrase "NomeRete" "password" > /tmp/wpa.conf
wpa_supplicant -B -i wlan0 -c /tmp/wpa.conf
udhcpc -i wlan0

# Test connessione
ping -c 3 1.1.1.1

Passo 9b — Installa i tool necessari nel live Alpine

# Configura APK (gestore pacchetti Alpine)
echo "https://dl-cdn.alpinelinux.org/alpine/v3.21/main" > /etc/apk/repositories
echo "https://dl-cdn.alpinelinux.org/alpine/v3.21/community" >> /etc/apk/repositories

apk update
apk add vboot-utils e2fsprogs parted wget curl tar xz util-linux
Se non hai rete, `cgpt` potrebbe già essere nel rootfs.
Verifica con `which cgpt`. Se mancano tool critici, puoi anche copiarli
dall'USB stesso oppure dal tarball di ChromeOS già presente.

Passo 9c — Partizionamento eMMC con cgpt

EMMC=/dev/mmcblk0   # eMMC interna

# Attenzione: questo cancella TUTTO su mmcblk0, incluso ChromeOS
cgpt create ${EMMC}

# Partizione 1: KERN-A — 64 MiB per il kpart
cgpt add -i 1 \
    -b 8192 -s 131072 \
    -t kernel \
    -l "KERN-A" \
    -P 15 -T 1 -S 1 \
    ${EMMC}

# Partizione 2: ROOT — tutto il resto
ROOT_START=139264
DISK_SECTORS=$(blockdev --getsz ${EMMC})
ROOT_SIZE=$(( DISK_SECTORS - ROOT_START - 33 ))

cgpt add -i 2 \
    -b ${ROOT_START} \
    -s ${ROOT_SIZE} \
    -t data \
    -l "ROOT-A" \
    ${EMMC}

# Protective MBR
cgpt boot -p ${EMMC}

# Verifica
cgpt show ${EMMC}

Output atteso:

       start        size    part  contents
           0           1          PMBR
           1           1          Pri GPT header
           2          32          Pri GPT table
        8192      131072       1  Label: "KERN-A"
                                  Type: ChromeOS kernel
                                  Attr: priority=15 tries=1 successful=1
      139264   <N settori>    2  Label: "ROOT-A"
                                  Type: Linux data

Passo 9d — Formatta e monta la partizione root

# Forza il riconoscimento delle nuove partizioni
partprobe ${EMMC} 2>/dev/null || true
sleep 2

# Formatta come ext4
mkfs.ext4 -L nixos ${EMMC}p2

# Monta
mkdir -p /mnt/nixos
mount ${EMMC}p2 /mnt/nixos

Passo 9e — Scarica e installa NixOS AArch64

Hai due opzioni:

**Opzione A — Tarball NixOS minimal (richiede rete)**

# Scarica il tarball NixOS AArch64 minimal
NIXOS_VER="25.05"
wget "https://channels.nixos.org/nixos-${NIXOS_VER}/latest-nixos-minimal-aarch64-linux.tar.xz" \
    -O /tmp/nixos.tar.xz

tar xJf /tmp/nixos.tar.xz -C /mnt/nixos --strip-components=1

**Opzione B — Installa Nix nel live Alpine e usa nixos-install**

# Installa Nix nel live Alpine
apk add nix
# Poi nixos-generate-config e nixos-install come nella Sezione 12

Opzione A è più rapida. Continuiamo con quella.

Passo 9f — Monta i filesystem virtuali per il chroot

mount --bind /dev  /mnt/nixos/dev
mount --bind /proc /mnt/nixos/proc
mount --bind /sys  /mnt/nixos/sys
mount -t devpts devpts /mnt/nixos/dev/pts

Passo 9g — Installa i moduli kernel nell'eMMC

KVER="6.12.66-stb-cbm+"

# Copia dall'USB (già presente in /root/install)
cp /root/install/linux-${KVER}-aarch64-modules.tar.gz /tmp/

tar xzf /tmp/linux-${KVER}-aarch64-modules.tar.gz \
    -C /mnt/nixos \
    --strip-components=0

# Copia anche l'Image e i DTB (utili per ricreare il kpart dall'interno di NixOS)
mkdir -p /mnt/nixos/boot/dtb-${KVER}
cp /boot/Image-${KVER} /mnt/nixos/boot/
cp /root/install/magneton.its /mnt/nixos/boot/
cp /root/install/cmdline-emmc.txt /mnt/nixos/boot/

# Verifica
ls /mnt/nixos/lib/modules/

---

10. Scrittura del kpart sull'eMMC

Ancora dal live Alpine, scrivi il kpart-emmc.bin sulla partizione KERN-A:

# Il file è già nel rootfs USB live
dd if=/root/install/kpart-emmc.bin of=/dev/mmcblk0p1 bs=4M status=progress
sync

# Riconferma gli attributi CGpt (per sicurezza)
cgpt add -i 1 -P 15 -T 1 -S 1 /dev/mmcblk0

# Verifica
cgpt show /dev/mmcblk0 | grep -A4 "KERN-A"
# Deve mostrare: Attr: priority=15 tries=1 successful=1

---

11. Configurazione NixOS (configuration.nix)

La configurazione è suddivisa in tre file nella directory `/etc/nixos/`:

/etc/nixos/
├── configuration.nix        ← sistema base + Niri + servizi
├── hardware-configuration.nix  ← generato automaticamente
└── home.nix                 ← Home Manager: Waybar, Fuzzel, config utente

Entra nel chroot e genera la configurazione hardware:

chroot /mnt/nixos /bin/bash
nixos-generate-config --root /

---

File 1 — `/etc/nixos/configuration.nix`

{ config, lib, pkgs, ... }:

{
  imports = [
    ./hardware-configuration.nix
    ./home.nix
  ];

  # ============================================================
  # BOOTLOADER
  # Su Depthcharge NON si usa GRUB né systemd-boot.
  # Il kernel viene caricato direttamente dal kpart ChromeOS.
  # Il kpart va aggiornato manualmente dopo ogni cambio kernel
  # (vedi Sezione 13).
  # ============================================================
  boot.loader.grub.enable = false;
  boot.loader.generic-extlinux-compatible.enable = false;

  # Parametri kernel — devono corrispondere a cmdline-emmc.txt
  boot.kernelParams = [
    "console=tty1"
    "root=/dev/mmcblk0p2"
    "rootwait"
    "rw"
    "quiet"
  ];

  # ============================================================
  # KERNEL
  # linuxPackages_latest → 6.12+ con supporto corsola/magneton
  # ============================================================
  boot.kernelPackages = pkgs.linuxPackages_latest;

  boot.initrd.availableKernelModules = [ "mmc_block" "mmc_core" ];

  boot.kernelModules = [
    "mt7921e"   # WiFi MediaTek MT7921
    "panfrost"  # GPU Mali-G52 (open source)
  ];

  # ============================================================
  # FILESYSTEM
  # ============================================================
  fileSystems."/" = {
    device = "/dev/disk/by-label/nixos";
    fsType = "ext4";
    options = [ "defaults" "noatime" ];
  };

  swapDevices = [{ device = "/swapfile"; size = 2048; }];

  # ============================================================
  # HARDWARE
  # ============================================================
  hardware.enableRedistributableFirmware = true;
  hardware.firmware = [ pkgs.linux-firmware ];

  # GPU Panfrost — driver open source Mali
  hardware.opengl = {
    enable = true;
    driSupport = true;
  };

  # ============================================================
  # WAYLAND / NIRI
  # Niri è un compositor Wayland scrolling-tiled.
  # Non usa programs.sway né programs.hyprland.
  # ============================================================
  programs.niri = {
    enable = true;
    # Installa niri come pacchetto di sistema e abilita il
    # portale XDG necessario per screen capture e file picker
  };

  # Portale XDG — richiesto da molte app Wayland (Firefox, ecc.)
  xdg.portal = {
    enable = true;
    extraPortals = [ pkgs.xdg-desktop-portal-gnome ];
    config.common.default = "*";
  };

  # Variabili d'ambiente Wayland globali
  environment.sessionVariables = {
    NIXOS_OZONE_WL       = "1";   # Electron/Chromium su Wayland
    MOZ_ENABLE_WAYLAND   = "1";   # Firefox
    QT_QPA_PLATFORM      = "wayland";
    GDK_BACKEND          = "wayland";
    CLUTTER_BACKEND      = "wayland";
    XDG_SESSION_TYPE     = "wayland";
    XDG_CURRENT_DESKTOP  = "niri";
  };

  # ============================================================
  # DISPLAY MANAGER — greetd con autologin
  # (alternativa leggera a GDM/SDDM, adatta ad ARM)
  # ============================================================
  services.greetd = {
    enable = true;
    settings = {
      default_session = {
        command = "${pkgs.niri}/bin/niri-session";
        user    = "richard";
      };
    };
  };

  # ============================================================
  # AUDIO — PipeWire
  # ============================================================
  security.rtkit.enable = true;
  services.pipewire = {
    enable            = true;
    alsa.enable       = true;
    alsa.support32Bit = false;   # ARM64, no 32-bit
    pulse.enable      = true;
    jack.enable       = false;
  };

  # ============================================================
  # RETE
  # ============================================================
  networking.hostName = "magneton";
  networking.networkmanager.enable = true;

  # ============================================================
  # LOCALE
  # ============================================================
  time.timeZone = "Europe/Rome";
  i18n.defaultLocale = "it_IT.UTF-8";
  console.keyMap = "it";

  # ============================================================
  # FONT
  # ============================================================
  fonts = {
    enableDefaultPackages = true;
    packages = with pkgs; [
      noto-fonts
      noto-fonts-emoji
      nerd-fonts.jetbrains-mono   # font per Waybar e terminale
      nerd-fonts.iosevka
    ];
    fontconfig.defaultFonts = {
      monospace = [ "JetBrainsMono Nerd Font" ];
      sansSerif = [ "Noto Sans" ];
      serif     = [ "Noto Serif" ];
    };
  };

  # ============================================================
  # PACCHETTI DI SISTEMA
  # ============================================================
  environment.systemPackages = with pkgs; [
    # Wayland essentials
    wayland-utils
    wl-clipboard      # wl-copy / wl-paste
    wlr-randr         # gestione display Wayland
    grim              # screenshot Wayland
    slurp             # selezione area per grim

    # Terminale
    foot              # terminale Wayland nativo, leggero

    # Applicazioni base
    firefox-wayland
    nautilus          # file manager GTK

    # Tool di sistema
    wget curl git vim htop
    networkmanagerapplet  # nm-applet per tray WiFi

    # Tool per gestione kpart (necessari dopo ogni aggiornamento kernel)
    vboot_utils       # cgpt, futility
    ubootTools        # mkimage
    dtc               # device tree compiler

    pciutils usbutils
  ];

  # ============================================================
  # UTENTE
  # ============================================================
  users.users.richard = {
    isNormalUser = true;
    extraGroups  = [ "wheel" "networkmanager" "video" "audio" "input" ];
    initialPassword = "changeme";
    shell = pkgs.bash;
  };

  # ============================================================
  # HOME MANAGER — integrazione in-system
  # ============================================================
  home-manager.useGlobalPkgs   = true;
  home-manager.useUserPackages = true;

  # ============================================================
  # SSH
  # ============================================================
  services.openssh.enable = true;

  system.stateVersion = "25.05";
}

---

File 2 — `/etc/nixos/home.nix`

Questo file gestisce la configurazione utente tramite **Home Manager**:

Waybar, Fuzzel e la config di Niri sono dichiarativi qui.

**Nota:** Home Manager deve essere aggiunto come input flake oppure
come canale. Il modo più semplice senza flakes:
```bash
sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-25.05.tar.gz home-manager
sudo nix-channel --update
```
poi aggiungere `imports = [ <home-manager/nixos> ]` in `configuration.nix`
(già incluso con `./home.nix` come wrapper qui sotto).
# /etc/nixos/home.nix
{ config, pkgs, ... }:

{
  imports = [ <home-manager/nixos> ];

  home-manager.users.richard = { pkgs, config, lib, ... }: {

    home.stateVersion = "25.05";
    home.username     = "richard";
    home.homeDirectory = "/home/richard";

    # ============================================================
    # NIRI — configurazione compositor
    # File: ~/.config/niri/config.kdl
    # ============================================================
    programs.niri.settings = {
      # Layout scrolling tiles
      layout = {
        gaps = 8;
        center-focused-column = "never";
        preset-column-widths = [
          { proportion = 0.33333; }
          { proportion = 0.5; }
          { proportion = 0.66667; }
        ];
        default-column-width = { proportion = 0.5; };
        focus-ring = {
          enable = true;
          width  = 2;
          active-color   = "#7fc8ff";
          inactive-color = "#505050";
        };
        border = {
          enable = false;
        };
      };

      # Comportamento finestre
      prefer-no-csd = true;

      # Spawn al login
      spawn-at-startup = [
        { command = [ "waybar" ]; }
        { command = [ "nm-applet" "--indicator" ]; }
      ];

      # Input
      input = {
        keyboard = {
          xkb = {
            layout = "it";
            options = "caps:escape";  # CapsLock → Escape
          };
          repeat-delay    = 400;
          repeat-rate     = 30;
        };
        touchpad = {
          tap                    = true;
          dwt                    = true;   # disabilita durante digitazione
          natural-scroll         = true;
          scroll-method          = "two-finger";
          click-method           = "clickfinger";
          accel-speed            = 0.2;
        };
      };

      # Output (display interno magneton)
      outputs = {
        "eDP-1" = {
          scale  = 1.0;
          # transform = "normal";
        };
      };

      # Animazioni
      animations = {
        slowdown = 1.0;
        workspace-switch.spring = {
          damping-ratio = 1.0;
          stiffness     = 1000;
          epsilon       = 0.0001;
        };
        window-open.duration-ms   = 150;
        window-close.duration-ms  = 150;
      };

      # Keybindings
      binds = with config.lib.niri.actions; {
        # Launcher
        "Mod+Space".action   = spawn "fuzzel";
        # Terminale
        "Mod+Return".action  = spawn "foot";
        # Browser
        "Mod+B".action       = spawn "firefox";
        # File manager
        "Mod+E".action       = spawn "nautilus";
        # Screenshot schermo intero
        "Mod+Shift+S".action = spawn "sh" "-c" "grim ~/screenshot-$(date +%Y%m%d-%H%M%S).png";
        # Screenshot area selezionata
        "Mod+S".action       = spawn "sh" "-c" "grim -g \"$(slurp)\" ~/screenshot-$(date +%Y%m%d-%H%M%S).png";
        # Clipboard screenshot
        "Print".action       = spawn "sh" "-c" "grim - | wl-copy";

        # Gestione finestre
        "Mod+Q".action       = close-window;
        "Mod+H".action       = focus-column-left;
        "Mod+L".action       = focus-column-right;
        "Mod+J".action       = focus-window-down;
        "Mod+K".action       = focus-window-up;
        "Mod+Shift+H".action = move-column-left;
        "Mod+Shift+L".action = move-column-right;
        "Mod+Shift+J".action = move-window-down;
        "Mod+Shift+K".action = move-window-up;

        # Dimensioni colonne
        "Mod+R".action       = switch-preset-column-width;
        "Mod+F".action       = maximize-column;
        "Mod+Shift+F".action = fullscreen-window;

        # Workspace
        "Mod+1".action       = focus-workspace 1;
        "Mod+2".action       = focus-workspace 2;
        "Mod+3".action       = focus-workspace 3;
        "Mod+4".action       = focus-workspace 4;
        "Mod+5".action       = focus-workspace 5;
        "Mod+Shift+1".action = move-column-to-workspace 1;
        "Mod+Shift+2".action = move-column-to-workspace 2;
        "Mod+Shift+3".action = move-column-to-workspace 3;
        "Mod+Shift+4".action = move-column-to-workspace 4;
        "Mod+Shift+5".action = move-column-to-workspace 5;

        # Volume (tasti Fn Chromebook)
        "XF86AudioRaiseVolume".action  = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%+";
        "XF86AudioLowerVolume".action  = spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%-";
        "XF86AudioMute".action         = spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";

        # Luminosità (richiede brightnessctl)
        "XF86MonBrightnessUp".action   = spawn "brightnessctl" "set" "+10%";
        "XF86MonBrightnessDown".action = spawn "brightnessctl" "set" "10%-";

        # Esci da Niri
        "Mod+Shift+E".action = quit;
      };
    };

    # ============================================================
    # WAYBAR
    # ============================================================
    programs.waybar = {
      enable  = true;
      systemd.enable = false;  # avviato da niri spawn-at-startup

      style = ''
        * {
          font-family: "JetBrainsMono Nerd Font", monospace;
          font-size: 13px;
          border: none;
          border-radius: 0;
          min-height: 0;
        }

        window#waybar {
          background-color: rgba(20, 20, 28, 0.92);
          color: #cdd6f4;
        }

        .modules-left,
        .modules-center,
        .modules-right {
          padding: 2px 8px;
        }

        #workspaces button {
          padding: 2px 8px;
          color: #6c7086;
          background: transparent;
        }

        #workspaces button.active {
          color: #cdd6f4;
          background: rgba(137, 180, 250, 0.15);
          border-bottom: 2px solid #89b4fa;
        }

        #workspaces button:hover {
          color: #cdd6f4;
          background: rgba(255,255,255,0.07);
        }

        #clock {
          color: #cdd6f4;
          padding: 0 10px;
        }

        #battery {
          color: #a6e3a1;
          padding: 0 8px;
        }

        #battery.warning  { color: #f9e2af; }
        #battery.critical { color: #f38ba8; }

        #network {
          color: #89dceb;
          padding: 0 8px;
        }

        #network.disconnected { color: #6c7086; }

        #pulseaudio {
          color: #cba6f7;
          padding: 0 8px;
        }

        #pulseaudio.muted { color: #6c7086; }

        #cpu, #memory {
          color: #fab387;
          padding: 0 8px;
        }

        #temperature {
          color: #a6e3a1;
          padding: 0 8px;
        }

        #temperature.critical { color: #f38ba8; }

        #tray {
          padding: 0 8px;
        }
      '';

      settings = [{
        layer    = "top";
        position = "top";
        height   = 28;
        spacing  = 4;

        modules-left   = [ "niri/workspaces" "niri/window" ];
        modules-center = [ "clock" ];
        modules-right  = [
          "cpu" "memory" "temperature"
          "pulseaudio" "network" "battery"
          "tray"
        ];

        "niri/workspaces" = {
          format = "{name}";
        };

        "niri/window" = {
          max-length = 50;
          separate-outputs = true;
        };

        clock = {
          format          = " {:%H:%M}";
          format-alt      = " {:%A %d %B %Y}";
          tooltip-format  = "<tt>{calendar}</tt>";
          calendar = {
            mode        = "year";
            mode-mon-col = 3;
            on-scroll   = 1;
            format = {
              months    = "<span color='#cdd6f4'><b>{}</b></span>";
              days      = "<span color='#cdd6f4'><b>{}</b></span>";
              weekdays  = "<span color='#89b4fa'><b>{}</b></span>";
              today     = "<span color='#a6e3a1'><b><u>{}</u></b></span>";
            };
          };
        };

        battery = {
          states = {
            warning  = 30;
            critical = 15;
          };
          format            = "{icon} {capacity}%";
          format-charging   = "󰂄 {capacity}%";
          format-plugged    = "󰚥 {capacity}%";
          format-icons      = [ "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ];
          tooltip-format    = "{timeTo} — {power:.1f}W";
        };

        network = {
          format-wifi         = "󰤨 {essid}";
          format-ethernet     = "󰈀 {ifname}";
          format-disconnected = "󰤭 Disconnesso";
          tooltip-format-wifi = "{signalStrength}% — {frequency}GHz";
          on-click            = "nm-connection-editor";
        };

        pulseaudio = {
          format        = "{icon} {volume}%";
          format-muted  = "󰝟 Muto";
          format-icons  = {
            default = [ "󰕿" "󰖀" "󰕾" ];
          };
          on-click      = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle";
          on-click-right = "pavucontrol";
          scroll-step   = 5;
        };

        cpu = {
          format   = "󰻠 {usage}%";
          interval = 5;
          tooltip  = false;
        };

        memory = {
          format   = "󰍛 {used:.1f}G";
          interval = 10;
          tooltip-format = "Usata: {used:.1f}G / {total:.1f}G";
        };

        temperature = {
          thermal-zone    = 0;
          critical-threshold = 80;
          format          = "󰔏 {temperatureC}°C";
          format-critical = "󰸁 {temperatureC}°C";
        };

        tray = {
          icon-size   = 16;
          spacing     = 8;
          show-passive-items = true;
        };
      }];
    };

    # ============================================================
    # FUZZEL — launcher applicazioni Wayland
    # ============================================================
    programs.fuzzel = {
      enable = true;
      settings = {
        main = {
          font               = "JetBrainsMono Nerd Font:size=13";
          dpi-aware          = "auto";
          width              = 35;
          lines              = 10;
          tabs               = 8;
          horizontal-pad     = 16;
          vertical-pad       = 8;
          inner-pad          = 4;
          image-size-ratio   = 0.5;
          prompt             = "  ";
          terminal           = "foot -e";
          launch-prefix      = "";
          match-mode         = "fzf";
          show-actions       = true;
          icons-enabled      = true;
          icon-theme         = "Papirus-Dark";
        };
        colors = {
          # Schema Catppuccin Mocha
          background        = "1e1e2edd";
          text              = "cdd6f4ff";
          match             = "89b4faff";
          selection         = "313244ff";
          selection-text    = "cdd6f4ff";
          selection-match   = "89b4faff";
          border            = "89b4fa99";
        };
        border = {
          width  = 2;
          radius = 8;
        };
        dmenu = {
          exit-immediately-if-only-one-item = true;
        };
      };
    };

    # ============================================================
    # FOOT — terminale Wayland
    # ============================================================
    programs.foot = {
      enable = true;
      settings = {
        main = {
          font        = "JetBrainsMono Nerd Font:size=11";
          pad         = "8x8";
          shell       = "bash";
          term        = "foot";
        };
        colors = {
          # Catppuccin Mocha
          background  = "1e1e2e";
          foreground  = "cdd6f4";
          regular0    = "45475a";
          regular1    = "f38ba8";
          regular2    = "a6e3a1";
          regular3    = "f9e2af";
          regular4    = "89b4fa";
          regular5    = "f5c2e7";
          regular6    = "94e2d5";
          regular7    = "bac2de";
          bright0     = "585b70";
          bright1     = "f38ba8";
          bright2     = "a6e3a1";
          bright3     = "f9e2af";
          bright4     = "89b4fa";
          bright5     = "f5c2e7";
          bright6     = "94e2d5";
          bright7     = "a6adc8";
        };
        cursor = {
          style = "beam";
          blink = "yes";
        };
        scrollback = {
          lines = 5000;
        };
      };
    };

    # ============================================================
    # PACCHETTI UTENTE aggiuntivi
    # ============================================================
    home.packages = with pkgs; [
      brightnessctl    # controllo luminosità da tastiera
      pavucontrol      # mixer audio grafico
      papirus-icon-theme  # icone per Fuzzel
      playerctl        # controllo media player
    ];

    # ============================================================
    # VARIABILI D'AMBIENTE utente
    # ============================================================
    home.sessionVariables = {
      EDITOR  = "vim";
      BROWSER = "firefox";
      TERM    = "foot";
    };

  }; # fine home-manager.users.richard
}

---

## 12. nixos-install e primo avvio

Ancora nel chroot, o uscendo e usando nixos-install da fuori:

Esci dal chroot se ci sei dentro

exit

Esegui l'installazione

nixos-install --root /mnt/nixos

Imposta la password di root quando richiesto

Smonta tutto

umount -R /mnt/nixos

sync


**Riavvio:**

reboot


Al riavvio:
1. Rimuovi l'USB mentre il Chromebook si spegne
2. Alla schermata "OS verification is OFF": premi **Ctrl+D** (avvia da eMMC)
3. NixOS si avvierà

**Se il boot fallisce** (kernel panic / no root):
- Reinsersci l'USB, riavvia con Ctrl+U → torna nel live Alpine
- Controlla che `cgpt show /dev/mmcblk0` mostri `priority=15 successful=1` su KERN-A
- Verifica che `root=` in `cmdline-emmc.txt` sia `/dev/mmcblk0p2`
- Riscrivi il kpart con `dd` (Sezione 10)

---

## 13. Gestione degli aggiornamenti del kernel

> **Importante:** Depthcharge non aggiorna il kpart automaticamente.
> Ogni volta che il kernel cambia (dopo `nixos-rebuild switch`), devi
> **ricreare e riscrivere il kpart** manualmente dall'interno di NixOS.

### Workflow post-aggiornamento

1. Aggiorna il sistema

sudo nixos-rebuild switch

2. Identifica il nuovo kernel

NEW_KERNEL=$(readlink -f /run/current-system/kernel)

echo "Nuovo kernel: ${NEW_KERNEL}"

3. Vai nella directory di lavoro

cd /boot # dove hai copiato magneton.its e cmdline-emmc.txt (Sezione 9g)

4. Aggiorna il percorso kernel nel .its

(Sostituisci il percorso del kernel nel file magneton.its con quello nuovo)

sed -i "s|data = /incbin/(\"boot/Image.*\")|data = /incbin/(\"${NEW_KERNEL}\")|" magneton.its

5. Usa i DTB del nuovo kernel (se aggiornato)

I DTB magneton si trovano in:

/run/current-system/kernel-modules/lib/modules/$(uname -r)/dtb/mediatek/

oppure in /boot/dtb-${KVER}/ se hai estratto il tarball hexdump0815

6. Ricrea il FIT image

mkimage -f magneton.its magneton.itb

7. Firma il nuovo kpart

DEVKEYS="/nix/var/nix/profiles/default/share/vboot/devkeys"

oppure: find /nix/store -name "kernel.keyblock" 2>/dev/null | head -1 | xargs dirname

sudo futility vbutil_kernel \

--arch arm --version 1 \

--keyblock "${DEVKEYS}/kernel.keyblock" \

--signprivate "${DEVKEYS}/kernel_data_key.vbprivk" \

--bootloader cmdline-emmc.txt \

--config cmdline-emmc.txt \

--vmlinuz magneton.itb \

--pack kpart-emmc-new.bin

8. Scrivi il nuovo kpart

sudo dd if=kpart-emmc-new.bin of=/dev/mmcblk0p1 bs=4M status=progress

sudo sync

sudo cgpt add -i 1 -P 15 -T 1 -S 1 /dev/mmcblk0

echo "Kpart aggiornato. Riavvia."


### Script helper `/usr/local/bin/update-kpart`

Salva questo script in NixOS per semplificare gli aggiornamenti:

#!/usr/bin/env bash

set -euo pipefail

EMMC="${1:-/dev/mmcblk0}"

WORKDIR="/boot"

DEVKEYS="$(find /nix/store -name 'kernel.keyblock' 2>/dev/null | head -1 | xargs dirname)"

if [[ -z "${DEVKEYS}" ]]; then

echo "ERRORE: vboot dev keys non trovate. Installa vboot_utils."

exit 1

fi

NEW_KERNEL=$(readlink -f /run/current-system/kernel)

echo "Kernel: ${NEW_KERNEL}"

echo "Dev keys: ${DEVKEYS}"

cd "${WORKDIR}"

Aggiorna percorso kernel nel .its

sed -i "s|data = /incbin/(\"[^\"]*Image[^\"]*\")|data = /incbin/(\"${NEW_KERNEL}\")|" magneton.its

mkimage -f magneton.its magneton.itb

futility vbutil_kernel \

--arch arm --version 1 \

--keyblock "${DEVKEYS}/kernel.keyblock" \

--signprivate "${DEVKEYS}/kernel_data_key.vbprivk" \

--bootloader cmdline-emmc.txt \

--config cmdline-emmc.txt \

--vmlinuz magneton.itb \

--pack kpart-new.bin

echo "Scrittura kpart su ${EMMC}p1..."

dd if=kpart-new.bin of="${EMMC}p1" bs=4M status=progress

sync

cgpt add -i 1 -P 15 -T 1 -S 1 "${EMMC}"

echo "Fatto. Riavvia con: sudo reboot"


chmod +x /usr/local/bin/update-kpart


---

## 14. Stato dell'hardware

| Componente | Stato | Note |
|---|---|---|
| CPU MT8186 (8 core) | ✅ | cpufreq e thermal OK |
| Display 14" FHD | ✅ | DRM/KMS attivo, visibile dal boot |
| GPU Mali-G52 (Panfrost) | ✅ | Driver open source, Mesa ≥ 23.x |
| WiFi MT7921 | ✅ | Modulo `mt7921e`, firmware in `linux-firmware` |
| Tastiera / Touchpad | ✅ | Input PS/2 standard |
| eMMC interna | ✅ | `/dev/mmcblk0` |
| microSD | ✅ | `/dev/mmcblk1` |
| USB-C (charging + data) | ✅ | OK |
| USB-C DisplayPort | ✅ parziale | Richiede patch extra (kernel ≥ 6.12.18) |
| Audio | ⚠️ parziale | Patch incluse da kernel 6.12.42+; UCM profile da configurare |
| Bluetooth | ⚠️ parziale | Firmware `mt7921_bt*` necessario |
| Touchscreen (SKU dipendente) | ⚠️ | Varia per SKU 393216/217/218 |
| Suspend/Resume | ⚠️ non testato | Potenzialmente funzionante su 6.12+ |
| Webcam | ⚠️ non testato | Driver MIPI CSI da verificare |

**Workaround audio in configuration.nix:**

sound.enable = true;

hardware.alsa.enable = true;

environment.systemPackages = [ pkgs.alsa-ucm-conf pkgs.alsa-utils ];

boot.kernelModules = [ "snd_soc_mt8186_mt6366" ];


---

## 15. Ripristino di ChromeOS

Se vuoi tornare a ChromeOS:

1. Scarica l'immagine di recovery ufficiale da [chromeosdatarestore.withgoogle.com](https://chromeosdatarestore.withgoogle.com) cercando **STEELIX** o **MAGNETON**
2. Usa **Chromebook Recovery Utility** (estensione Chrome) su un altro PC per creare un USB di recovery
3. Sul Chromebook: tieni premuto **Esc + Refresh + Power** → Recovery Mode
4. Inserisci l'USB di recovery e segui le istruzioni

ChromeOS sovrascriverà l'intera eMMC e ripristinerà le GBB Flags ai valori di fabbrica.

---

## Riferimenti

- [hexdump0815/linux-mainline-mediatek-mt81xx-kernel](https://github.com/hexdump0815/linux-mainline-mediatek-mt81xx-kernel) — Kernel precompilati per corsola/MT8186, testati su magneton
- [postmarketOS Wiki — ChromeOS devices](https://wiki.postmarketos.org/wiki/ChromeOS_devices) — GBB flags, Developer Mode, WP
- [Chromebook Boot Flow — kernel.org](https://docs.kernel.org/arch/arm/google/chromebook-boot-flow.html) — Come Depthcharge seleziona il DTB dal FIT
- [Gentoo wiki — depthcharge bootable media](https://wiki.gentoo.org/wiki/Creating_bootable_media_for_depthcharge_based_devices) — Creazione FIT + vbutil_kernel
- [thefloweringash/kevin-nix](https://github.com/thefloweringash/kevin-nix) — NixOS su Chromebook ARM con modulo depthcharge
- [Mobile NixOS — lenovo-krane](https://mobile.nixos.org/devices/lenovo-krane.html) — kpart/depthcharge su MT8183 (stesso approccio)
- [alpernebbi/depthcharge-tools](https://github.com/alpernebbi/depthcharge-tools) — Tool alternativo `mkdepthcharge`

---

*Guida scritta Giugno 2026 — Kernel 6.12.66-stb-cbm+ / NixOS 25.05*