Perché ho bisogno di initramfs?


17

Ho scoperto che se scelgo jffso sdcome filesystem (e non initramfs), la dimensione del kernel sarà molto piccola (1,4 MB rispetto al initramfsquale è 3,4 MB). Significa che initramfsoccupa uno spazio considerevolmente grande. Quindi, se posso, lo rimuoverei completamente, e quindi avrò un kernel molto piccolo, che è quello che voglio.

La domanda di base che mi viene in mente è: perché ne ho bisogno initramfs? Non è possibile avviare un kernel Linux senza avere un filesystem iniziale?

La mia applicazione finale eseguirà solo calcoli e comunicazioni, senza alcuna memorizzazione. Quindi un sistema operativo senza un filesystem ha senso, almeno per la mia applicazione.


2
Non puoi fare a meno di initramfs. È possibile fare a meno del file initramfs aggiuntivo, ma indipendentemente da ciò che si fa, il kernel include il proprio vuoto oppure no. Quindi non capisco la tua domanda - di quale distribuzione stai parlando? Come stai costruendo il tuo kernel? Potete fornire il file .config del kernel? Questi sono molto importanti. Sospetto che la tua distribuzione stia compilando i suoi initramfs direttamente nel kernel - e quindi riempiendo gli initramfs altrimenti vuoti che contiene - ma non posso sapere in base alle informazioni che hai fornito.
Mikeserv,

2
@mikeserv, ovviamente un initramfs incorporato ma vuoto / non usato non conta.
psusi

Bene, @psusi i documenti del kernel non sono d'accordo. E ne sono così irremovibile perché non c'è bisogno di alcun mistero - è solo /root- tutto qui. L'unica cosa che fa diversamente è switch_rootma anche che, purché vengano prese le precauzioni appropriate con alcuni moduli del kernel caricati, si può fare in qualsiasi momento. Initramfs non è altro che un'immagine del disco: piena o no, è lì. E non ne sei mai senza - dopo tutto è la tua radice. Non dovrebbe essere solo un mistero, è quello che penso, e non mi piace tutta la confusione non necessaria che lo circonda.
Mikeserv,

2
@mikeserv, no, / root è la home directory per l'utente root. Il rootfs è /, che quindi ha la radice reale montata sopra di esso. Stai solo discutendo di semantica. Ai fini di questa discussione, non avere un initramfs significa non avere un file sul disco che il boot loader deve caricare e passare al kernel.
psusi

Questo è vero, ho usato / root solo per motivi di chiarezza, ma te lo darò. Ma no, non sono semantica, sono la meccanica fondamentale del tuo kernel Linux. Queste sono cose basilari. Proviamo solo a farli bene.
Mikeserv,

Risposte:


11

L'aumento delle dimensioni di avere un initramfs non è dovuto al driver ramfs (è solo qualche kB, e comunque necessario per altre cose) ma allo stesso initramfs. Initramfs contiene i programmi necessari per assemblare e montare il vero filesystem di root.

Initramfs rende molto più semplice, e in alcuni casi possibile (ad es. Crittografato /), avviare il sistema. Si consiglia vivamente di mantenerlo su hardware in stile PC con molte periferiche hot plug. D'altra parte, ha molto senso avviare un dispositivo incorporato senza alcun initramfs, con un kernel che supporta solo la particolare configurazione hardware per cui è stato creato.

Il kernel ovviamente deve avviarsi su un filesystem: deve esserci un modo per caricare qualunque applicazione tu voglia eseguire. Se non si esegue nulla, è possibile che la macchina sia spenta.

Se non vuoi usare un initramfs, dì semplicemente al tuo bootloader di non passarne uno. Inoltre non includerne uno nell'output della compilazione del kernel, ovviamente - come ciò accade se dipende dall'architettura e dal bootloader: per esempio, vmlinuxe bzImagenon includere gli initramfs (sono rispettivamente il kernel raw e compresso ), ma uImage(per U-Boot) comprime sia il kernel che initramfs se ce n'è uno.

(Tecnicamente, come osserva mikeserv , c'è sempre un initramfs - ma per impostazione predefinita, è un archivio vuoto di 134 byte. Quello che stai vedendo, e di cui vuoi sbarazzarti, è un "vero", non vuoto initramfs creato da il tuo processo di compilazione e contenente strumenti che vengono quindi utilizzati per montare il filesystem di root.)

Intendiamoci, un initramfs può essere un modo ragionevole di creare un sistema a singola applicazione senza dati persistenti: inserisci tutta la tua applicazione in initramfs, avvialo e conservalo. Ciò semplifica l'organizzazione dell'archiviazione persistente o dell'immagine di avvio (tutto ciò che serve è il kernel e initramfs, che possono essere raggruppati). Tuttavia, questo approccio presenta degli svantaggi: tutti i dati in initramfs verranno archiviati permanentemente nella RAM e non è possibile modificare facilmente i file nell'immagine di avvio, è necessario ricostruire l'archivio.


Se stai usando un kernel Linux 2.6 o più recente hai initramfs. Se usi o meno un'immagine secondaria di initramfs, come è consuetudine, è un'altra questione, ma initramfs non è facoltativo.
Mikeserv,

2
@mikeserv Ne hai uno, sì. Ma un initramfs vuoto è noccioline. Non deve essere utilizzato (il che richiede che contenga abbastanza programmi per montare la radice reale, il che aumenta le dimensioni in modo non trascurabile in un tipico sistema incorporato).
Gilles 'SO- smetti di essere malvagio' il

Arachidi obbligatorie comunque. E non so quando ho detto diversamente! Il richiedente stava chiedendo informazioni su come rimuoverlo come filesystem - il che non è possibile.
Mikeserv,

E sì, deve essere usato - senza initramfs non c'è root. Mai.
Mikeserv,

8

Da LFS :

L'unico scopo di un initramfs è montare il filesystem di root. Initramfs è un set completo di directory che potresti trovare su un normale filesystem di root. È raggruppato in un unico archivio cpio e compresso con uno dei numerosi algoritmi di compressione.

...

Ci sono solo quattro ragioni principali per avere un initramfs nell'ambiente LFS: caricare i rootfs da una rete, caricarlo da un volume logico LVM, avere un rootfs crittografato dove è richiesta una password, o per la comodità di specificare i rootfs come ETICHETTA o UUID. Qualsiasi altra cosa di solito significa che il kernel non è stato configurato correttamente.

...

Per la maggior parte delle distribuzioni, i moduli del kernel sono la ragione principale per avere un initramfs. In una distribuzione generale, ci sono molte incognite come tipi di file system e layout del disco. In un certo senso, questo è l'opposto di LFS in cui sono note le funzionalità e il layout del sistema e viene normalmente creato un kernel personalizzato. In questa situazione, raramente è necessario un initramfs.

Un'altra fonte www.kernel.org

Oltre a questo ci sono molti sistemi Linux che amano i router che non usano initramfs.


1

È necessario un initramfs per configurazioni più complesse, come l'avvio di rete o lvm o raid, poiché richiedono alcune utilità in modalità utente per configurare l'accesso al root fs. Per una partizione semplice e convenzionale su un disco, fino a quando si hanno i driver del disco integrati nel kernel e si specifica l'argomento root per percorso del dispositivo anziché UUID, è possibile fare a meno di un initramfs. Ovviamente, il percorso del dispositivo è soggetto a modifiche, a seconda dei dispositivi plug and play (ovvero USB) collegati, o anche semplicemente delle variazioni di temporizzazione casuali, motivo per cui praticamente tutti usano uuidi e initramfs per affidabilità.


Anche questo non è corretto.
Mikeserv,

6
@mikeserv, il tuo commento è inutile. Se lo rivendichi, devi spiegare perché.
psusi

Ho fatto, o meglio, la documentazione del kernel che compone circa il 99% della mia risposta.
Mikeserv,

@mikeserv, è corretto. Uso Gentoo Linux da anni ormai senza initramfs.
Tim

1

Questa è una vecchia domanda ma non sembra ancora avere una risposta accettata, quindi la lancerò qui (non sono un esperto qui, sto cercando di capirlo da solo.)

Da https://www.kernel.org/doc/Documentation/early-userspace/README (tutto in fondo che dice che non è stato aggiornato dal 2004.)

Il kernel ha attualmente 3 modi per montare il filesystem di root:

a) tutti i driver necessari per dispositivo e file system compilati nel kernel, senza initrd. init / main.c: init () chiamerà prepar_namespace () per montare il filesystem di root finale, in base all'opzione root = e facoltativo init = per eseguire un binario di init diverso da quello elencato alla fine di init / main.c: init ().

b) alcuni driver di dispositivo e file system creati come moduli e memorizzati in un initrd. Initrd deve contenere un binario '/ linuxrc' che dovrebbe caricare questi moduli driver. È anche possibile montare il filesystem di root finale via linuxrc e usare il syscall pivot_root. Initrd viene montato ed eseguito tramite prepar_namespace ().

c) usando initramfs. La chiamata a prepar_namespace () deve essere ignorata. Ciò significa che un binario deve fare tutto il lavoro. Detto binario può essere memorizzato in initramfs o modificando usr / gen_init_cpio.c o tramite il nuovo formato initrd, un archivio cpio. Deve essere chiamato "/ init". Questo binario è responsabile di fare tutto ciò che farebbe names_namespace ().

Per mantenere la compatibilità con le versioni precedenti, il file binario / init verrà eseguito solo se arriva tramite un archivio cpio initramfs. In caso contrario, init / main.c: init () eseguirà prepar_namespace () per montare la radice finale ed eseguire uno dei binari init predefiniti.

Per quello che vale, credo che dispositivi / distribuzioni come Raspberry Pi, ecc. Non utilizzino initramfs; in alcuni casi il kernel si trova sulla partizione root (montata dal bootloader che ha i moduli fs richiesti). In altri casi in cui il kernel si trova ad es. su una /bootpartizione, è possibile accedere direttamente agli initramfs sulla stessa partizione prima di montare i rootfs come altri ho dichiarato.

In alcuni casi, initramfs può essere integrato nello stesso file del kernel, ma non è sempre così. (a) sembra affermare abbastanza chiaramente che in alcuni casi initramfs non è necessario.


0

Trovo più chiara la seguente spiegazione ,

initramfsè un filesystem di root che è incorporato nel kernel e caricato in una fase iniziale del processo di avvio. È il successore di initrd. Fornisce uno spazio utente iniziale che può fare cose che il kernel non può facilmente fare da solo durante il processo di avvio.

L'uso di initramfs è facoltativo. Per impostazione predefinita, il kernel inizializza l'hardware utilizzando i driver integrati, monta la partizione root specificata, carica il sistema init della distribuzione Linux installata. Il sistema init carica quindi moduli aggiuntivi e avvia i servizi fino a quando non ti consente di accedere. Questo è un buon comportamento predefinito e sufficiente per molti utenti. initramfs è per utenti con requisiti avanzati; per gli utenti che devono fare le cose il prima possibile, anche prima che venga montata la partizione di root.

Ecco alcuni esempi di cosa puoi fare con initramfs:

  • Montare la partizione di root (per partizioni crittografate, logiche e altrimenti speciali);
  • Fornire una shell di salvataggio minimalista (se qualcosa va storto);
  • Personalizza il processo di avvio (ad es. Stampa di un messaggio di benvenuto, avvio di avvio, ecc.);
  • Moduli di carico (ad esempio driver di terze parti);
  • Tutto ciò che il kernel non può fare (purché sia ​​possibile farlo nello spazio utente, ad es. Eseguendo i comandi). Se non hai requisiti avanzati, non hai bisogno di initramfs.

-1

Non importa quello che fai, hai initramfs. Non ne puoi fare a meno: è l'unico file system che ti è stato imposto. 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 di 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ò sovrastare / con un nuovo dispositivo root ed eseguire un altro programma init. Vedi 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. La maggior parte degli altri pacchetti (come busybox) ha chiamato questo comando "switch_root".

Popolazione di initramfs:

Il processo di compilazione del kernel 2.6 crea sempre un archivio initramfs in formato cpio 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 in usr / Kconfig) può essere usata per specificare una fonte per l'archivio initramfs, che verrà automaticamente incorporato nel binario risultante. Questa opzione può puntare a un archivio cpio gzip esistente, 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 non è necessario l'accesso root 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 chiamata "initramfs", nella directory linux-2.6. *. Vedere la documentazione / early-userspace / README per più dettagli.)

Il kernel non dipende da strumenti cpio 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 / Makefile chiama script / gen_initramfs_list.sh) e procede a impacchettare quella directory usando il file di configurazione (alimentandolo a usr / gen_init_cpio, creato da usr / gen_init_cpio.c). Il codice di creazione cpio in fase di creazione del kernel è completamente autonomo e anche l'estrattore del tempo di avvio del kernel è (ovviamente) autonomo.


1
È possibile avviare senza un initramfs. La tua risposta espone i meriti di initramfs, ma ciò non si applica ai tipici sistemi embedded, e anche su desktop o server in cui è raccomandato un initramfs, non è obbligatorio.
Gilles 'SO-smetti di essere malvagio' il

@Gilles - no non puoi. Indipendentemente da ciò che fai, hai initramfs. È compilato nel kernel - proprio ora, il tuo kernel, il mio kernel, tutti quelli del nostro kernel. Leggi i documenti del kernel - il mio intero post è stato un copia-incolla. Sei errato Come si può contestare la documentazione ufficiale?
Mikeserv,

1
Non disputo la documentazione ufficiale, contesto le conclusioni che ne trai. Stai leggendo la documentazione che spiega come usare un initramfs. Da nessuna parte si afferma che initramfs deve essere usato.
Gilles 'SO- smetti di essere malvagio' il

@Gilles Se questo non è abbastanza buono: "Il processo di compilazione del kernel 2.6 crea sempre un archivio initramfs in formato cpio gzipped e lo collega al binario del kernel risultante. Per impostazione predefinita, questo archivio è vuoto (consumando 134 byte su x86) .... " Posso fare di meglio. Quanto sopra era una ricerca web di 2 o 3 minuti.
Mikeserv,

3
Ho letto la documentazione Lo faccio per vivere. Non è una questione di opinione. C'è sempre un initramfs, ma non è necessariamente utilizzato per l'avvio. Non riesco a trovare una spiegazione decente della struttura del kernel per quel caso, presumibilmente perché è il caso classico che si ritiene non meriti una spiegazione. La logica principale è in do_mounts.c- specificamente prepare_namespace, in cui saved_root_nameviene popolata con l' root=argomento della riga di comando.
Gilles 'SO-smetti di essere malvagio' il
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.