Comment compiler des fichiers supplémentaires dans le répertoire racine d'une ROM Android

8

Je construis un noyau Android personnalisé basé sur le code source du noyau de la ROM Cyanogenmod. Je voudrais ajouter des dossiers et des fichiers dans le dossier racine du système d'exploitation ( /). Par exemple, après avoir compilé mon noyau, j'aimerais qu'un dossier supplémentaire nommé toto(chemin absolu = /toto) soit créé.

Je ne sais vraiment pas quels fichiers doivent être modifiés et comment faire le travail.


Remarque: Si vous êtes un utilisateur Android (pas un développeur ROM) qui souhaite ajouter des fichiers à votre rootfs, veuillez plutôt consulter la question Android.SE appropriée .

deadeert
la source
3
Android est un système Linux, mais comme la question est spécifique à Android, pas à tous les Unix. Un meilleur endroit pour cela est sur android.stackexchange.com
enedil
@enedil D'une manière générale, les questions Android sont hors sujet ici, car Android n'est pas Linux au sens commun du terme (il utilise simplement un noyau Linux). Cependant, la même question s'appliquerait à d'autres systèmes Linux embarqués, donc je pense que ça va ici.
Gilles 'SO- arrête d'être méchant'
@Graeme En fait, le système de fichiers racine est compilé dans chaque noyau. Habituellement, il est vide et nous y décompressons une archive cpio - notre image initramfs. Vous pouvez y mettre tout ce que vous voulez au moment de la compilation.
mikeserv
@enedil Dans ce cas, je crois que cette question est entièrement sur le sujet. Android diffère le plus des autres Unix, userspace,mais des autres Linux, la in-kerneldifférence ne représente qu'une poignée de correctifs. En fait, la popularité d'Android est une force motrice majeure derrière le développement du noyau, et ce depuis quelques années. Jetez un œil aux changelogs de kernel.org et décidez par vous-même de leur pertinence pour les systèmes mobiles - Android en particulier.
mikeserv du
Une question similaire sur Android.SE: comment décompresser et modifier boot.imgpour le portage ROM? : les réponses expliquent comment récupérer et modifier le boot.imgfichier, ce qui permet de modifier de manière persistante le contenu du répertoire racine de l'appareil.
WhiteWinterWolf

Réponses:

7

Sur Android, comme sur de nombreux systèmes basés sur Linux, le noyau monte d' abord un initramfs sur /. Les initramfs sont stockés dans la RAM; il est chargé à partir d'une archive CPIO qui est stockée avec le noyau lui-même (ou à un autre endroit où le chargeur de démarrage peut le trouver).

La plupart des systèmes Linux de bureau ont un petit initramfs qui contient juste assez de programmes et de fichiers de configuration pour monter le vrai système de fichiers racine, qui est ensuite monté /, remplaçant les initramfs. Android, comme certains systèmes Linux embarqués, maintient les initramfs montés pour toujours. Les initramfs Android contient /init, adbdet quelques fichiers de configuration.

Pour CyanogenMod, vous pouvez trouver des instructions de construction dans le guide de portage . Vous souhaitez copier plus de fichiers sur le disque virtuel (l'image initramfs, dans la terminologie Android), vous devez donc les ajouter à la PRODUCT_COPY_FILESliste dans le device_*.mkmakefile de votre appareil.

Gilles 'SO- arrête d'être méchant'
la source
En fait, notre fichier initramfs image est ce qui contient ces fichiers de configuration, le initramfs système de fichiers est compilé dans chaque noyau.
mikeserv
1
@mikeserv Je vous invite à vous familiariser avec le concept de métonymie . L'écriture technique l'utilise moins que la parole ordinaire, mais elle est utilisée occasionnellement.
Gilles 'SO- arrête d'être méchant'
Je vais le faire, mais je dois d'abord le vérifier dans le dictionnaire ...
mikeserv
Vous soulevez un très bon point, et comme je l'ai déjà dit, la seule raison pour laquelle je suis catégorique à ce sujet est qu'il semble que c'est si peu compris mais c'est vraiment très simple, alors j'ai tendance à tergiverser sur ce sujet - pour lequel je m'excuse . Je pense simplement qu'il serait plus facile de montrer aux autres à quel point il peut être simple de concevoir votre propre système à partir du noyau si les détails ci-dessus étaient clairs. Encore une fois, je suis désolé, Gilles, je veux dire aucune insulte que ce soit.
mikeserv
@mikeserv Merci pour vos conseils. J'ai localisé le fichier utilisé pour copier les blobs (blbs.mk). Je ne comprends toujours pas quel (s) fichier (s) doit être édité pour ajouter un dossier de dossier à rootfs (/). Je peux accéder aux fichiers init * .rc de la rom, mais je ne le fais pas maintenant si l'édition (en ajoutant un mkdir / titi par exemple) ces fichiers me permettront d'ajouter définitivement mes dossiers (/ titi). Après quoi j'ajouterai dans le fichier PRODUCT_COPY_FILES + = / titi / myfile: <localpath> / myfiles. Un indice? Merci encore
deadeert
1

Les documents du noyau expliquent comment empaqueter une image dans le noyau lui-même. De kernel.org :

Qu'est-ce que rootfs?

Rootfsest une instance spéciale de ramfs(ou tmpfs, si elle est activée), qui est toujours présente dans les systèmes 2.6. Vous ne pouvez pas démonterrootfs pour à peu près la même raison que vous ne pouvez pas tuer le processus d'initialisation; plutôt que d'avoir un code spécial pour rechercher et gérer une liste vide, il est plus petit et plus simple pour le noyau de s'assurer que certaines listes ne peuvent pas devenir vides.

La plupart des systèmes montent simplement un autre système de fichiers rootfset l'ignorent. La quantité d'espace qu'une instance vide de ramfs occupe est minuscule.

Si CONFIG_TMPFS est activé, rootfsutilisera tmpfsau lieu de ramfspar défaut. Pour forcer ramfs, ajoutez "rootfstype=ramfs"à la ligne de commande du noyau.

Qu'est-ce que initramfs?

Tous les noyaux Linux 2.6 contiennent une archive au"cpio"formatgzippé, qui est extraite au rootfsdémarrage du noyau. Après extraction, le noyau vérifie pour voir sirootfscontient un fichier"init" , et s'il l'exécute comme PID 1. Si trouvé, ceinitprocessus est responsable de mettre le système le reste du chemin, y comprislocalisation etmontage du dispositif réel racine ( si seulement). Sirootfsne contient pas deinitprogramme après que l'cpioarchiveincorporée yest extraite, le noyau passera à l'ancien code pour localiser et monter une partition racine, puis exécutera une variante/sbin/initde celle-ci.

Tout cela diffère de l'ancien initrd à plusieurs égards:

  • L'ancien initrd était toujours un fichier séparé, tandis que l'archive initramfs est liée à l'image du noyau linux. (Le répertoire linux - * / usr est consacré à la génération de cette archive lors de la construction.)

  • L'ancien fichier initrd était une image du système de fichiers gzippé (dans certains formats de fichier, comme ext2, qui nécessitait un pilote intégré au noyau), tandis que la nouvelle archive initramfs est une archive cpio gzippée (comme tar plus simple, voir cpio (1) et Documentation / early-userspace / buffer-format.txt). Le code d'extraction cpio du noyau n'est pas seulement extrêmement petit, c'est aussi du texte et des données __init qui peuvent être supprimés pendant le processus de démarrage.

  • Le programme exécuté par l'ancien initrd (qui s'appelait / initrd, pas / init) a effectué une configuration puis est retourné au noyau, tandis que le programme init de initramfs ne devrait pas retourner au noyau. (Si / init doit transférer le contrôle, il peut sur-monter / avec un nouveau périphérique racine et exécuter un autre programme init. Voir l'utilitaire switch_root ci-dessous.)

  • Lors du basculement d'un autre périphérique racine, initrd pivot_root puis démontait le ramdisk. Mais initramfs est rootfs: vous ne pouvez ni pivot_root rootfs, ni le démonter. Au lieu de cela, supprimez tout de rootfs pour libérer de l'espace (find -xdev / -exec rm '{}' ';'), surmontez rootfs avec la nouvelle racine (cd / newmount; mount --move. /; Chroot.), attachez stdin / stdout / stderr au nouveau / dev / console et exécutez le nouveau init.

Comme il s'agit d'un processus remarquablement persévérant (et implique la suppression de commandes avant de pouvoir les exécuter), le package klibc a introduit un programme d'aide (utils / run_init.c) pour faire tout cela pour vous. La plupart des autres packages (tels que busybox) ont nommé cette commande "switch_root".

Remplissage des initramfs:

Le processus de construction du noyau 2.6 crée toujours une archive initramfs au format cpio compressé et la relie au binaire du noyau résultant. Par défaut, cette archive est vide (consommant 134 octets sur x86).

L'option de configuration CONFIG_INITRAMFS_SOURCE (dans la configuration générale dans menuconfig,et vivant dans usr/Kconfig) peut être utilisée pour spécifier une source pour l' initramfsarchive, qui sera automatiquement incorporée dans le binaire résultant. Cette option peut pointer vers une archive * gzippée * existantecpio , un répertoire contenant des fichiers à archiver ou une spécification de fichier texte telle que l'exemple suivant:

 dir /dev 755 0 0
 nod /dev/console 644 0 0 c 5 1
 nod /dev/loop0 644 0 0 b 7 0
 dir /bin 755 1000 1000
 slink /bin/sh busybox 777 0 0
 file /bin/busybox initramfs/busybox 755 0 0
 dir /proc 755 0 0
 dir /sys 755 0 0
 dir /mnt 755 0 0
 file /init initramfs/init.sh 755 0 0

Exécutez " usr/gen_init_cpio" (après la construction du noyau) pour obtenir un message d'utilisation documentant le format de fichier ci-dessus.

Un avantage du fichier de configuration est que l' rootaccès n'est pas nécessaire pour définir les autorisations ou créer des nœuds de périphérique dans la nouvelle archive.

(Notez que ces deux exemples d'entrées de "fichier" s'attendent à trouver des fichiers nommés " init.sh" et " busybox" dans un répertoire appelé " initramfs", sous le linuxrépertoire -2.6. *. Voir Documentation / early-userspace / README pour plus de détails.)

Le noyau ne dépend pas d' cpiooutils externes . Si vous spécifiez un répertoire au lieu d'un fichier de configuration, l'infrastructure de construction du noyau crée un fichier de configuration à partir de ce répertoire ( usr/Makefileappels scripts/gen_initramfs_list.sh) et procède à l'empaquetage de ce répertoire à l'aide du fichier de configuration (en l'alimentant vers usr/gen_init_cpio, qui est créé à partir de usr/gen_init_cpio.c). Le cpiocode de création au moment de la construction du noyau est entièrement autonome, et l'extracteur au démarrage du noyau est également (évidemment) autonome.

mikeserv
la source