Portage Linux pour téléphone
Sur un téléphone en cours de portage mainline, une itération de débogage coûte une construction, un flash et un démarrage (5-10 min), et les correctifs aveugles sont bien plus souvent réfutés qu'appliqués. Suivez strictement cet ordre.
0. Préparation du port
À faire une fois, avant le premier flash. Deux choses en font une phase 0 plutôt qu'une simple paperasse : le système d'origine est la source de recherche la plus fiable que vous aurez jamais pour cette carte, et certaines parties cessent d'être lisibles dès que vous commencez à écraser des partitions.
Établissez d'abord la cible, car chaque réponse ultérieure en dépend :
- Identité exacte du périphérique — nom commercial, nom de code, SoC, variante régionale ou de stockage. Les variantes frères d'un même nom commercial diffèrent couramment par l'écran, le contrôleur tactile ou le modem, et un correctif recherché sur la mauvaise variante semble plausible mais échoue.
- Distribution cible et init — postmarketOS, Mobian, NixOS, Debian simple, autre. Cela détermine l'empaquetage, la disposition de l'image et la source de la phase 2 la plus pertinente.
- Topologie de démarrage — A/B ou non A/B, disposition des slots, état de verrouillage du chargeur d'amorçage. Chargeurs d'amorçage déverrouillés uniquement. Si le chargeur d'amorçage est verrouillé, arrêtez : cette compétence ne déverrouille pas les chargeurs d'amorçage et ne fournit pas de procédures de déverrouillage — orientez l'utilisateur vers les instructions de son OEM et reprenez une fois le périphérique déverrouillé.
- Récupération — si une récupération personnalisée est installée. Pas une exigence : une commodité pour sauvegarder et restaurer.
Ensuite, effectuez une sauvegarde complète de toutes les partitions sauf userdata :
- Ignorez userdata : c'est le volume principal, ce sont les données de l'utilisateur, et c'est la seule partition que vous pouvez vous permettre de perdre.
- Sauvegardez les partitions uniques au périphérique et ne les publiez jamais. NV/EFS du modem, persist, et leurs frères d'étalonnage contiennent l'IMEI, l'étalonnage radio et le calibrage des capteurs de cet appareil individuel. Elles ne sont reproductibles à partir d'aucune image sur internet, et un port qui les corrompt laisse un téléphone qui ne peut pas s'enregistrer sur un réseau. Traitez-les à la fois comme critiques et privées.
- Hachez chaque image et enregistrez les hachages avec la table de partitions à côté. Plus tard, vous devrez répondre à la question "ce qui est sur le périphérique est-il toujours ce que j'ai sauvegardé", et seul un hachage le permet.
- Vérifiez que la sauvegarde est réellement restaurable avant le premier flash risqué, pas après.
Ce que vaut la sauvegarde comme recherche, au-delà de la récupération :
- Le DTB d'origine — vérité terrain pour l'arborescence de périphériques de cette carte, et l'arbitre en cas de désaccord du dtsi du SoC frère.
- Les blobs de firmware et leur ordre de chargement — ce que la pile du fabricant livre réellement et où elle s'attend à le trouver.
- La ligne de commande du noyau du fabricant et la disposition de l'image de démarrage — décalages, version d'en-tête et arguments donnés au noyau d'origine.
- La chaîne de version exacte du noyau —
uname -aou/proc/versionde la ROM d'origine, tant qu'elle peut encore être lue (également extractible plus tard de l'image de démarrage sauvegardée). C'est l'empreinte digitale qui sélectionne la bonne version source OEM publiée sous GPL en phase 2 ; les fabricants livrent plusieurs versions et elles diffèrent. - Configurations du fabricant — configuration des capteurs, du modem et de la HAL décrivant les interfaces que le pilote mainline devra satisfaire.
Enfin, définissez les conventions de travail que le reste de la session suppose : un répertoire côté hôte qui accumule un sous-répertoire par démarrage pour les logs et pstore, et une note de quel chemin de récupération est connu pour fonctionner. Si une sauvegarde existe déjà d'une tentative précédente, confirmez qu'elle couvre ces partitions et que ses hachages sont toujours vérifiés, plutôt que de le supposer.
1. Recueillir les preuves depuis le périphérique en fonctionnement d'abord
Capturez le dmesg complet de l'exécution en échec avant de modifier quoi que ce soit. Activez les boutons de débogage pertinents avant de reproduire (par exemple echo 0xffffffff > /sys/module/<driver>/parameters/debug_mask), car une deuxième reproduction coûte un autre démarrage.
Canaux de preuve, par ordre de fiabilité approximatif :
- Shell en direct sur le réseau ou USB. Canal le moins coûteux ; utilisez-le pour tout ce que le périphérique survit.
- pstore. Une fois systemd démarré, récoltez depuis
/var/lib/systemd/pstore/, pas/sys/fs/pstore/—systemd-pstore.servicedéplace chaque enregistrement tôt dans le démarrage, donc un/sys/fs/pstorevide n'est pas une preuve qu'aucun crash n'a été enregistré. La région console est généralement un seul slot : copiez-la sur l'hôte avant de faire quoi que ce soit d'autre, sinon le prochain crash l'écrase également dans l'archive. - ramoops. Considérez-le comme avec pertes. La rétention de charge DRAM se dégrade pendant l'intervalle hors tension — mesurée à environ 6,5 % des bits sur un appareil, suffisamment pour faire échouer l'ECC sur les en-têtes de zone et perdre complètement un enregistrement. Grep les enregistrements flous. Ce qui corrompt la région est le temps passé hors tension, pas le temps passé à spammer avant de couper l'alimentation, donc laissez un appareil bloqué journaliser aussi longtemps que la zone console peut contenir, puis coupez et rallumez rapidement. Vérifiez la taille de la zone avant de supposer que vous devez vous dépêcher : une zone console de 4 Mio absorbe des heures de spam de watchdog avant de s'enrouler.
- Console USB ACM au niveau du noyau (
CONFIG_U_SERIAL_CONSOLE=yplusconsole=ttyGS0sur la ligne de commande). Le seul canal qui survit à un blocage, et vaut son coût de flash unique tôt dans un port. Un getty ACM en espace utilisateur n'en survit pas un — il nécessite un CPU planifiable, et produit zéro octet tout en s'énumérant toujours bien sur USB. Les deux moitiés sont requises : le symbole de configuration seul laisse la fonctionnalité inactive.
Cinq règles qui transforment systématiquement l'inférence en mesure :
- Confirmez ce qui est réellement flashé en lisant la partition, jamais à partir de notes et jamais à partir d'un journal de construction. Lisez avec
iflag=directpour que la lecture elle-même ne perturbe pas ce que vous déboguez. Méfiez-vous des comparaisons de taille uniquement — les images de démarrage sont rembourrées à une taille fixe, donc une longueur égale entre deux images différentes ne prouve rien. Hachez la charge utile. - Lire une interface de débogage peut créer le symptôme. Les nœuds d'état de crash DRM/GPU sont le cas classique : en échantillonner un pendant que le GPU soumet activement synthétise des lignes de défaut et de récupération qui ne se sont jamais produites (mesuré : cinq lectures, cinq paires défaut/récupération, contre aucune observée non). Avant de faire confiance à une ligne de log, vérifiez si votre propre observation l'a produite.
- Capturez la réponse brute d'un rejet avant d'interpréter l'errno mappé. L'erreur mappée d'un appel de firmware était ambiguë —
EINVALpouvait signifier un mauvais encodage ou une politique refusée — jusqu'à ce que le débogage dynamique dans l'emballage d'appel expose les mots de réponse bruts : un appel bien formé portant un refus explicite. C'est de la politique, pas de l'encodage — le verdict opposé, avec l'étape suivante opposée. Classez chaque rejet de firmware comme mauvais encodage, refusé par politique, ou non trouvé avant d'agir. La règle miroir : un négatif propre et bien formé est une preuve positive — un non trouvé d'une recherche correctement formée valide l'encodage et élimine une branche du plan sans jamais toucher au chargeur. - Une mesure en concurrence avec une condition non contrôlée renvoie un nombre plausible et vide. Un benchmark a marqué 55 en deux secondes : le compositeur détenait le DRM master, chaque scène échouait, et le nombre semblait réel jusqu'à ce que la condition soit vérifiée. La comparaison valide — 132 → 485 — nécessitait l'arrêt du compositeur pour les deux exécutions, comparé uniquement au sein de cette génération. Avant de faire confiance à un benchmark, nommez la condition qui pourrait l'invalider et vérifiez qu'elle a tenu pour chaque exécution.
- Enregistrez les règles que vous retirez. Le portage accumule rapidement du folklore, et une règle qui était correcte pour une révision matérielle ou une taille de tampon devient activement trompeuse après un changement. Gardez la version révoquée à côté de la version actuelle avec ce qui a changé, afin que la session suivante sache quel conseil a été testé sous contrainte.
Pièges côté hôte à anticiper :
timeout N ssh <device> '<cmd>'tue uniquement le client local ; le processus distant continue. Suivez avec un kill explicite.pgrep -fetpkill -fs'exécutent sur ce même chemin ssh et s'auto-correspondent avec leur propre shell distant. Filtrez le matcher, ou faites correspondre par PID.findnécessite-Llorsque le chemin de départ est un lien symbolique, sinon il renvoie silencieusement vide.- Tout wrapper ou hook qui réécrit la sortie de commande — filtres de jetons, pagers, formateurs — corrompra les preuves, parfois en inversant un test plutôt qu'en le cassant visiblement. Utilisez la commande brute pour tout ce que vous allez consigner comme constatation.
2. Recherche avant implémentation — toutes ces sources
La recherche précède toujours l'implémentation. Ce qu'elle consomme dépend de ce que vous faites :
- Enquête sur une défaillance — les preuves de la phase 1. Capturez-les d'abord ; rechercher un symptôme que vous n'avez pas réellement lu, c'est deviner avec des citations.
- Ajout d'une capacité — un pilote, un périphérique, un sous-système qui n'a jamais été abordé — les artefacts de la phase 0 sont les données du périphérique. Le DTB d'origine, les configurations du fabricant et la disposition du firmware décrivent comment cette carte s'attend à être pilotée, et ils sont aussi faisant autorité ici qu'un journal de crash l'est là.
Dans les deux cas, avant d'écrire quoi que ce soit :
- Raisonnez sur le sous-système — identifiez quel pilote, liaison ou interface de firmware possède la défaillance, ou posséderait la nouvelle capacité. Les compétences à votre disposition sont listées dans votre contexte de session : parcourez cette liste maintenant, et si elle contient une compétence de développement du noyau ou d'analyse de crash, lisez-la avant de continuer — ses détails au niveau registre et de liaison sont exactement ce dont cette étape a besoin. Raisonnez-la directement uniquement quand aucune n'est listée.
- Recherchez les bibliothèques et outils en espace utilisateur impliqués — docs actuels, pas d'API rappelée. Si une compétence de récupération de documentation est dans cette même liste de session, exécutez-la plutôt que de vous souvenir des signatures de mémoire.
- Recherche web sur les six familles de sources (les sous-agents parallèles fonctionnent bien ici ; si une compétence de recherche web est dans cette liste, préférez-la pour la mise en cache, car les sessions relisent les mêmes pages) :
- Mainline — lore.kernel.org, la source du pilote, les liaisons DT et le dtsi du SoC frère le plus proche (même famille, ou même génération RPM). Avant de définir une campagne "porter le pilote aval", balayez ce que mainline a déjà pour l'interface : son API exportée, si elle atteint l'espace utilisateur ou est uniquement interne au noyau, et ses portes — listes d'autorisation machine, sémantiques "préchargé par le chargeur d'amorçage", intégré plutôt que module (mesuré : un tel balayage a réduit un port aval de 9,4 k lignes à un module de sonde d'environ 300 lignes, parce que mainline transportait déjà l'interface en interne au noyau derrière une liste d'autorisation — le plan est devenu piloter l'API existante, pas la porter).
- Noyau aval du fabricant — la source OEM publiée sous GPL. GPLv2 oblige les OEM Android à publier les sources du noyau qu'ils ont livrées, donc une version exacte pour cet appareil existe généralement : le portail open source de l'OEM (Samsung, Sony, Xiaomi, Fairphone, OnePlus/OPPO et Motorola en ont tous un), leurs miroirs GitHub/GitLab, et des archives communautaires comme XDA lorsqu'un lien de portail est mort. Sélectionnez l'archive dont la chaîne de version correspond à
/proc/versionde la phase 0 — les fabricants en publient plusieurs, et elles diffèrent. La qualité de conformité varie, donc traitez l'arbre comme un oracle à miner — le dts de la carte et la defconfig pour cet appareil exact, et les pilotes aval hors arbre (tactile, écran, chargeur, colle de modem) avec leurs séquences de registres et leurs poignées de main de firmware — plutôt que de supposer qu'il se construit. Lorsqu'aucune version exacte n'émerge, la version d'un appareil frère transporte généralement toujours le dtsi du SoC. Encore mieux : le DTB d'origine extrait de l'appareil lui-même (ddle slot de démarrage intact, scannez pourd00dfeed,dtc -I dtb -O dts). C'est la vérité terrain pour cette carte et a corrigé des suppositions erronées de SoC frère plus d'une fois — y compris un ID de flux SMMU que le SoC frère a mal et que le DTB d'origine a bien. - postmarketOS — paquets de périphériques pmaports et APKBUILD, demandes de fusion, pages wiki des périphériques, et l'arbre SoC-mainline.
- Halium / UBports — arbres
halium/android_device_*, configurationshybris-bootet ports de périphériques UBports. Halium exécute la pile Android du fabricant plutôt que mainline, ce qui en fait la meilleure source pour savoir comment le firmware du fabricant s'attend à être piloté : chemins et ordre de chargement des blobs de firmware, interfaces de propriétés et de sockets que les démons attendent, configurations du HAL des capteurs et du modem. Lorsqu'un pilote mainline sonde mais que la poignée de main du firmware échoue — ou lorsque vous avez besoin de savoir quelle poignée de main un périphérique non encore pris en charge attend — c'est généralement là que la pièce manquante est écrite. - Mobian — les dépôts de périphériques Debian.
- NixOS — modèles mobile-nixos et empaquetage nixpkgs.
Les résultats minces sont le cas normal, pas un blocage. La plupart de ce dont un port a besoin n'a jamais été fait sur cette carte, et souvent pas du tout sur ce SoC. Six sources ne rapportant rien signifie que personne n'a publié le travail — cela ne signifie jamais que le travail doit s'arrêter ou être rendu. Lorsqu'il n'y a pas de précédent, les réponses sont encore dans les artefacts primaires : le pilote aval hors arbre qui pilote déjà le périphérique (séquences de registres, poignée de main de firmware, câblage GPIO et régulateur), le propre nœud du DTB d'origine pour celui-ci, le config HAL du fabricant nommant ce que l'espace utilisateur attend, et le pilote mainline le plus proche pour la même classe de périphérique comme modèle structurel. Lisez-les, déduisez la conception et écrivez la pièce manquante — un nœud DT, un quirk, un petit pilote. Rédiger cette pièce est l'état terminal ordinaire d'un portage, pas une exception à justifier ; la sauvegarde de la phase 0 et la règle d'une variable par flash existent précisément pour qu'une déduction erronée coûte un démarrage et une ligne de registre, comme n'importe quelle autre réfutation.
Un balayage vide et une analyse vide sont des constatations différentes. Un balayage vide des sources signifie que personne n'a publié le travail. Une analyse vide — une extraction qui ne renvoie rien — est nulle jusqu'à ce que la même méthode ait été exécutée sur un positif connu et que sa couverture soit vérifiée : nombre de fichiers, listes de segments, ce que le glob a réellement correspondu. Presque-erreurs mesurés : un glob a correspondu à 9 des 27 segments de firmware et a presque enregistré un faux "le firmware l'omet" ; une analyse de bibliothèque n'est devenue fiable qu'une fois qu'elle a trouvé un identifiant de puce connu comme contrôle positif.
Les identifiants aval sont les p…
[Le reste du contenu a été tronqué dans la demande originale.]