Introduzione
In questa serie di articoli voglio esaminare il sistema di build del distribuito buildroot e condividere la mia esperienza nella sua personalizzazione. Qui ci sarà esperienza pratica nella creazione di un piccolo sistema operativo con interfaccia grafica e funzionalità minime.
Prima di tutto, non bisogna confondere il sistema di build con il distribuito. Buildroot può assemblare un sistema a partire da un insieme di pacchetti che gli vengono proposti. Buildroot è basato su file make e offre quindi enormi possibilità di personalizzazione. Sostituire un pacchetto con un'altra versione, aggiungere il proprio pacchetto, modificare le regole di assemblaggio del pacchetto, personalizzare il file system dopo l'installazione di tutti i pacchetti? Buildroot può fare tutto questo.
In Russia buildroot viene utilizzato, ma a mio avviso c'è poca informazione in lingua russa per i principianti.
L'obiettivo del lavoro è assemblare un distribuito con avvio live, interfaccia icewm e browser. La piattaforma target è virtualbox.
Perché assemblare il proprio distribuito? Spesso è necessaria una funzionalità limitata con risorse limitate. Ancor più frequentemente, nell'automazione è necessario creare firmware. Adattare un distribuito generico, rimuovendo i pacchetti superflui e trasformandolo in firmware è un processo molto più laborioso rispetto all'assemblaggio di un nuovo distribuito. Anche l'uso di Gentoo ha le sue limitazioni.
Il sistema Buildroot è molto potente, ma non farà nulla per te. Può solo fornire opportunità e automatizzare il processo di assemblaggio.
I sistemi di build alternativi (yocto, open build system e altri) non vengono presi in considerazione e non vengono confrontati.
Dove trovare e come iniziare
Sito del progetto — . Qui puoi scaricare l'ultima versione e leggere la documentazione. Puoi anche rivolgerti alla comunità, ci sono un bug tracker, mail-lists e un canale irc.
Buildroot opera con defconfig per la scheda target di assemblaggio. Defconfig è un file di configurazione che contiene solo opzioni senza valore predefinito. Esso determina cosa e come sarà assemblato. È possibile anche configurare separatamente i conf di busybox, linux-kernel, uglibc, bootloader u-boot e barebox, ma tutti saranno legati alla scheda target.
Dopo aver estratto l'archivio scaricato o clonando da git, otteniamo un buildroot pronto per l'uso. Puoi leggere dettagliatamente sulla struttura delle directory nella documentazione; parlerò delle più importanti:
board — catalogo con file specifici per ogni scheda. Possono essere script per la creazione di immagini di sistema (iso, sdcart, cpio e altri), catalogo overlay, configurazione del kernel e altri.
configs — il defconfig della scheda. Defconfig è una configurazione incompleta della scheda. Contiene solo i parametri differenti rispetto alle impostazioni predefinite.
dl — catalogo con i codici sorgente/file scaricati per la compilazione.
output/target — il file system compilato del sistema operativo ottenuto. Successivamente, da esso vengono creati le immagini per il caricamento/installazione.
output/host — utilità host per la compilazione.
output/build — pacchetti compilati.
La configurazione della compilazione si effettua tramite KConfig. Questo stesso sistema è utilizzato per compilare il kernel Linux. Ecco un elenco dei comandi più utilizzati (da eseguire nella cartella buildroot):
- make menuconfig — attivare le impostazioni di compilazione. È possibile anche utilizzare un'interfaccia grafica (make nconfig, make xconfig, make gconfig).
- make linux-menuconfig — attivare la configurazione del kernel.
- make clean — pulire i risultati della compilazione (tutto ciò che è contenuto in output).
- make — compilare il sistema. Durante questo processo non viene effettuata la ricompilazione dei processi già compilati.
- make defconfig_name — passare alla configurazione di un determinato defconfig.
- make list-defconfigs — mostrare l'elenco dei defconfig.
- make source — scaricare solo i file di installazione, senza compilazione.
- make help — mostrare l'elenco dei comandi disponibili.
Osservazioni importanti e consigli utili.
Buildroot non ricompila i pacchetti già compilati! Pertanto, può verificarsi una situazione in cui è necessaria una ricompilazione completa.
È possibile ricompilare un pacchetto specifico con il comando: make packagename-rebuild. Ad esempio, è possibile ricompilare il kernel Linux:
make linux-rebuild.Buildroot memorizza lo stato di qualsiasi pacchetto creando file .stamp nella cartella output/build/$packagename:

Pertanto, è possibile ricompilare il root-fs e le immagini senza ricompilare i pacchetti:
rm output/build/host-gcc-final-*/.stamp_host_installed; rm -rf output/target; find output/ -name ".stamp_target_installed" | xargs rm -rf; makeVariabili utili.
Nel buildroot esiste un insieme di variabili per una configurazione più comoda.
- $TOPDIR — cartella principale di buildroot.
- $BASEDIR — cartella OUTPUT.
- $HOST_DIR, $STAGING_DIR, $TARGET_DIR — cartelle di compilazione per host fs, staging fs, target fs.
- $BUILD_DIR — cartella con pacchetti estratti e compilati.
Visualizzazione
Nel buildroot è possibile effettuare visualizzazioni. Si possono costruire schemi di dipendenze, grafici del tempo di compilazione e grafici delle dimensioni dei pacchetti nel sistema finale. I risultati sono disponibili sotto forma di file pdf (c'è la scelta tra svn e png) nella cartella output/graph.
Esempi di comandi di visualizzazione:
crea graph-dependscostruire l'albero delle dipendenzecrea <pkg>-graph-dependscostruire l'albero delle dipendenze di un pacchetto specificoBR2_GRAPH_OUT=png crea graph-buildcostruire un grafico del tempo di compilazione con output in PNGcrea graph-sizecostruire un grafico delle dimensioni dei pacchetti
Script utili
Nella cartella buildroot c'è una sottocartella utils con script utili. Ad esempio, c'è uno script che verifica la correttezza delle descrizioni dei pacchetti. Questo può essere utile quando si aggiungono i propri pacchetti (lo farò più tardi). Nella cartella utils/readme.txt c'è una descrizione di questi script.
Compiliamo un pacchetto stock
È importante ricordare che tutte le operazioni vengono effettuate a nome di un utente normale, non root.
Tutti i comandi vengono eseguiti nella radice di buildroot. Nella fornitura di buildroot ci sono già una serie di configurazioni per molte schede comuni e virtualizzazione.
Controlliamo l'elenco delle configurazioni:

Passiamo alla configurazione qemu_x86_64_defconfig
make qemu_x86_64_defconfigE avviamo la compilazione
makeLa compilazione è completata con successo, controlliamo i risultati:
![]()
Buildroot ha creato immagini che possono essere avviate in Qemu per verificare che funzionino.
qemu-system-x86_64 -kernel output/images/bzImage -hda output/images/rootfs.ext2 -append "root=\/dev\/sda rw" -s -SIl risultato — sistema avviato in qemu:

Creazione della configurazione della propria scheda
Aggiunta dei file della scheda
Controlliamo l'elenco delle configurazioni:

Nell'elenco vediamo pc_x86_64_efi_defconfig. Creeremo la nostra scheda copiandola dalla configurazione:
cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfigCreiamo subito una cartella per la scheda per memorizzare i nostri script, rootfs-overlay e altri file necessari:
mkdir board/my_x86_boardPassiamo a questo defconfig:
make my_x86_board_defconfigOra, la configurazione di compilazione (memorizzata in .config nella radice della cartella buildroot) corrisponde alla macchina target x86-64 legacy(bios).
Copiamo la configurazione linux-kernel (che sarà utile più avanti):
cp board/pc/linux.config board/my_x86_board/Configurazione dei parametri di compilazione tramite KConfig
Iniziamo la configurazione:
, e davanti a te apparirà un'interfaccia testuale comoda con la visualizzazione delle descrizioni dei parametri. Si aprirà una finestra KConfig. È possibile configurare tramite interfaccia grafica (make nconfig, make xconfig, make gconfig):

Entriamo nella prima sezione Opzioni target. Qui è possibile scegliere l'architettura target per la quale si effettuerà la compilazione.

Opzioni di compilazione — qui ci sono varie impostazioni di compilazione. È possibile specificare le cartelle con il codice sorgente, il numero di thread per la compilazione, mirror per il download del codice sorgente e altre impostazioni. Lasceremo le impostazioni di default.
Toolchain – qui si configura l'insieme di strumenti di compilazione. Maggiori dettagli su di esso.

Tipo di toolchain – il tipo di toolchain utilizzato. Può essere integrato in buildroot o un toolchain esterno (puoi specificare la directory con una versione già compilata o l'URL per il download). Ci sono opzioni aggiuntive per diverse architetture. Ad esempio, per arm puoi semplicemente scegliere la versione del toolchain esterno Linaro.
Libreria C – selezione della libreria C. Questo influisce sul funzionamento dell'intero sistema. Di solito si usa glibc, che supporta tutte le funzionalità possibili. Tuttavia, potrebbe risultare troppo grande per un sistema embedded, quindi spesso si scelgono uglibc o musl. Noi sceglieremo glibc (in seguito sarà necessario per usare systemd).
Intestazioni del kernel e serie di intestazioni del kernel personalizzate – devono corrispondere alla versione del kernel che sarà nel sistema in fase di assemblaggio. Per le intestazioni del kernel è possibile anche specificare il percorso a un tarball o a un repository git.
VERSIONI DEL COMPILATORE GCC – selezione della versione del compilatore che sarà utilizzata per la compilazione
Abilita supporto C++ – selezioniamo per la compilazione con supporto per le librerie C++ nel sistema. Questo ci sarà utile in seguito.
Opzioni gcc aggiuntive – è possibile specificare opzioni aggiuntive del compilatore. Al momento non sono necessarie.
La configurazione del sistema consente di specificare i parametri futuri del sistema creato:

La maggior parte dei punti è chiara dal titolo. Focalizziamoci sui seguenti punti:
Percorso verso le tabelle degli utenti — tabella con gli utenti da creare ().
Esempio di file. Sarà creato un utente user con password admin, gid/uid automatico, shell /bin/sh, gruppo predefinito user, membro del gruppo root, commento Foo user
[alexey@alexey-pc buildroot ]$ cat board/my_x86_board/users.txt
user -1 user -1 =admin /home/user /bin/sh root Foo userDirectory sovrapposte del filesystem root — directory sovrapposte al target-fs assemblato. Aggiunge nuovi file e sostituisce i file esistenti.
Script personalizzati da eseguire prima di creare le immagini del filesystem — Script eseguiti subito prima di comprimere il filesystem in immagini. Lasciamo in bianco lo script per ora
Passiamo alla sezione Kernel

Qui vengono impostate le configurazioni del kernel. Il kernel stesso viene configurato tramite make linux-menuconfig.
È possibile specificare la versione del kernel in vari modi: scegliere tra quelle disponibili, inserire manualmente la versione, specificare un repository o un tarball già pronto.
Configurazione del kernel — percorso al file di configurazione del kernel. Puoi scegliere la configurazione predefinita per l'architettura selezionata o un defconfig da Linux. Nei sorgenti di Linux c'è un insieme di defconfig per diversi sistemi target. Puoi trovare quello necessario, . Ad esempio, per la scheda beagle bone black puoi .
La sezione Target packages consente di selezionare quali pacchetti verranno installati nel sistema da costruire. Per ora lasciamo tutto invariato. In seguito aggiungeremo i nostri pacchetti a questo elenco.
Filesystem images — un elenco delle immagini dei file system che verranno assemblate. Aggiungeremo un'immagine iso

Bootloaders — selezione dei bootloader da assemblare. Scegliamo isolinix

Configurazione di Systemd
Systemd sta diventando uno dei pilastri di linux, al pari del kernel e di glibc. Per questo ho separato la sua configurazione in un punto distinto.
Si configura tramite make menuconfig, quindi Target packages → System tools → systemd. Qui puoi specificare quali servizi systemd saranno installati e avviati all'avvio del sistema.

Salvataggio della configurazione di sistema
Salviamo questo config tramite KConfig.
Dopo di che salveremo il nostro defconfig:
make savedefconfigConfigurazione del kernel Linux
La configurazione del kernel linux viene attivata con il seguente comando:
make linux-menuconfigAggiungiamo il supporto per la scheda video Virtualbox

Aggiungiamo il supporto per l'integrazione degli ospiti Virtualbox

Salviamo e usciamo. IMPORTANTE: la configurazione sarà salvata in output/build/linux-$version/config, ma non in board/my_x86_board/linux.config

Quindi è necessario copiare manualmente il config nella posizione di archiviazione:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.configDopo di che eseguiremo una completa ricostruzione dell'intero sistema. Poiché buildroot non ricostruisce già assemblato, è necessario specificare manualmente i pacchetti per la ricostruzione. Per non perdere tempo e nervi, è più semplice ricostruire completamente un piccolo sistema):
make clean;makeAl termine della costruzione avviamo VirtualBox (verificato su versioni 5.2 e 6.0) avviando da un CD. Parametri di sistema:

Avvio dall’iso assemblato:

Elenco dei materiali utilizzati
- Manuale di Buildroot
Fonte: habr.com
