Sotto la scocca c'è un vero kernel Linux, ma sopra ci hanno costruito un mondo a parte: Binder, Zygote, ART, un sandbox per-app invece del multiutente classico. ADB, root, aggiornamenti A/B e Android Enterprise, spiegati a chi viene dal Linux "vero".
"Ho sbloccato il bootloader e ora l'app della banca non parte più" — il momento in cui scopri cosa fa davvero Play Integrity dietro le quinte.
Non è "Linux col touchscreen": è un kernel Linux vero, ma con uno userspace completamente riscritto da zero, con regole tutte sue.
Android usa il kernel Linux (con patch specifiche, vedi cap. 2), ma sopra non c'è niente di GNU: niente glibc (usa Bionic, una libc scritta da Google per essere più piccola e veloce su mobile), niente systemd (init è un binario Android dedicato con la propria sintassi .rc), niente coreutils GNU o BSD (una toolbox minimale chiamata toybox). Chi conosce bene un Linux desktop/server si sente "quasi a casa" in una shell Android, ma con molte sorprese sui dettagli.
AOSP (Android Open Source Project) è il codice sorgente, completamente aperto e gratuito. Quello che gira sulla maggior parte dei telefoni in vendita include però anche i Google Mobile Services (GMS): Play Store, Play Services, Play Protect — software proprietario che i produttori devono licenziare da Google e il cui dispositivo deve superare una certificazione di compatibilità (CDD/CTS) per ottenerlo.
Samsung (One UI), Xiaomi (HyperOS), altri vendor: tutti partono dallo stesso AOSP e ci sovrappongono un layer grafico e funzionale proprio. È il motivo per cui due telefoni con "la stessa versione Android" possono sembrare sistemi operativi diversi, e per cui gli aggiornamenti arrivano a velocità molto diverse (cap. 8).
Cinque strati, ognuno con un lavoro preciso. Il pezzo più particolare, Binder, non esiste in nessun altro Linux mainstream.
Su un Linux tradizionale, i processi comunicano con socket, pipe o D-Bus in userspace. Android ha bisogno di qualcosa di più veloce e più sicuro, perché ogni app è un processo separato che deve costantemente chiedere servizi ad altri processi (fotocamera, notifiche, posizione...). La soluzione è Binder: un driver del kernel (/dev/binder, esattamente il tipo di device driver visto nella guida Kernel Linux, cap. 8) che fa da "citofono" ultraveloce tra processi, con il vantaggio di portare gratis anche l'identità del chiamante (UID/PID) — fondamentale per verificare i permessi a ogni chiamata.
Zygote è un processo speciale avviato al boot che pre-carica le classi Java/Kotlin più comuni e inizializza la macchina virtuale ART una volta sola. Ogni volta che apri una nuova app, il sistema non parte da zero: fa un fork() di Zygote (esattamente il meccanismo di copy-on-write visto nella guida Kernel Linux, cap. 6) ottenendo un nuovo processo che eredita già tutto il lavoro di inizializzazione fatto in comune, pagando solo il costo di ciò che è specifico della singola app.
Due copie complete del sistema operativo sullo stesso telefono, così un aggiornamento non ti lascia mai senza un dispositivo funzionante.
| Partizione | Contiene |
|---|---|
/system | Il sistema operativo Android vero e proprio (framework, app di sistema) |
/vendor | HAL e blob proprietari del produttore del chip (Project Treble, cap. 2) |
/data | App installate, dati utente, database — cifrata (cap. 9) |
/boot | Kernel + ramdisk iniziale, l'equivalente Android di vmlinuz+initramfs |
/recovery | Ambiente minimale per aggiornamenti manuali e ripristino (sui device A/B spesso fusa in boot) |
Dal Android 7 in poi, molti dispositivi hanno due copie di ogni partizione di sistema (slot A e slot B). Un aggiornamento OTA scarica e installa la nuova versione sullo slot inattivo mentre continui a usare il telefono normalmente sull'altro; al riavvio successivo, il bootloader passa semplicemente al nuovo slot. Se qualcosa va storto, il dispositivo torna automaticamente allo slot precedente funzionante: zero rischio di un "brick" a metà aggiornamento, un problema reale sui vecchi dispositivi a partizione singola.
adb shell getprop ro.boot.slot_suffix
Uno parla con Android già avviato, l'altro parla col bootloader prima ancora che Android esista. Non sono intercambiabili.
Comunica con un'istanza Android già avviata (via USB o rete), tramite un demone (adbd) che gira sul telefono. Richiede il Debug USB attivo nelle Opzioni sviluppatore.
adb devices
adb shell # shell interattiva sul device
adb install app.apk
adb logcat # log di sistema in tempo reale (cap. 10)
adb push locale.txt /sdcard/
adb pull /sdcard/file.txt .
adb tcpip 5555 && adb connect 192.168.1.50:5555 # ADB via Wi-Fi
Opera prima che Android sia avviato, comunicando direttamente col bootloader (il telefono va riavviato in modalità fastboot). Usato per flashare partizioni, sbloccare il bootloader, installare recovery custom.
adb reboot bootloader # passa in modalita' fastboot
fastboot devices
fastboot flashing unlock # cancella TUTTI i dati (cap. 6)
fastboot flash boot nuovo_boot.img
fastboot reboot
adb shell su un device non modificato è una shell con l'UID limitato dell'utente shell, sufficiente per debug e diagnostica ma non per toccare i file di altre app o del sistema. Il root vero è un argomento separato, cap. 6.
Android capovolge il classico modello multiutente Unix: qui non è l'utente umano ad avere un UID, è ogni singola app.
Su un Linux server tradizionale, gli UID separano utenti umani diversi. Su Android, ogni app installata riceve automaticamente un UID Linux univoco al momento dell'installazione (tipicamente a partire da 10000): i suoi file in /data/data/com.esempio.app/ sono leggibili solo da quel preciso UID, esattamente come i permessi Unix classici impedirebbero a un utente di leggere i file privati di un altro. Un'app di terze parti non può leggere i dati di un'altra app senza un meccanismo esplicito (content provider, permessi condivisi) — è il sandbox più rigido che il modello Unix tradizionale possa offrire, applicato non alle persone ma al software stesso.
Prima di Android 6.0 (Marshmallow), tutti i permessi venivano accettati in blocco all'installazione ("prendere o lasciare"). Da Android 6.0 in poi, i permessi pericolosi (fotocamera, posizione, contatti, microfono...) vengono chiesti a runtime, quando l'app li usa davvero, e sono revocabili in qualsiasi momento dalle Impostazioni senza disinstallare l'app.
Dal Android 5.0 (Lollipop), SELinux gira in modalità enforcing su tutto il sistema (lo stesso framework LSM visto nella guida Kernel Linux, cap. 12, e nella guida AppArmor per il suo cugino Debian/Ubuntu): anche se un'app riuscisse a bypassare i permessi Android tradizionali, le policy SELinux limitano comunque cosa può fare davvero a livello di kernel. È una delle ragioni per cui exploit di privilege escalation completi sono diventati molto più rari nel tempo.
"Rootare" un Android moderno non significa più quello che significava dieci anni fa. Ecco come funziona davvero oggi, e cosa costa farlo.
Il metodo moderno standard non modifica /system (che oltretutto, come su macOS, è sempre più spesso protetto da verifica di integrità, cap. 12): Magisk applica una patch al boot image, iniettando il proprio codice all'avvio senza toccare le partizioni di sistema originali. Questo permette anche di nascondere selettivamente il root a singole app (utile perché molte app bancarie si rifiutano di funzionare su device rootati).
# 1. Sblocca il bootloader (cancella tutti i dati)
fastboot flashing unlock
# 2. Estrai il boot.img originale del firmware del tuo device
# 3. Patchalo con l'app Magisk (genera magisk_patched.img)
# 4. Flasha l'immagine patchata al posto del boot originale
fastboot flash boot magisk_patched.img
Un recovery personalizzato sostituisce quello di stock con un'interfaccia più ricca: backup completi del sistema (Nandroid), flash di pacchetti ZIP (custom ROM, Magisk), accesso a shell avanzata anche a telefono spento normalmente.
L'equivalente Android di un .deb o un .dmg, con la sua anatomia e le sue regole di firma.
| Componente | Cosa contiene |
|---|---|
AndroidManifest.xml | Permessi richiesti, componenti dell'app, versione minima supportata |
classes.dex | Bytecode compilato per la Dalvik/ART virtual machine (non bytecode JVM standard) |
res/ | Layout, immagini, stringhe localizzate |
| Firma digitale | APK Signing (v1-v4): garantisce che gli update provengano dallo stesso sviluppatore dell'originale |
Installare un APK fuori dal Play Store, richiede di abilitare "Installa app sconosciute" per l'app specifica che sta facendo l'installazione (browser, file manager...) — un permesso concesso per singola sorgente, non un interruttore globale come nelle vecchie versioni Android.
Il formato di pubblicazione moderno su Play Store: invece di un unico APK universale, Google genera al volo APK ottimizzati per lo specifico dispositivo (architettura CPU, risoluzione schermo, lingua), riducendo la dimensione di download reale per l'utente finale.
La frammentazione degli aggiornamenti Android non è (solo) pigrizia dei produttori: per anni è stata un problema strutturale dell'architettura stessa.
Prima del 2017, framework Android e driver hardware del chip erano fusi in un'unica immagine di sistema: aggiornare Android richiedeva che ogni singolo produttore di chip (Qualcomm, MediaTek...) prima aggiornasse i propri driver per la nuova versione, poi il produttore del telefono li integrasse. Una catena lenta, che lasciava molti dispositivi fermi alla versione con cui erano usciti.
Separa il framework OS (/system) dall'implementazione hardware del vendor (/vendor, cap. 3) tramite un'interfaccia stabile (HAL, cap. 2). In teoria, questo permette a Google/al produttore di aggiornare il framework senza aspettare che il chip vendor aggiorni i propri driver, perché l'interfaccia tra i due resta compatibile.
Va oltre: alcuni componenti core del sistema diventano moduli APEX aggiornabili direttamente tramite Play Store, esattamente come un'app, senza bisogno di un aggiornamento OTA completo del sistema operativo. Sicurezza e bugfix di componenti critici arrivano più velocemente, indipendentemente dal produttore del telefono.
Il parallelo diretto del FileVault visto nella guida macOS, ma con una particolarità che macOS non ha: alcune app funzionano anche a telefono ancora bloccato.
Dal Android 7 (Nougat), la File-Based Encryption cifra ogni file con una chiave potenzialmente diversa, invece di cifrare l'intero volume con un'unica chiave (Full-Disk Encryption, il metodo precedente). Questo abilita Direct Boot: alcune app (sveglia, chiamate in arrivo, notifiche accessibilità) possono girare e accedere ai propri dati anche prima che l'utente inserisca il PIN/password al riavvio, mentre i dati "sensibili" restano cifrati e inaccessibili finché non sblocchi.
Un'API di sistema che permette alle app di generare e usare chiavi crittografiche senza mai vederne il valore grezzo: le operazioni crittografiche avvengono in un ambiente isolato (TEE, Trusted Execution Environment, o hardware dedicato StrongBox sui device più recenti). Se il telefono viene compromesso a livello di sistema operativo, le chiavi restano comunque protette dall'isolamento hardware.
Il ruolo di Android Keystore/StrongBox è concettualmente identico al Secure Enclave visto nella guida macOS, cap. 10: un coprocessore isolato che custodisce le chiavi senza mai esporle al sistema operativo principale, così anche un attacco software non può estrarle direttamente.
Gli strumenti che usi per capire perché un'app crasha, una batteria si scarica troppo in fretta, o un servizio non parte.
adb logcat
adb logcat *:E # solo livello Error e superiore
adb logcat --pid=$(adb shell pidof com.esempio.app)
adb logcat -c # pulisce il buffer
I livelli, dal meno al più grave: Verbose, Debug, Info, Warning, Error.
adb shell dumpsys battery
adb shell dumpsys package com.esempio.app
adb shell dumpsys activity | less
adb bugreport report.zip # tutto insieme, per un ticket di supporto
Strumento open source (non ufficiale Google, ma diventato standard de facto) che rispecchia lo schermo del device sul computer via ADB, con input da mouse/tastiera: comodo per demo, supporto remoto, o semplicemente testare senza tenere in mano il telefono.
Come si amministrano centinaia di telefoni aziendali, con un modello diverso (e in un certo senso più flessibile) di quello Apple.
Su un telefono personale dell'utente, l'azienda può creare un profilo di lavoro isolato: app aziendali, email, dati separati crittograficamente dal resto del telefono, gestibili/cancellabili da remoto senza toccare i dati personali dell'utente. Le app appaiono con una piccola icona di valigetta per distinguerle.
Fully Managed: l'intero dispositivo è di proprietà e sotto controllo aziendale (tipico per device forniti dall'azienda). Dedicated Device (kiosk mode): il telefono esegue solo una o poche app specifiche, tipico per tablet di reception, POS, dispositivi logistica.
Come un'app scopre se il telefono su cui gira è "quello che dice di essere", e perché il root spesso rompe questa fiducia.
Ogni stadio del boot verifica crittograficamente il successivo prima di eseguirlo: il bootloader verifica il kernel, il kernel verifica (via dm-verity) che /system non sia stato alterato rispetto a un hash firmato noto. È concettualmente lo stesso principio del Secure Boot UEFI e del Signed System Volume di macOS: una catena di fiducia dall'hardware fino al sistema operativo completo.
Successore di SafetyNet (deprecato nel 2023), permette a un'app di chiedere a Google "questo dispositivo è genuino? Il bootloader è bloccato? Gira su hardware certificato o su un emulatore?" prima di concedere funzionalità sensibili: pagamenti, DRM video ad alta qualità (Widevine L1), anti-cheat nei giochi.
Un bootloader sbloccato (cap. 6) o un boot image patchato da Magisk alterano proprio quello che AVB e Play Integrity verificano. Alcune app rifiutano di funzionare, altre degradano funzionalità (streaming solo in bassa qualità). Magisk include moduli che tentano di "nascondere" questi segnali, ma è una rincorsa costante contro le difese di Google, non una soluzione garantita e permanente.
Tutto quello che serve, su una pagina. Bookmark questa sezione e dimentica il resto.
adb devices
adb shell
adb install app.apk
adb logcat *:E
adb bugreport report.zip
adb reboot bootloader
fastboot devices
fastboot flashing unlock
fastboot flash boot img.img
fastboot reboot
enforcing, mai disabilitato per "comodità"dumpsys battery/activity prima di dare la colpa "al telefono lento"