Introduzione
In questa serie di articoli voglio esaminare il sistema di build del distribuitore buildroot e condividere la mia esperienza nella sua personalizzazione. Qui troverete un'esperienza pratica per creare un piccolo sistema operativo con interfaccia grafica e funzionalità ridotte.
Prima di tutto, non bisogna confondere il sistema di build con il distributore. Buildroot può assemblare un sistema da un insieme di pacchetti che gli sono stati forniti. Buildroot è basato su makefile e quindi ha enormi possibilità di personalizzazione. Vuoi sostituire un pacchetto con un'altra versione, aggiungere il tuo pacchetto, cambiare le regole di build di un pacchetto o personalizzare il file system dopo aver installato tutti i pacchetti? Buildroot può fare tutto questo.
In Russia buildroot viene utilizzato, ma a mio avviso ci sono poche informazioni in lingua russa per i principianti.
L'obiettivo del lavoro è assemblare un distributore con avvio live, interfaccia icewm e browser. La piattaforma target è virtualbox.
Perché costruire la tua distribuzione? Spesso è necessario avere funzionalità limitate in presenza di risorse limitate. Ancora più frequentemente, nella creazione automatizzata, è necessario generare firmware. Adattare una distribuzione generale, rimuovendo i pacchetti superflui per trasformarla in un firmware, è un processo molto più laborioso rispetto alla costruzione di una nuova distribuzione. Anche l'uso di Gentoo ha le sue limitazioni.
Il sistema Buildroot è molto potente, ma non farà nulla per voi. Può solo fornire opportunità e automatizzare il processo di compilazione.
Sistemi di costruzione alternativi (yocto, open build system e altri) non sono considerati e non vengono confrontati.
Dove trovare e come iniziare
Sito del progetto — . Qui puoi scaricare l'ultima versione e leggere la guida. Puoi anche contattare la comunità, c'è un bug tracker, mailing list e canale IRC.
Buildroot utilizza defconfig per la scheda target di costruzione. Defconfig è un file di configurazione che contiene solo le opzioni che non hanno un valore predefinito. Questo file determina cosa e come verrà compilato. È possibile configurare separatamente le impostazioni di busybox, linux-kernel, uclibc, caricatori di avvio u-boot e barebox, ma tutti questi saranno legati alla scheda target.
Dopo aver estratto l'archivio scaricato o clonando da git, otteniamo un buildroot pronto all'uso. Puoi leggere in dettaglio sulla struttura delle directory nel manuale; parlerò delle parti più importanti:
board — la directory con i file specifici per ogni scheda. Questi possono essere script per la generazione delle immagini di sistema (iso, sdcart, cpio e altri), la directory overlay, la configurazione del kernel e altro
configs — la defconfig della scheda. La defconfig è una configurazione incompleta della scheda. In essa vengono memorizzati solo i parametri che differiscono dalle impostazioni predefinite
dl — la directory con i codici sorgente/file scaricati per la costruzione
output/target — il file system dell'OS ottenuto. Da esso vengono creati successivamente i file immagine per il boot/installazione
output/host — utilità host per la costruzione
output/build — pacchetti compilati
La configurazione della build avviene tramite KConfig. Questo stesso sistema è utilizzato per la compilazione del kernel linux. Ecco un elenco dei comandi più frequentemente utilizzati (da eseguire nella directory buildroot):
- make menuconfig — per avviare la configurazione della build. Puoi anche utilizzare l'interfaccia grafica (make nconfig, make xconfig, make gconfig)
- make linux-menuconfig — per avviare la configurazione del kernel.
- make clean — pulisce i risultati della costruzione (tutto ciò che si trova in output)
- make — compila il sistema. Durante questa operazione non vengono ricompilati i processi già costruiti
- make defconfig_name — passa alla configurazione di un determinato defconfig
- make list-defconfigs — mostra l'elenco dei defconfig
- make source — scarica solo i file di installazione, senza compilare.
- make help — visualizza un elenco di comandi disponibili
Note importanti e suggerimenti utili
Buildroot non ricompila i pacchetti già costruiti! Pertanto, può verificarsi una situazione in cui è necessaria una ricompilazione completa.
È possibile ricompilare un singolo pacchetto con il comando make packagename-rebuild. Ad esempio, è possibile ricompilare il kernel linux:
make linux-rebuildBuildroot memorizza lo stato di qualsiasi pacchetto creando file .stamp nella directory output/build/$packagename:

Di conseguenza, è possibile ricompilare root-fs e 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
In buildroot c'è un insieme di variabili per una facile configurazione
- $TOPDIR — directory radice di buildroot
- $BASEDIR — directory OUTPUT
- $HOST_DIR, $STAGING_DIR, $TARGET_DIR — directory per la costruzione di host fs, staging fs, target fs.
- $BUILD_DIR — directory contenente pacchetti estratti e costruiti
Visualizzazione
In buildroot, c'è la possibilità di visualizzazione. È possibile costruire uno schema delle dipendenze, un grafico del tempo di compilazione e un grafico delle dimensioni dei pacchetti nel sistema finale. I risultati sono disponibili in formato pdf (con opzioni per svn, png) nella directory output/graph.
Esempi di comandi di visualizzazione:
make graph-dependscostruire l'albero delle dipendenzemake -graph-dependscostruire l'albero delle dipendenze di un pacchetto specificoBR2_GRAPH_OUT=png make graph-buildcostruire un grafico del tempo di compilazione in formato PNGmake graph-sizecostruire un grafico delle dimensioni dei pacchetti
Script utili
Nella directory buildroot c'è una sottodirectory utils con script utili. Ad esempio, c'è uno script che controlla la correttezza della descrizione dei pacchetti. Questo può essere utile quando si aggiungono i propri pacchetti (lo farò più tardi). Nel file utils/readme.txt c'è una descrizione di questi script.
Compiliamo una distribuzione stock
È importante ricordare che tutte le operazioni vengono eseguite come utente normale, non come root.
Tutti i comandi vengono eseguiti nella radice di buildroot. Nella fornitura di buildroot è già presente un insieme di configurazioni per molte schede comuni e virtualizzazioni.
Guardiamo l'elenco delle configurazioni:

Passiamo alla configurazione qemu_x86_64_defconfig
make qemu_x86_64_defconfigE avviamo la compilazione
makeLa build è completata con successo, vediamo i risultati:
![]()
Buildroot ha creato immagini che possono essere eseguite 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 è un sistema eseguito in qemu:

Creazione della configurazione per la scheda personalizzata
Aggiunta dei file per la scheda
Guardiamo l'elenco delle configurazioni:

Nell'elenco vediamo pc_x86_64_efi_defconfig. Creeremo la nostra scheda copiando la sua configurazione:
cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfigCreiamo subito un catalogo 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_defconfigIn questo modo, ora la configurazione della build (che si trova in .config nella radice della directory di buildroot) corrisponde alla macchina target x86-64 con avvio legacy (bios).
Copiamo la configurazione del linux-kernel (sarà utile in seguito):
cp board/pc/linux.config board/my_x86_board/Impostazione dei parametri di build tramite KConfig
Avviamo la configurazione:
make menuconfig Si aprirà la finestra KConfig. È possibile configurare tramite interfaccia grafica (make nconfig, make xconfig, make gconfig):

Entriamo nella prima sezione Target Options. Qui è possibile scegliere l'architettura target per cui verrà eseguita la build.

Opzioni di costruzione — qui trovi diverse impostazioni per la compilazione. Puoi specificare le directory con il codice sorgente, il numero di thread di compilazione, i mirror per il download del codice sorgente e altre impostazioni. Lasciamo le impostazioni predefinite.
Toolchain – qui si configura l'insieme degli strumenti di compilazione. Maggiori dettagli su di esso.

Tipo di toolchain – il tipo di toolchain utilizzato. Può essere integrato in buildroot o una toolchain esterna (puoi specificare una directory con già i file compilati o un URL per il download). Ci sono opzioni aggiuntive per diverse architetture. Ad esempio, per arm puoi semplicemente scegliere la versione della toolchain esterna Linaro.
Libreria C – selezione della libreria C. Questo determina il funzionamento di tutto il sistema. Di solito si utilizza glibc, che supporta tutte le funzionalità possibili. Tuttavia, potrebbe rivelarsi troppo grande per un sistema embedded, pertanto spesso si preferiscono uglibc o musl. Noi sceglieremo glibc (in seguito sarà necessaria per utilizzare systemd).
Kernel Headers e serie Custom Kernel Headers – devono corrispondere alla versione del kernel che sarà presente nel sistema costruito. Per i kernel headers puoi anche specificare un percorso a un tarball o un repository git.
VERSIONI DEL COMPILATORE GCC – scegliere la versione del compilatore da utilizzare per la compilazione
Abilita il supporto C++ – selezioniamo il supporto per le librerie c++ nel sistema. In seguito ci sarà utile.
Opzioni gcc aggiuntive – è possibile specificare opzioni aggiuntive per il compilatore. Per il momento non ci servono.
La configurazione del sistema consente di impostare i futuri parametri del sistema creato:

La maggior parte degli elementi è chiara dal titolo. Presteremo attenzione ai seguenti punti:
Percorso ai file degli utenti — tabella con gli utenti creati ().
Esempio di file. Sarà creato l'utente user con la password admin, gid/uid automatici, 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 di sovrapposizione del filesystem root — catalogo sovrapposto al target-fs assemblato. Aggiunge nuovi file e sostituisce quelli esistenti.
Script personalizzati da eseguire prima di creare le immagini del filesystem — Script eseguiti immediatamente prima della compressione del filesystem in immagini. Lasceremo lo script vuoto per ora
Passiamo alla sezione Kernel

Qui vengono impostate le configurazioni del kernel. Il kernel è configurato tramite make linux-menuconfig.
È possibile specificare la versione del kernel in vari modi: selettendola da quelle disponibili, inserendo manualmente la versione, indicando un repository o un tarball pronto all'uso.
Configurazione del kernel — percorso verso il file di configurazione del kernel. Puoi scegliere la configurazione predefinita per l'architettura selezionata o un defconfig da Linux. Nei sorgenti di Linux è presente un insieme di defconfig per diversi sistemi target. Puoi trovare quello giusto, . Ad esempio, per la scheda BeagleBone Black puoi .
La sezione Target packages consente di scegliere quali pacchetti verranno installati nel sistema da costruire. Per ora lasciamo tutto invariato. In seguito aggiungeremo i nostri pacchetti a questo elenco.
Filesystem images — elenco delle immagini dei file system che verranno create. Aggiungeremo un'immagine iso

Bootloaders — selezione dei bootloader da costruire. Selezioniamo isolinix

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

Salvataggio della configurazione di sistema
Salviamo questa configurazione tramite KConfig.
Dopodiché salveremo il nostro defconfig:
make savedefconfigConfigurazione del kernel Linux
La configurazione del kernel linux si esegue con il seguente comando:
make linux-menuconfigAggiungiamo il supporto per la scheda video Virtualbox

Aggiungiamo il supporto per Virtualbox Guest integration

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

Pertanto, bisogna copiare manualmente il file di configurazione nella directory di destinazione:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.configDopo di che, eseguiamo una ricompilazione completa dell'intero sistema. Poiché buildroot non ricompila ciò che è già stato compilato, è necessario specificare manualmente i pacchetti da ricompilare. Per non perdere tempo e pazienza, è più semplice ricompilare completamente un sistema ridotto):
make clean;makeAl termine della compilazione, avviamo VirtualBox (testato su versioni 5.2 e 6.0) avviando dal cd. Parametri del sistema:

Avvio dall'immagine iso compilata:

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