Cómo compilar archivos adicionales en el directorio raíz de una ROM de Android

8

Estoy construyendo un kernel de Android personalizado basado en el código fuente del kernel de Cyanogenmod ROM. Me gustaría agregar carpetas y archivos en la carpeta raíz del sistema operativo ( /). Por ejemplo, después de haber compilado mi kernel, me gustaría crear una carpeta adicional llamada toto(ruta absoluta = /toto).

Realmente no tengo idea de qué archivos tienen que editarse y cómo hacer el trabajo.


Nota: Si usted es un usuario de Android (no es un desarrollador ROM) que quiere agregar archivos a su rootfs, por favor vea la pregunta Android.SE relevante en su lugar.

deadeert
fuente
3
Android es un sistema Linux, pero como la pregunta es específica de Android, no de todos los Unix. Mejor lugar para ello es en android.stackexchange.com
enedil
@enedil En términos generales, las preguntas de Android están fuera de tema aquí, ya que Android no es Linux en el sentido común del término (simplemente usa un kernel de Linux). Sin embargo, la misma pregunta se aplicaría a otros sistemas Linux integrados, así que creo que está bien aquí.
Gilles 'SO- deja de ser malvado'
@Graeme En realidad, el sistema de archivos raíz se compila en cada núcleo. Por lo general, está vacío y desempaquetamos un archivo cpio en él, nuestra imagen initramfs. Sin embargo, puede poner lo que quiera en el momento de la compilación.
mikeserv
@enedil En este caso, creo que esta pregunta es completamente sobre el tema. Android difiere más de otros unixes en userspace,pero de otros Linux, la in-kerneldiferencia es solo un puñado de parches. De hecho, la popularidad de Android es una importante fuerza impulsora detrás del desarrollo del kernel, y lo ha sido durante un par de años. Eche un vistazo a los registros de cambios de kernel.org y decida usted mismo cuán relevantes son para los sistemas móviles, especialmente Android.
mikeserv
Una pregunta similar en Android.SE: ¿Cómo descomprimir y editar boot.imgpara portar ROM? : las respuestas allí explican cómo buscar y editar el boot.imgarchivo, lo que permite cambiar de manera persistente el contenido del directorio raíz del dispositivo.
WhiteWinterWolf

Respuestas:

7

En Android, al igual que en muchos sistemas basados en Linux, el kernel monta por primera vez un initramfs en /. El initramfs se almacena en la RAM; se carga desde un archivo CPIO que se almacena junto con el núcleo mismo (o en algún otro lugar donde el gestor de arranque pueda encontrarlo).

La mayoría de los sistemas Linux de escritorio tienen un pequeño initramfs que contiene suficientes programas y archivos de configuración para montar el sistema de archivos raíz real, que luego se monta /, reemplazando los initramfs. Android, como algunos sistemas Linux integrados, mantiene los initramfs montados para siempre. Initramfs de Android incluye solamente /init, adbdy algunos archivos de configuración.

Para Cyanogenmod, puede encontrar instrucciones de compilación en la guía de portabilidad . Desea copiar más archivos en el disco RAM (la imagen initramfs, en la terminología de Android), por lo que debe agregarlos a la PRODUCT_COPY_FILESlista en el device_*.mkarchivo MAKE para su dispositivo.

Gilles 'SO- deja de ser malvado'
fuente
En realidad, nuestro archivo de initramfs imagen es el que contiene esos archivos de configuración, el initramfs sistema de archivos se compila en cada núcleo.
mikeserv
1
@mikeserv Te invito a que te familiarices con el concepto de metonimia . La escritura técnica lo usa menos que el discurso ordinario, pero tiene un uso ocasional.
Gilles 'SO- deja de ser malvado'
Lo haré, pero primero tengo que revisarlo en el diccionario ...
mikeserv 03 de
Usted hace una muy buena observación, y como dije antes, la única razón por la que soy inflexible sobre esto es que parece que se entiende muy poco, pero en realidad es muy sencillo, por lo que tiendo a dudar sobre este tema, por lo cual me disculpo. . Simplemente creo que sería más fácil mostrarles a los demás lo simple que puede ser diseñar su propio sistema desde el núcleo si los detalles anteriores se aclaran. De nuevo, lo siento, Gilles, no quiero decir insulto alguno.
mikeserv
@mikeserv Gracias por tus consejos. Encontré el archivo utilizado para copiar blobs (blbs.mk). Todavía no entiendo qué archivo (s) tiene que editar para agregar una carpeta en rootfs (/). Puedo acceder a los archivos init * .rc de la rom, pero ahora no lo hago si edito (agregando un mkdir / titi por ejemplo) estos archivos me permitirán agregar permanentemente mis carpetas (/ titi). Luego agregaré el archivo PRODUCT_COPY_FILES + = / titi / myfile: <localpath> / myfiles. Cualquier pista ? Gracias de nuevo
deadeert
1

Los documentos del núcleo explican cómo empaquetar una imagen en el núcleo mismo. Desde kernel.org :

¿Qué es rootfs?

Rootfses una instancia especial de ramfs(o tmpfs, si está habilitada), que siempre está presente en los sistemas 2.6. No puede desmontarrootfs aproximadamente por la misma razón por la que no puede eliminar el proceso de inicio; en lugar de tener un código especial para verificar y manejar una lista vacía, es más pequeño y simple para el núcleo asegurarse de que ciertas listas no puedan quedar vacías.

La mayoría de los sistemas simplemente montan otro sistema de archivos rootfsy lo ignoran. La cantidad de espacio que ocupa una instancia vacía de ramfs es pequeña.

Si CONFIG_TMPFS está habilitado, rootfsse usará en tmpfslugar de ramfspor defecto. Para forzar ramfs, agregue "rootfstype=ramfs"a la línea de comando del núcleo.

¿Qué es initramfs?

Todos los núcleos 2.6 de Linux contienen un"cpio"archivo de formato comprimido, que se extrae rootfscuando se inicia el núcleo. Después de extraer, el kernel verifica sirootfscontiene un archivoy"init" , de ser así, lo ejecuta como PID 1. Si se encuentra, esteinitproceso es responsable de llevar el sistema al resto, incluyendo la ubicación y el montaje del dispositivo raíz real ( Si alguna). Sirootfsno contiene uninitprograma después de que elcpioarchivoincrustadose extrae, el núcleo pasará al código anterior para ubicar y montar una partición raíz, luego ejecute alguna variante/sbin/initde eso.

Todo esto difiere del antiguo initrd de varias maneras:

  • El viejo initrd siempre fue un archivo separado, mientras que el archivo initramfs está vinculado a la imagen del kernel de Linux. (El directorio linux - * / usr está dedicado a generar este archivo durante la compilación).

  • El antiguo archivo initrd era una imagen del sistema de archivos comprimido (en algún formato de archivo, como ext2, que necesitaba un controlador integrado en el núcleo), mientras que el nuevo archivo initramfs es un archivo comprimido de cpio (como tar, más simple, vea cpio (1) y Documentation / early-userspace / buffer-format.txt). El código de extracción cpio del kernel no solo es extremadamente pequeño, también es __init texto y datos que pueden descartarse durante el proceso de arranque.

  • El programa ejecutado por el antiguo initrd (que se llamaba / initrd, no / init) realizó una configuración y luego regresó al kernel, mientras que no se espera que el programa init de initramfs regrese al kernel. (Si / init necesita transferir el control, puede sobremontarse / con un nuevo dispositivo raíz y ejecutar otro programa de inicio. Consulte la utilidad switch_root, a continuación).

  • Al cambiar otro dispositivo raíz, initrd pivot_root y luego desmontaría el ramdisk. Pero initramfs es rootfs: no puede pivot_root rootfs, ni desmontarlo. En su lugar, elimine todo de rootfs para liberar el espacio (find -xdev / -exec rm '{}' ';'), superponga rootfs con la nueva raíz (cd / newmount; mount --move. /; Chroot.), adjunte stdin / stdout / stderr a la nueva / dev / console y ejecute el nuevo init.

Dado que este es un proceso notablemente perspicaz (e implica eliminar comandos antes de que pueda ejecutarlos), el paquete klibc introdujo un programa auxiliar (utils / run_init.c) para hacer todo esto por usted. La mayoría de los otros paquetes (como busybox) han llamado a este comando "switch_root".

Poblar initramfs:

El proceso de compilación del kernel 2.6 siempre crea un archivo initramfs en formato cpio comprimido y lo vincula al binario del kernel resultante. Por defecto, este archivo está vacío (consume 134 bytes en x86).

La opción de configuración CONFIG_INITRAMFS_SOURCE (en Configuración general en menuconfig,y viviendo en usr/Kconfig) se puede utilizar para especificar una fuente para el initramfsarchivo, que se incorporará automáticamente al binario resultante. Esta opción puede apuntar a un * existente gzipped cpioarchivo *, un directorio que contiene los archivos a ser archivada, o un texto de especificación de archivo como el siguiente ejemplo:

 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

Ejecute " usr/gen_init_cpio" (después de la compilación del núcleo) para obtener un mensaje de uso que documente el formato de archivo anterior.

Una ventaja del archivo de configuración es que rootno se requiere acceso para establecer permisos o crear nodos de dispositivo en el nuevo archivo.

(Tenga en cuenta que esas dos entradas de "archivo" de ejemplo esperan encontrar archivos llamados " init.sh" y " busybox" en un directorio llamado " initramfs", en el linuxdirectorio -2.6. *. Consulte Documentación / early-userspace / README para obtener más detalles).

El núcleo no depende de cpioherramientas externas . Si especifica un directorio en lugar de un archivo de configuración, la infraestructura de compilación del núcleo crea un archivo de configuración a partir de ese directorio ( usr/Makefilellamadas scripts/gen_initramfs_list.sh) y procede a empaquetar ese directorio utilizando el archivo de configuración (al alimentarlo usr/gen_init_cpio, que se crea a partir de usr/gen_init_cpio.c). El código de creación del tiempo de compilación del núcleo cpioes completamente autónomo, y el extractor del tiempo de arranque del núcleo también es (obviamente) autónomo.

mikeserv
fuente