Analyse des problèmes de démarrage d'un boot.img
L'une des choses à faire pour dépanner un probleme de boot lié au ramdisk, est d'essayer un ramdisk qui est connu pour fonctionner.
De l'article précedent, j'ai deux TWRP, un qui est fonctionnel, l'autre que j'essaye de dépanner.
Je vais donc faire des tests croisés, gràce à l'outil de osm0sis: https://shaarli.nailyk.fr/?laIuDw (lien vers le shaarli au cas où il disparaisse d'ici: https://github.com/osm0sis/mkbootimg )
mkdir /tmp/mkbootimg cd $_ wget "https://github.com/osm0sis/mkbootimg/archive/master.zip" unzip master.zip cd mkbootimg-master make -j 4
L'aide:
nailyk@nailyk :) % ./unpackbootimg /tmp/mkbootimg/mkbootimg-master usage: unpackbootimg -i|--input boot.img [ -o|--output output_directory] [ -p|--pagesize <size-in-hexadecimal> ]
Le TWRP en train d'être dépanné: recovery.img
Le connu pour fonctionner: twrp_z3_2018-11-03_unsecure.img
Extraction:
./unpackbootimg -i /tmp/recovery.img -o BAD/ ./unpackbootimg -i /tmp/twrp_z3_2018-11-03_unsecure.img -o OK/ -rw-r--r-- 1 nailyk nailyk 9 nov. 3 17:05 recovery.img-base -rw-r--r-- 1 nailyk nailyk 1 nov. 3 17:05 recovery.img-board -rw-r--r-- 1 nailyk nailyk 194 nov. 3 17:05 recovery.img-cmdline -rw-r--r-- 1 nailyk nailyk 274K nov. 3 17:05 recovery.img-dtb -rw-r--r-- 1 nailyk nailyk 5 nov. 3 17:05 recovery.img-hash -rw-r--r-- 1 nailyk nailyk 9 nov. 3 17:05 recovery.img-kerneloff -rw-r--r-- 1 nailyk nailyk 8 nov. 3 17:05 recovery.img-oslevel -rw-r--r-- 1 nailyk nailyk 6 nov. 3 17:05 recovery.img-osversion -rw-r--r-- 1 nailyk nailyk 5 nov. 3 17:05 recovery.img-pagesize -rw-r--r-- 1 nailyk nailyk 5,9M nov. 3 17:05 recovery.img-ramdisk.gz -rw-r--r-- 1 nailyk nailyk 9 nov. 3 17:05 recovery.img-ramdiskoff -rw-r--r-- 1 nailyk nailyk 9 nov. 3 17:05 recovery.img-secondoff -rw-r--r-- 1 nailyk nailyk 9 nov. 3 17:05 recovery.img-tagsoff -rw-r--r-- 1 nailyk nailyk 5,0M nov. 3 17:05 recovery.img-zImage
Les fichiers ont des noms comprehensible.
Etape suivante: vérifier que le ramdisk n'est pas corrompu:
(ici, le ramdisk est en lzma, pas en gz car il fallait une compression plus forte pour faire tenir le recovery.img dans la partion, et seul ces deux formats sont supportés par le bootloader)
<pre> mkdir ramdisk cd ramdisk mv ../recovery.img-ramdisk.gz ../recovery.img-ramdisk.gz.lzma lzma -d ../recovery.img-ramdisk.gz.lzma cpio -i < ../recovery.img-ramdisk.gz ls -1 acct bin bugreports charger config d data default.prop dev etc file_contexts file_contexts.bin fstab.qcom init.rc init.recovery.hlthchrg.rc init.recovery.qcom.rc init.recovery.service.rc init.recovery.usb.rc license mnt odm oem plat_file_contexts plat_hwservice_contexts plat_property_contexts plat_seapp_contexts plat_service_contexts proc product prop.default res sbin sdcard sepolicy storage sys system tmp twres ueventd.qcom.rc ueventd.rc vendor_file_contexts vendor_hwservice_contexts vendor_property_contexts vendor_seapp_contexts vendor_service_contexts vndservice_contexts
Première chose qui saute aux yeux, il manque le binaire /init
Sony faisant les choses très bien, il faut un init particulier pour pouvoir booter l'ordiphone correctement, et, lors de l'article précédent, pour résoudre des problèmes de compilation, j'ai purement et simplement enlevé l'init car il ne voulait pas construire.
Ceci pourrait être une piste à suivre, mais le kernel s'est plaint de ne pas trouver le ramdisk, pas de ne pas avoir d'init.
Ceci devrait être facile à vérifier avec les tests croisés.
Construction d'une image de boot de test:
./mkbootimg error: no output filename specified usage: mkbootimg --kernel <filename> [ --ramdisk <filename> ] [ --second <2ndbootloader-filename> ] [ --recovery_dtbo <recoverydtbo-filename> ] [ --cmdline <kernel-commandline> ] [ --board <boardname> ] [ --base <address> ] [ --pagesize <pagesize> ] [ --dt <dtb-filename> ] [ --kernel_offset <base offset> ] [ --ramdisk_offset <base offset> ] [ --second_offset <base offset> ] [ --tags_offset <base offset> ] [ --os_version <A.B.C version> ] [ --os_patch_level <YYYY-MM-DD date> ] [ --header_version <version number> ] [ --hash <sha1(default)|sha256> ] [ --id ] -o|--output <filename>
Mis à part les secondary, il faut tout spécifier:
./mkbootimg --kernel BAD/recovery.img-zImage \ --ramdisk OK/twrp_z3_2018-11-03_unsecure.img-ramdisk.gz \ --cmdline "$(cat BAD/recovery.img-cmdline)" \ --base $(cat BAD/recovery.img-base ) \ --pagesize $(cat BAD/recovery.img-pagesize ) \ --dt BAD/recovery.img-dtb \ --kernel_offset $(cat BAD/recovery.img-kerneloff ) \ --ramdisk_offset $(cat BAD/recovery.img-ramdiskoff ) \ --output /tmp/test.img file /tmp/test.img /tmp/test.img: Android bootimg, kernel (0x8000), ramdisk (0x2000000), page size: 2048, cmdline (msm_rtb.filter=0x3F ehci-hcd.park=3 dwc3.maximum_speed=high dwc3_msm.prop_chg_detect=Y coherent)
Tout semble ok, plus qu'a tester ;)
fastboot boot /tmp/test.img adb shell uname -a Linux localhost 3.4.123-OmniROM-g4332f698b4d-dirty #2 SMP PREEMPT Sat Nov 3 16:02:59 CET 2018 armv7l
J'avais taggué le kernel que je build -123 pour pouvoir le repérer. Ici c'est bien lui qui démarre, donc il s'agit bien d'un problème ramdisk.
Plus qu'a savoir quelle étape du ramdisk se passe mal ;)
Etant donné qu'ici ma théorie est que les binaire d'init sont manquant, prenons ceux du bon ramdisk pour les mettre dans l'autre:
cp ../../OK/ramdisk/sbin/init_sony ./sbin cp ../../OK/ramdisk/init ./init find . -print |cpio -H newc -o |gzip -9 > ../ramdisk.cpio.gz ./mkbootimg --kernel BAD/recovery.img-zImage --ramdisk BAD/ramdisk.cpio.gz --cmdline "$(cat BAD/recovery.img-cmdline)" --base $(cat BAD/recovery.img-base ) \/mkbootimg-master --pagesize $(cat BAD/recovery.img-pagesize ) \ --dt BAD/recovery.img-dtb \ --kernel_offset $(cat BAD/recovery.img-kerneloff ) \ --ramdisk_offset $(cat BAD/recovery.img-ramdiskoff ) \ --output /tmp/test.img
Aucune importance de faire du gzip ici car l'image est juste démarrée, sans être flashée, pas de problème de taille de partition.
Après le fastboot boot l'ordiphone redémarre en mode bootloader. C'est bon signe, car le comportement à changé.
Dans le last_kmsg:
selinux: SELinux: Loaded policy from /sepolicy type=1404 audit(7898.910:3): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295 selinux: selinux_android_file_context: Error getting file context handle (No such file or directory) type=1400 audit(7898.913:4): avc: denied { dac_override } for pid=1 comm="init" capability=1 scontext=u:r:kernel:s0 tcontext=u:r:kernel:s0 tclass=capability permissive=0 init: execv("/init") failed: Permission denied init: Security failure... init: panic: rebooting to bootloader
Le ramdisk démarre bien, mais selinux empeche l'init de démarrer. De plus on note que le contexte est 'enforcing' ce qui va poser des problèmes.
Il faut donc:
- désactiver selinux pour l'instant,
- réparer le build du /init & /sbin/init_sony pour avoir une image fonctionnelle!