GNU/Linux >> Linux Esercitazione >  >> Linux

Linux:configurazione, compilazione e installazione di un kernel Linux personalizzato?

Vorrei provare a utilizzare un kernel diverso da quello fornito dalla mia distribuzione, da qualche altra parte o personalizzato da me. È difficile o pericoloso?

Da dove comincio?

Risposta accettata:

La creazione di un kernel personalizzato può richiedere molto tempo, soprattutto nella configurazione, poiché i computer moderni possono eseguire la compilazione in pochi minuti, ma non è particolarmente pericoloso se mantieni il tuo kernel attuale e funzionante e assicurati di lasciarlo come opzione tramite il tuo bootloader (vedi il passaggio n. 6 di seguito). In questo modo, se quello 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 [src] è la directory in cui hai installato il sorgente, ad es. /usr/src/linux-3.13.3 . Probabilmente vorrai fare queste cose su root poiché l'albero dei sorgenti dovrebbe rimanere sicuro in termini di autorizzazioni di scrittura (dovrebbe essere di proprietà di root).

Sebbene alcuni passaggi siano facoltativi, dovresti comunque leggerli poiché contengono le informazioni necessarie per comprendere il resto del processo.

  1. Scarica e decomprimi il tarball di origine.

    Questi sono disponibili da kernel.org. Gli ultimi sono elencati in prima pagina, ma se guardi all'interno del /pub/ directory, troverai un archivio che risale alla versione 1.0. A meno che tu non abbia una ragione speciale per fare diversamente, è meglio scegliere "Latest Stable". Al momento in cui scrivo, questo è un tar.xz da 74 MB file.

    Una volta scaricato il tarball, devi decomprimerlo da qualche parte. La posizione normale è in /usr/src . Metti il ​​file lì e:

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

    Nota che le singole distribuzioni di solito consigliano di utilizzare uno dei loro pacchetti sorgente invece dell'albero vanilla. Questo contiene patch specifiche per la distribuzione, che possono essere importanti o meno per te. Corrisponderà anche alle intestazioni include del kernel utilizzate per compilare alcuni strumenti dello spazio utente, anche se molto probabilmente sono comunque identici.

    In oltre 15 anni di creazione di kernel personalizzati (principalmente su Fedora/Debian/Ubuntu), non ho mai avuto problemi nell'usare il sorgente vanilla. Fare ciò non fa davvero molta differenza, tuttavia, a parte il fatto che se vuoi il kernel più recente in assoluto, la tua distribuzione probabilmente non l'ha ancora impacchettato. Quindi la strada più sicura è ancora usare il pacchetto distro, che dovrebbe essere installato in /usr/src . Preferisco l'ultima scuderia in modo da poter fare da cavia prima che venga lanciata nelle distribuzioni 🙂

  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 molto di tentativi ed errori. Ciò 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]/.config file, quindi puoi usarlo. Altrimenti, controlla un /proc/config.gz . Questa è una funzionalità opzionale aggiunta nel kernel 2.6. Se esiste, copialo nel livello superiore dell'albero dei sorgenti e gunzip -c config.gz > .config .

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

La configurazione della distribuzione non è molto ideale, nel senso che include quasi tutti i possibili driver hardware. Questo non ha molta importanza per la funzionalità del kernel, dal momento che sono moduli e la maggior parte di essi non verrà mai utilizzata, ma aumenta in modo molto significativo il tempo necessario per la compilazione. È anche scomodo in quanto richiede un initramfs per contenere determinati moduli principali (vedere il passaggio n. 4 di seguito). Tuttavia, è probabilmente un punto di partenza migliore rispetto all'impostazione predefinita.

Nota che le opzioni di configurazione si spostano e cambiano da una versione del kernel alla successiva e quando esegui una delle make config programmi sotto il tuo .config verrà prima analizzato e aggiornato per corrispondere alla nuova versione. Se la configurazione proviene da una versione molto precedente, ciò potrebbe portare a strani risultati, quindi presta attenzione quando esegui la configurazione. AFAIK non funzionerà affatto al contrario (usando una configurazione da una versione più recente).

  1. Crea un .config razione.

    [src]/.config è un file di testo utilizzato per configurare il kernel. Non modificare questo file direttamente . La modifica delle opzioni spesso non è una semplice questione di sostituzione di una Y con un N , eccetera; di solito c'è un insieme di interdipendenze e possibilità di ramificazione. Invece, vuoi usare una delle destinazioni di configurazione dal makefile del kernel (che significa, inserisci make _____ sulla riga di comando dalla directory di origine di livello superiore):

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

    • make oldconfig è come make config tranne, se hai già un .config da una versione precedente, salterà le domande tranne quelle relative a nuove opzioni. Ce ne possono essere ancora molti e la maggior parte di loro sarà irrilevante per te, quindi di nuovo, non te 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 il -dev pacchetto per ncurses installato. È abbastanza autoesplicativo, fatta eccezione per la ricerca che è accessibile tramite /; la "guida" di F1 fornisce una spiegazione per l'opzione corrente. Esiste una versione alternativa, make nconfig , con alcune funzionalità extra, in cui F2 "syminfo" è l'equivalente di F1 di menuconfig.

    • make xconfig è un'interfaccia GUI completa. Ciò richiede qmake e il -dev pacchetto per Qt da installare, come di nuovo, è un programma che viene compilato e costruito. Se non li stavi utilizzando in precedenza, potrebbe essere un download sostanziale. Il motivo per cui preferisco menuconfig alla versione GUI è che le gerarchie di opzioni vengono presentate utilizzando 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 Impostazioni generali ). La ragione di ciò è menzionata al n. 5 di seguito.

    "Labyrinthine" è un buon modo per descrivere la gerarchia delle opzioni e entrare nei dettagli va ben oltre lo scopo di domande e risposte come questa. Se vuoi sederti e ripassare tutto, dedica ore . Greg Kroah-Hartman (dev lead 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 al n. 2), quindi esaminalo 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 punto successivo...

  2. Informazioni su initramfs [facoltativo]

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

    Funziona bene e non rappresenta alcun tipo di svantaggio, ma probabilmente è una complicazione non necessaria quando si costruisce il proprio kernel. Il problema è che, se non usi un initramfs, devi assicurarti che i driver per il tuo filesystem di root (e il dispositivo su cui è installato) siano integrati nel kernel. In menuconfig , questa è la differenza tra un M (=modulo) e un * (=integrato) opzione. Se non lo fai bene, il sistema fallirà all'inizio del processo di avvio. Quindi, ad esempio, se hai un disco rigido SATA e un filesystem root ext4, hai bisogno di driver per quelli integrati. [Se qualcuno riesce a pensare a qualcos'altro che è un must, lascia un commento e lo incorporerò qui].

    Se vuoi usare un initramfs , dovrai selezionare le opzioni appropriate in Impostazioni generali . C'è una guida schematica per crearne uno integrato nel kernel in [src]/Documentation/filesystems/ramfs-rootfs-initramfs.txt , ma nota che le distribuzioni non lo fanno; usano un file cpio esterno compresso con gzip. Tuttavia, quel documento contiene una discussione su cosa dovrebbe essere contenuto in initramfs (vedi “Contenuto di initramfs”).

  3. Crea e installa il kernel.

    Il prossimo passo è facile. Per creare il kernel, esegui semplicemente make nel [src] directory. Se utilizzi un sistema multi-core, puoi aggiungere -j N per velocizzare le cose, dove N è il numero di core che vuoi dedicare + 1. Non c'è nessun test o check . Una volta fatto, puoi make modules . Su una scatola veloce, tutto questo dovrebbe richiedere <10 minuti.

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

    Puoi quindi make install per installare il kernel in una posizione predefinita. La mia raccomandazione, tuttavia, è di farlo da soli per garantire che nessun file esistente venga sovrascritto. Cerca in [src]/arch/[ARCH]/boot per un file chiamato bzImage , dove [ARCH] è x86 se sei su una macchina x86 o x86-64 (e qualcos'altro se sei su qualcos'altro). Copialo in /boot e rinominalo in qualcosa di più specifico e informativo (non importa cosa). 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 in /lib/modules creato da make modules_install , che includerà la stringa "Versione locale", ad esempio System.map-3.13.3-mykernel .

  4. Configura il bootloader di GRUB 2.

    Se non stai usando grub (la maggior parte degli utenti desktop Linux lo sono), questo ovviamente non si applica a te. Dovresti avere un /etc/grub.d/40_custom file con non molto in esso. In caso contrario, crealo di proprietà di root e chmod 755 (deve essere eseguibile). A questo aggiungi:

    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 al set root= linea. L'esempio presuppone che grub sia stato installato sulla prima partizione del primo disco rigido (hd0,1). Se hai più unità, potresti voler utilizzare invece 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 sia nel tuo filesystem di root, questo dovrebbe corrispondere anche a root= direttiva su linux line, che indica il tuo filesystem di root (quello con /sbin/init e /lib/modules ). La versione UUID è root=UUID=[the UUID] .

    Puoi guardare il tuo /boot/grub2/grub.cfg esistente per avere un indizio sul nome del dispositivo. Ecco una breve guida su grub 2. Quando sei soddisfatto, esegui grub2-mkconfig -o /boot/grub2/grub.cfg (ma esegui il backup del tuo attuale grub.cfg primo). Potresti quindi voler modificare quel file e spostare la tua voce in alto. Dovrebbe comunque contenere 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 lo fa, quindi, usando un titolo distinto con menuentry è una buona idea). Puoi rimuoverlo in seguito se tutto va bene.

    Puoi anche semplicemente inserire la menuentry in grub.cfg direttamente, ma alcune distribuzioni lo sovrascriveranno quando il loro kernel viene aggiornato (mentre usando /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 scegliendo un vecchio kernel e torna al passaggio 3 (tranne l'uso di .config lo hai già e modificalo). Potrebbe essere una buona idea make clean (o make mrproper ) tra un tentativo e l'altro ma assicurati di copiare [src]/.config prima su un backup, perché verrà cancellato. Questo aiuta a garantire che gli oggetti utilizzati nel processo di compilazione non siano obsoleti.

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

    Una cosa che dovresti probabilmente fare è un collegamento simbolico (ln -s -i ) /lib/modules/X.X.X/source e /lib/modules/X.X.X/build al /usr/src directory in cui si trova l'albero dei sorgenti (mantienilo). Ciò è necessario affinché alcuni strumenti dello spazio utente (e programmi di installazione di driver di terze parti) possano accedere al sorgente per il kernel in esecuzione.

    Un problema correlato a questo è .h file in /usr/include , ecc. Questi cambiano molto gradualmente e sono compatibili con le versioni precedenti. Hai due scelte:

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

    • Usa make headers_install .

    Dal momento che sono compatibili con le versioni precedenti (il che significa che "un programma creato su una libreria C che utilizza intestazioni del kernel precedenti dovrebbe essere eseguito su un kernel più nuovo"), non devi essere troppo esigente su questo. L'unico problema potenziale sarebbe se si compila un kernel personalizzato e lo si conserva per un po', durante il quale la distribuzione aggiorna il pacchetto "kernel-headers" a un nuovo versione di quella utilizzata per compilare il kernel, e risulta essere una certa incompatibilità (che si applicherebbe solo al software successivamente compilato dal sorgente).

Correlati:Linux – il comando finger non funziona?

Riferimenti

Ecco alcune risorse:

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

  • Il [src]/Documentation contiene molte informazioni che possono essere utili per la configurazione.

  • Gran parte del libro di Greg K-H Linux Kernel in a Nutshell (disponibile gratuitamente come serie di PDF) ruota attorno alla creazione del kernel.

  • Grub 2 ha un manuale online.

Correlati:Env o non env?


Linux
  1. Installazione e utilizzo di Homebrew Package Manager su Linux

  2. Configurazione di un indirizzo IPv6 in Red Hat Enterprise Linux 7 e 8

  3. Installazione e configurazione di Grafana in Linux

  4. Linux:differenza tra spazio utente e spazio kernel?

  5. Come salvare o esportare una configurazione del kernel Linux personalizzata?

Kernel Linux e le sue funzioni

Gestisci e monitora i moduli del kernel Linux con Kmon

Installa Linux Kernel 4.15 in sistemi basati su RPM e DEB

Installazione e configurazione di Jenkins in Linux

Guida per l'installazione e la disinstallazione di Anaconda in Linux

Come compilare il kernel Linux dal sorgente per creare un kernel personalizzato