Come compilare file extra nella directory principale di una ROM Android


8

Sto creando un kernel Android personalizzato basato sul codice sorgente del kernel della ROM Cyanogenmod. Vorrei aggiungere cartelle e file nella cartella principale del sistema operativo ( /). Ad esempio, dopo aver compilato il mio kernel, vorrei creare una cartella aggiuntiva chiamata toto(percorso assoluto = /toto).

Non ho davvero idea di quali file debbano essere modificati e come fare il lavoro.


Nota: se sei un utente Android (non uno sviluppatore ROM) che desidera aggiungere file al tuo rootfs, consulta invece la domanda Android.SE pertinente .


3
Android è un sistema Linux, ma poiché la domanda è specifica per Android, non per tutti gli Unix. Il posto migliore è su android.stackexchange.com
enedil

@enedil In generale, qui le domande Android sono fuori tema, poiché Android non è Linux nel senso comune del termine (utilizza semplicemente un kernel Linux). Tuttavia, la stessa domanda si applicherebbe ad altri sistemi Linux incorporati, quindi penso che qui vada bene.
Gilles 'SO- smetti di essere malvagio' il

@Graeme In realtà, il filesystem di root è compilato in ogni kernel. Di solito è vuoto e decomprimiamo un archivio cpio in esso - la nostra immagine initramfs. Puoi mettere quello che vuoi in esso anche se al momento della compilazione.
mikeserv,

@enedil In questo caso, credo che questa domanda sia interamente in argomento. Android differisce maggiormente da altri unix in userspace,ma da altri Linux, la in-kerneldifferenza è solo una manciata di patch. In effetti, la popolarità di Android è una delle principali forze trainanti dello sviluppo del kernel ed è stata per un paio d'anni. Dai un'occhiata ai log delle modifiche di kernel.org e decidi tu stesso quanto sono importanti per i sistemi mobili, in particolare Android.
mikeserv,

Una domanda simile su Android.SE: come decomprimere e modificare boot.imgper il porting della ROM? : le risposte spiegano come recuperare e modificare il boot.imgfile, consentendo di modificare in modo persistente il contenuto della directory principale del dispositivo.
WhiteWinterWolf

Risposte:


7

Su Android, come su molti sistemi basati su Linux, il kernel prima monta un initramfs on /. Initramfs è memorizzato nella RAM; viene caricato da un archivio CPIO che viene archiviato insieme al kernel stesso (o in qualche altro posto in cui il bootloader può trovarlo).

La maggior parte dei sistemi desktop Linux ha un piccolo initramfs che contiene solo abbastanza programmi e file di configurazione per montare il vero filesystem di root, che viene quindi montato /, sostituendo initramfs. Android, come alcuni sistemi Linux integrati, mantiene initramfs montato per sempre. Initramfs di Android contiene solo /init, adbde un paio di file di configurazione.

Per Cyanogenmod, puoi trovare le istruzioni di costruzione nella guida al porting . Vuoi copiare più file sul ramdisk (l'immagine di initramfs, nella terminologia Android), quindi devi aggiungerli PRODUCT_COPY_FILESall'elenco nel device_*.mkmakefile per il tuo dispositivo.


In realtà il nostro file di initramfs immagine è ciò che contiene quei file di configurazione, il initramfs filesystem è compilato in ogni kernel.
mikeserv,

1
@mikeserv Ti invito a familiarizzare con il concetto di metonimia . La scrittura tecnica lo usa meno del normale linguaggio, ma ne ottiene un uso occasionale.
Gilles 'SO- smetti di essere malvagio' il

Lo farò, ma prima devo controllarlo nel dizionario ...
mikeserv

Hai un ottimo punto e, come ho detto prima, l'unica ragione per cui sono irremovibile è che sembra così poco compreso ma è davvero molto diretto, quindi tendo a puntellare su questo argomento - per il quale mi scuso . Penso solo che sarebbe più facile mostrare agli altri quanto sia semplice ingegnerizzare il proprio sistema dal kernel se il dettaglio sopra fosse chiarito. Ancora una volta, mi dispiace, Gilles, non intendo insulti di sorta.
Mikeserv,

@mikeserv Grazie per i tuoi consigli. Ho trovato il file utilizzato per copiare i BLOB (blbs.mk). Continuo a non capire quali file debbano essere modificati per aggiungere una cartella di cartelle in rootfs (/). Posso accedere ai file init * .rc della rom, ma ora non posso modificare (ad esempio aggiungendo un mkdir / titi) questi file mi permetteranno di aggiungere in modo permanente le mie cartelle (/ titi). Successivamente aggiungerò nel file PRODUCT_COPY_FILES + = / titi / myfile: <localpath> / myfiles. Qualche idea? Grazie ancora
deadeert,

1

I documenti del kernel spiegano come impacchettare un'immagine nel kernel stesso. Da kernel.org :

Che cos'è rootfs?

Rootfsè un'istanza speciale di ramfs(o tmpfs, se abilitata), che è sempre presente nei sistemi 2.6. Non è possibile smontarerootfs per circa lo stesso motivo per cui non è possibile interrompere il processo di inizializzazione; piuttosto che avere un codice speciale per controllare e gestire un elenco vuoto, è più piccolo e più semplice per il kernel assicurarsi che determinati elenchi non possano diventare vuoti.

La maggior parte dei sistemi monta semplicemente un altro filesystem rootfse lo ignora. La quantità di spazio occupata da un'istanza vuota di ramfs è minuscola.

Se CONFIG_TMPFS è abilitato, rootfsverrà utilizzato tmpfsinvece di ramfsdefault. Per forzare ramfs, aggiungi "rootfstype=ramfs"alla riga di comando del kernel.

Che cos'è initramfs?

Tutti i kernel 2.6 di Linux contengono un"cpio"archivio in formatogzip, che viene estratto rootfsall'avvio del kernel. Dopo l'estrazione, il kernel verifica serootfscontiene un filee"init" , in tal caso, lo esegue come PID 1. Se trovato, questoinitprocesso è responsabile di portare il sistema al massimo, inclusa la localizzazione e il montaggio del dispositivo root reale ( se presente). Serootfsnon contiene uninitprogramma dopo che l'cpioarchivioincorporatoè stato estratto in esso, il kernel passerà al codice più vecchio per individuare e montare una partizione root, quindi eseguire una variante/sbin/initdi questo.

Tutto ciò differisce dal vecchio initrd in diversi modi:

  • Il vecchio initrd era sempre un file separato, mentre l'archivio initramfs è collegato all'immagine del kernel linux. (La directory linux - * / usr è dedicata alla generazione di questo archivio durante la compilazione.)

  • Il vecchio file initrd era un'immagine del filesystem gzipped (in alcuni formati di file, come ext2, che necessitava di un driver incorporato nel kernel), mentre il nuovo archivio initramfs è un archivio cpio gzipped (come tar solo più semplice, vedi cpio (1) e Documentation / early-userspace / buffer-format.txt). Il codice di estrazione cpio del kernel non è solo estremamente piccolo, è anche __init testo e dati che possono essere scartati durante il processo di avvio.

  • Il programma eseguito dal vecchio initrd (che era chiamato / initrd, non / init) ha fatto un po 'di installazione e poi è tornato al kernel, mentre non è previsto che il programma init da initramfs ritorni al kernel. (Se / init ha bisogno di passare il controllo, può sovrascrivere / con un nuovo dispositivo root ed eseguire un altro programma init. Vedere l'utilità switch_root, di seguito.)

  • Quando si cambia un altro dispositivo root, initrd pivot_root e quindi smonta il ramdisk. Ma initramfs è rootfs: non puoi né pivot_root rootfs, né smontarlo. Invece elimina tutto da rootfs per liberare spazio (trova -xdev / -exec rm '{}' ';'), monta i rootfs con la nuova radice (cd / newmount; mount --move. /; Chroot.), collega stdin / stdout / stderr al nuovo / dev / console ed esegui il nuovo init.

Dato che si tratta di un processo notevolmente persnickety (e comporta l'eliminazione di comandi prima che tu possa eseguirli), il pacchetto klibc ha introdotto un programma di supporto (utils / run_init.c) per fare tutto questo per te. Molti altri pacchetti (come busybox) hanno chiamato questo comando "switch_root".

Popolazione di initramfs:

Il processo di compilazione del kernel 2.6 crea sempre un archivio initramfs in formato cpio compresso con gzip e lo collega al binario del kernel risultante. Per impostazione predefinita, questo archivio è vuoto (consuma 134 byte su x86).

L'opzione di configurazione CONFIG_INITRAMFS_SOURCE (in Setup generale in menuconfig,e residente usr/Kconfig) può essere utilizzata per specificare una fonte per l' initramfsarchivio, che verrà automaticamente incorporata nel file binario risultante. Questa opzione può puntare a un archivio * esistente gzipped cpio*, una directory contenente file da archiviare o una specifica di file di testo come il seguente esempio:

 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

Eseguire " usr/gen_init_cpio" (dopo la compilazione del kernel) per ottenere un messaggio di utilizzo che documenta il formato di file sopra.

Un vantaggio del file di configurazione è che rootnon è necessario l'accesso per impostare autorizzazioni o creare nodi dispositivo nel nuovo archivio.

(Si noti che queste due voci "file" di esempio prevedono di trovare i file denominati " init.sh" e " busybox" in una directory denominata " initramfs", nella linuxdirectory -2.6. *. Consultare la documentazione / early-userspace / README per maggiori dettagli.)

Il kernel non dipende da cpiostrumenti esterni . Se si specifica una directory anziché un file di configurazione, l'infrastruttura di compilazione del kernel crea un file di configurazione da quella directory ( usr/Makefilechiama scripts/gen_initramfs_list.sh) e procede a impacchettare quella directory usando il file di configurazione (alimentandolo a usr/gen_init_cpio, da cui viene creato usr/gen_init_cpio.c). Il cpiocodice di creazione del kernel è interamente autonomo e anche l'estrattore del kernel è (ovviamente) autonomo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.