Configurazione, compilazione e installazione di un kernel Linux personalizzato


38

Mi piacerebbe provare a usare un kernel diverso da quello fornito dalla mia distribuzione - da qualche altra parte o come personalizzato da me. È difficile o pericoloso?

Da dove comincio?

Risposte:


51

La creazione di un kernel personalizzato può richiedere molto tempo, principalmente nella configurazione, poiché i computer moderni possono eseguire la compilazione in pochi minuti, ma non è particolarmente pericoloso se si mantiene il kernel corrente e funzionante e si accerta di lasciarlo come opzione tramite il bootloader (vedere il passaggio 6 di seguito). In questo modo, se il tuo nuovo non funziona, puoi semplicemente riavviare quello vecchio.

Nelle seguenti istruzioni, i percorsi all'interno dell'albero dei sorgenti assumono la forma [src]/whatever, dove si [src]trova la directory in cui hai installato i sorgenti, ad es /usr/src/linux-3.13.3. Probabilmente vuoi fare queste cose su rootpoiché l'albero dei sorgenti dovrebbe rimanere sicuro in termini di permessi di scrittura (dovrebbe essere di proprietà di root).

Mentre alcuni dei passaggi sono facoltativi, è necessario leggerli comunque poiché contengono le informazioni necessarie per comprendere il resto del processo.

  1. Scarica e decomprime il tarball di origine.

    Questi sono disponibili da kernel.org . Gli ultimi sono elencati in prima pagina, ma se guardi all'interno della /pub/directory, troverai un archivio che risale alla versione 1.0. A meno che non abbiate un motivo speciale per fare diversamente, è meglio scegliere semplicemente "Ultima scuderia". Al momento della stesura di questo documento, si tratta di un tar.xzfile di 74 MB .

    Una volta scaricato il tarball, è necessario decomprimerlo da qualche parte. Il posto normale è dentro /usr/src. Posiziona il file lì e:

    tar -xJf linux-X.X.X.tar.xz
    

    Nota che le distro individuali di solito raccomandano di usare uno dei loro pacchetti sorgente invece dell'albero della vaniglia. Questo contiene patch specifiche per la distro, che potrebbero interessarti o meno. Corrisponderà anche al kernel includendo le intestazioni utilizzate per compilare alcuni strumenti di userspace, anche se molto probabilmente sono identici.

    In oltre 15 anni di costruzione di kernel personalizzati (principalmente su Fedora / Debian / Ubuntu), non ho mai avuto problemi con l'utilizzo della sorgente vanilla 1 . Farlo non fa molta differenza, tuttavia, oltre al fatto che se si desidera l'ultimo kernel assoluto, la distribuzione probabilmente non lo ha ancora impacchettato. Quindi il percorso più sicuro è ancora quello di utilizzare il pacchetto distro, che dovrebbe essere installato in/usr/src . Preferisco l'ultima stalla in modo da poter agire come una cavia prima che venga srotolata nelle distro :)

  2. Inizia con una configurazione di base [opzionale].

    Non devi farlo: puoi semplicemente immergerti e creare una configurazione da zero. Tuttavia, se non l'hai mai fatto prima, aspettati molti tentativi ed errori. Questo significa anche dover leggere la maggior parte delle opzioni (ce ne sono centinaia). Una scommessa migliore è utilizzare la configurazione esistente, se disponibile. Se hai usato un pacchetto sorgente distro, probabilmente contiene già un [src]/.configfile, quindi puoi usarlo. Altrimenti, controllare per a /proc/config.gz. Questa è una funzione opzionale aggiunta nel kernel 2.6. Se esiste, copiarlo nel livello superiore dell'albero di origine e gunzip -c config.gz > .config.

Se non esiste, forse perché questa opzione è stata configurata come modulo. Prova sudo modprobe configs, quindi controlla/proc di config.gznuovo directory .

La configurazione distro non è molto ideale nel senso che include quasi tutti i possibili driver hardware. Questo non ha molta importanza per la funzionalità del kernel, poiché sono moduli e la maggior parte di essi non verrà mai utilizzata, ma aumenta notevolmente il tempo necessario per la compilazione. È anche imbarazzante in quanto richiede che un initramfs contenga determinati moduli core (vedere il passaggio 4 di seguito). Tuttavia, è probabilmente un punto di partenza migliore rispetto al valore predefinito.

Si noti che le opzioni di configurazione cambiano e cambiano da una versione del kernel a quella successiva e quando si esegue uno dei make configprogrammi di seguito .configverrà prima analizzato e aggiornato per corrispondere alla nuova versione. Se la configurazione proviene da una versione molto più vecchia, questo può portare a strani risultati, quindi fai attenzione quando esegui la configurazione. AFAIK non funzionerà affatto al contrario (usando una configurazione da una versione più recente).

  1. Crea una .configminzione.

    [src]/.configè un file di testo utilizzato per configurare il kernel. Non modificare questo file direttamente . Cambiare le opzioni spesso non è una semplice questione di sostituire a Ycon an N, ecc; di solito esiste una serie di interdipendenze e possibilità di ramificazione. Invece, si desidera utilizzare uno dei target di configurazione dal makefile del kernel (ovvero, immettere make _____sulla riga di comando dalla directory dei sorgenti di livello superiore):

    • make configè il più semplice ma probabilmente non per i gusti della maggior parte delle persone. È una sequenza di domande - molte domande - e se cambi idea devi ricominciare.

    • make oldconfigè come make configtranne, se ne hai già uno .configda una versione precedente, salterà le domande tranne quelle relative alle nuove opzioni. Ce ne possono essere ancora molti e molti di loro saranno irrilevanti per te, quindi non lo consiglio.

    • make menuconfigè il mio metodo preferito (e penso la maggior parte degli altri). Costruisce ed esegue un'interfaccia TUI (menu colorati che funzioneranno su un terminale). Ciò richiede che tu abbia -devinstallato il pacchetto per ncurses. È abbastanza autoesplicativo, ad eccezione della ricerca accessibile tramite /; la "guida" F1 fornisce una spiegazione per l'opzione corrente. Esiste una versione alternativa make nconfig, con alcune funzionalità extra, in cui F2 "Syminfo" è l'equivalente della F1 di menuconfig.

    • make xconfigè un'interfaccia grafica completa. Ciò richiede qmakee il -devpacchetto per Qt deve essere installato, come di nuovo, è un programma che viene compilato e creato. Se non li utilizzavi in ​​precedenza, potrebbe essere un download sostanziale. La ragione per cui preferisco menuconfigalla versione GUI è che le gerarchie di opzioni sono presentate usando schermate successive nella prima ma aperte a fisarmonica nella seconda.

    Una delle prime cose che dovresti (ma non devi fare) è aggiungere una stringa "Versione locale" (in Configurazione generale ). La ragione di ciò è menzionata nel n. 5 di seguito.

    "Labyrinthine" è un buon modo per descrivere la gerarchia delle opzioni e entrare nel dettaglio con essa è ben al di là dell'ambito di una domanda e risposta come questa. Se vuoi sederti e passare tutto, metti da parte le ore . Greg Kroah-Hartman (capo sviluppatore di lunga data per il kernel linux) ha un libro online gratuito sul kernel (vedi riferimenti sotto) che contiene un capitolo sulla configurazione , sebbene sia stato scritto nel 2006. Il mio consiglio è di iniziare con una base ragionevole dal tuo attuale kernel distro (come da # 2) e poi attraversalo e deseleziona tutte le cose che sai di non aver bisogno. Probabilmente vorrai anche cambiare alcune delle opzioni del "modulo" in "integrato", il che ci porta al mio prossimo punto ...

  2. Informazioni su initramfs[opzionale]

    Un "initramfs" è un filesystem compresso incorporato nel kernel e / o caricato all'avvio. Il suo scopo principale è quello di includere i moduli di cui il kernel avrà bisogno prima di poter accedere a quelli nel /lib/modulesfilesystem di root - ad esempio, i driver per il dispositivo contenente quel filesystem. Le distribuzioni li usano sempre parzialmente perché i driver sono reciprocamente incompatibili e quindi non possono essere tutti integrati nel kernel. Invece, quelli appropriati per il sistema attuale sono selezionati all'interno di initramfs.

    Funziona bene e non rappresenta alcun tipo di svantaggio, ma è probabilmente una complicazione inutile quando si crea il proprio kernel. 2 Il problema è che, se non si utilizza un initramfs, è necessario assicurarsi che i driver per il proprio filesystem di root (e il dispositivo acceso) siano integrati nel kernel. In menuconfig, questa è la differenza tra Mun'opzione (= module) e un'opzione *(= built-in). Se non riesci a farlo bene, il sistema fallirà all'inizio del processo di avvio. Quindi, ad esempio, se si dispone di un disco rigido SATA e di un file system root ext4, sono necessari driver per quelli integrati. [Se qualcuno può pensare a qualcos'altro che è un must-have, lascia un commento e lo incorporerò qui].

    Se si desidera utilizzare un initramfs, è necessario selezionare le opzioni appropriate in Impostazione generale . C'è una guida per la creazione di scheletro di uno integrato nel kernel in [src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt, ma è da notare che le distribuzioni non lo fanno; usano un file cpio compresso con gzip esterno. Tuttavia, quel documento contiene una discussione su cosa dovrebbe andare nel initramfs(vedi "Contenuto di initramfs").

  3. Compilare e installare il kernel.

    Il prossimo passo è semplice. Per creare il kernel, basta eseguire makenella [src]directory. Se utilizzi un sistema multi-core, puoi aggiungere -j Nper accelerare le cose, dove Nè il numero di core che vuoi dedicare + 1. Non c'è testo check. Una volta fatto, puoi make modules. In una scatola veloce, tutto ciò dovrebbe richiedere <10 minuti.

    Se tutto va bene, make INSTALL_MOD_STRIP=1 modules_install. Ciò creerà una directory /lib/modulescorrispondente al numero di versione del kernel più la stringa "Versione locale" menzionata nel passaggio 3, se presente. Se non hai usato una stringa "Versione locale", fai attenzione se hai già un kernel della stessa versione da cui dipendi , perché questi moduli sostituiranno quelli. 3 INSTALL_MOD_STRIP=1 è facoltativo, per il significato vedere qui .

    È quindi possibile make installinstallare il kernel in un percorso predefinito. La mia raccomandazione, tuttavia, è di farlo da soli per assicurarsi che nessun file esistente venga sovrascritto. Cerca in [src]/arch/[ARCH]/bootun file denominato bzImage4 , dove [ARCH]è x86se siete su un sistema x86 o x86-64 macchina (e qualcos'altro se siete su qualcosa d'altro). Copialo in /boote rinominalo in qualcosa di più specifico e informativo (non importa quale). Fai la stessa cosa con [src]/System.map, ma rinominalo secondo il seguente schema:

    System.map-[VERSION]
    

    Qui, [VERSION]è esattamente lo stesso del nome della directory /lib/modulescreata damake modules_install , che includerà la stringa "Versione locale", ad es System.map-3.13.3-mykernel.

  4. Configurare il bootloader di GRUB 2.

    Se non si utilizza grub(la maggior parte degli utenti desktop Linux lo sono), questo ovviamente non si applica a te. Dovresti avere un /etc/grub.d/40_customfile che non contiene molto. In caso contrario, crearlo di proprietà di root e chmod 755(deve essere eseguibile). A ciò aggiungere:

    menuentry 'My new kernel, or whatever' {
        set root='hd0,1'
        linux /boot/[name-of-kernel] root=/dev/sda1 [other kernel options]
    }
    

    Se stai usando un initramfs, dovresti anche avere un'ultima riga initrd /path/to/initramfs. Attenzione alla set root=linea. L'esempio presume che grub sia stato installato sulla prima partizione del primo disco rigido (hd0,1). Se si dispone di più unità, è possibile utilizzare l'UUID della partizione e sostituire quella riga con:

        search --no-floppy --fs-uuid --set=root [the UUID of the partition]
    

    A meno che grub non si trovi sul tuo filesystem di root, questo dovrebbe corrispondere anche alla root=direttiva sulla linuxlinea, che indica il tuo filesystem di root (quello con /sbin/inite /lib/modules). La versione UUID è root=UUID=[the UUID].

    Puoi esaminare il tuo esistente /boot/grub2/grub.cfgper avere un'idea del nome del dispositivo. Ecco una breve guida a tale sotto grub 2. Una volta che sei felice, corri grub2-mkconfig -o /boot/grub2/grub.cfg(ma esegui prima il backup del tuo attuale grub.cfg). È quindi possibile modificare quel file e spostare la voce in alto. Dovrebbe contenere ancora un elenco per il tuo vecchio kernel (in esecuzione), e la tua distribuzione potrebbe avere un meccanismo che duplica automaticamente una voce per il nuovo kernel (perché è stata trovata in /boot; Fedora fa questo, quindi, usando un titolo distinto con menuentryè un buona idea). Puoi rimuoverlo in seguito se tutto va bene.

    Puoi anche semplicemente inserire direttamente menuentryin grub.cfg, ma alcune distro lo sovrascriveranno quando il loro kernel viene aggiornato (mentre l'uso /etc/grub.d/lo manterrà incorporato).

    Questo è tutto. Tutto quello che devi fare ora è riavviare. Se non funziona, prova a dedurre il problema dall'output dello schermo, riavvia la scelta di un vecchio kernel e torna al passaggio 3 (tranne usa quello che .confighai già e modificalo). Potrebbe essere una buona idea make clean(o make mrproper) tra i tentativi, ma assicurati di copiarlo prima [src]/.configin un backup, perché verrà cancellato. Questo aiuta a garantire che gli oggetti utilizzati nel processo di generazione non siano obsoleti.

  5. Per quanto riguarda le intestazioni del kernel et. al.

    Una cosa che dovresti probabilmente fare è symlink ( ln -s -i) /lib/modules/X.X.X/sourcee /lib/modules/X.X.X/buildla /usr/srcdirectory dove si trova l'albero dei sorgenti (mantienilo). Ciò è necessario in modo che alcuni strumenti di userspace (e programmi di installazione di driver di terze parti) possano accedere all'origine per il kernel in esecuzione.

    Un problema legato a questo sono i .hfile in /usr/include, ecc. Questi cambiano molto gradualmente e sono retrocompatibili . Hai due scelte:

    • Lascia quelli usati dalla tua distribuzione. Se aggiorni regolarmente l'intero sistema, la distribuzione installerà comunque periodicamente nuovi, quindi questa è l'opzione "il minimo fastidio".

    • Usa make headers_install.

    Poiché sono compatibili con le versioni precedenti (ovvero "un programma creato su una libreria C che utilizza intestazioni del kernel più vecchie dovrebbe essere eseguito su un kernel più recente"), non è necessario essere troppo esigenti al riguardo. L'unico potenziale problema potrebbe essere se si crea un kernel personalizzato e lo si mantiene per un po ', durante il quale la distro aggiorna il pacchetto "kernel-headers" a una versione più recente rispetto a quella utilizzata per compilare il kernel, e risulta che ci sono alcuni incompatibilità (che si applicherebbe solo al software successivamente compilato dalla fonte).

Riferimenti

Ecco alcune risorse:

  • [src]/README include una breve guida alla costruzione e all'installazione.

  • La [src]/Documentationdirectory contiene molte informazioni che possono essere utili nella configurazione.

  • Gran parte del libro di Greg KH Linux Kernel in a Nutshell (disponibile lì gratuitamente come una serie di PDF) ruota attorno alla costruzione del kernel.

  • Grub 2 ha un manuale online .


1. "Vaniglia" si riferisce alla fonte ufficiale originale, non alterata, come trovata su kernel.org. La maggior parte delle distro prende questa fonte di vaniglia e aggiunge alcune personalizzazioni minori.

2. Notare che ci sono circostanze che richiedono un initramfs perché è necessario un po 'di spazio utente per montare il filesystem di root - per esempio, se è crittografato o diffuso su un array RAID complesso.

3. Non rimuoverà i moduli che sono già lì se non li hai creati, tuttavia, il che significa che puoi aggiungere un modulo in un secondo momento semplicemente modificando la configurazione ed eseguendolo di make modules_installnuovo. Si noti che la creazione di alcuni moduli potrebbe richiedere modifiche al kernel stesso, nel qual caso è necessario sostituire anche il kernel. Sarai in grado di dire quando si tenta di utilizzare modprobeper inserire il modulo.

4. Questo file può essere denominato in modo diverso se si utilizzava un'opzione di compressione non standard. Non sono sicuro di quali siano tutte le possibilità.


3
Upvoted. Potresti voler aggiungere una menzione localmodconfige strumenti come lo streamline_config.plscript; un approccio utile per lavorare dalla tua configurazione esistente ...
Jasonwryan,

1
Questo è probabilmente abbastanza dettagliato da essere una domanda di tipo canonico per iniziativa di @ terdon. Valuta di fornire una risposta alla sua domanda su meta. O potrei, se preferisci. Sembra che questa sia stata l'intenzione, dal momento che hai posto la domanda comunque. Anche l'inclusione di metodi specifici della distribuzione per la creazione di pacchetti binari sarebbe utile, credo.
Faheem Mitha,

1
FYI: initramfsdovrebbe essere usato quasi sempre. Ad esempio, l'impostazione di rootfs su LVM + RAID spesso ne richiede una. La radice crittografata lo fa sicuramente. Anche le configurazioni RAID ragionevolmente complicate lo fanno. L'assemblaggio automatico nel kernel di array anche banali è in realtà deprecato ...
derobert,

2
@derobert: Questo pone la domanda che "quasi sempre" linux viene utilizzato per eseguire un server aziendale. Il mio punto initramfsè che se non è necessario utilizzarne uno, non è necessario e questo semplifica il processo. Ad ogni modo, ho aggiunto una nota a piè di pagina sulla radice cifrata fs, ecc.
Riccioli d'oro,

Si prega di includere dettagli sulla funzionalità efi-stub di EFI e Linux.
IW16,
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.