Introducere
În această serie de articole, vreau să discut despre sistemul de construire a distribuțiilor buildroot și să împărtășesc experiența mea de personalizare a acestuia. Aici va fi o experiență practică de creare a unui sistem de operare mic cu o interfață grafică și funcționalitate minimală.
În primul rând, nu trebuie să confundăm sistemul de construire cu distribuția. Buildroot poate construi un sistem dintr-un set de pachete propuse. Buildroot se bazează pe fișiere make și, prin urmare, are oportunități uriașe de personalizare. Să înlocuiești un pachet cu o altă versiune, să adaugi propriul pachet, să schimbi regulile de construire ale pachetului, să personalizezi sistemul de fișiere după instalarea tuturor pachetelor? Toate acestea sunt posibile cu buildroot.
În Rusia, buildroot este utilizat, dar, din punctul meu de vedere, există puține informații în limba rusă pentru începători.
Scopul lucrării este să construim o distribuție cu încărcare live, interfață icewm și browser. Platforma țintă este virtualbox.
De ce să construiești propria distribuție? Adesea, este nevoie de o funcționalitate limitată cu resurse limitate. Și mai frecvent, în automatizare, este necesar să creezi firmware. Adaptarea unei distribuții de uz general, curățând pachetele inutile și transformând-o într-un firmware, este un proces mult mai laborios decât construirea unei noi distribuții. Utilizarea Gentoo are și ea propriile sale limitări.
Buildroot este un sistem foarte puternic, dar nu va face nimic în locul tău. Poate doar să ofere oportunități și să automatizeze procesul de construire.
Sistemele alternative de construcție (yocto, open build system și altele) nu sunt luate în considerare și nu sunt comparate.
Unde să găsim și cum să începem
Site-ul proiectului — . Aici poți descărca cea mai recentă versiune și citi ghidul. De asemenea, poți contacta comunitatea, există un tracker de bug-uri, liste de e-mailuri și un canal IRC.
Buildroot operează cu defconfig-uri pentru placa țintă de construire. Defconfig este un fișier de configurare care conține doar opțiuni fără valori implicite. Acesta definește ce și cum va fi construit. De asemenea, poți personaliza separat config-urile busybox, linux-kernel, uglibc, încărcătoarele u-boot și barebox, dar toate acestea vor fi legate de placa țintă.
După despachetarea arhivei descărcate sau clonarea din git, obținem un buildroot gata de utilizare. Despre structura directorului se poate citi în ghid, dar voi povesti despre cele mai importante:
board — catalog cu fișiere specifice pentru fiecare plăcă. Acestea pot include scripturi pentru generarea imaginilor sistemului (iso, sdcart, cpio și altele), catalog overlay, configurația nucleului și altele.
configs — efectiv defconfig-ul plăcii. Defconfig — este o configurație incompletă a plăcii. Acesta conține doar parametrii care diferă de setările implicite.
dl — catalog cu codurile sursă/fișierele descărcate pentru compilare.
output/target — sistemul de fișiere compilat al sistemului de operare obținut. În continuare, din acesta sunt create imagini pentru bootare/instalare.
output/host — utilitare host pentru compilare.
output/build — pachete compilate.
Configurarea compilării se realizează prin KConfig. Acesta din urmă este folosit și pentru compilarea nucleului Linux. Lista celor mai frecvent utilizate comenzi (executați în catalogul buildroot):
- make menuconfig — a apela configurarea compilării. De asemenea, poate fi folosit un interfață grafică (make nconfig, make xconfig, make gconfig).
- make linux-menuconfig — a apela configurația nucleului.
- make clean — a curăța rezultatele compilării (tot ce este stocat în output).
- make — a compila sistemul. În acest caz, nu se va efectua recompilarea proceselor deja compilate.
- make defconfig_name — a schimba configurația la un anumit defconfig.
- make list-defconfigs — a afișa lista defconfig-urilor.
- make source — doar a descărca fișierele de instalare, fără a compila.
- make help — a afișa lista comenzilor disponibile.
Observații importante și sfaturi utile.
Buildroot nu recompune pachetele deja compilate! Prin urmare, ar putea apărea o situație în care este necesară o recompilare completă.
Se poate recompila un pachet individual cu comanda make packagename-rebuild. De exemplu, se poate recompila nucleul Linux:
make linux-rebuild.Buildroot păstrează starea oricărui pachet prin crearea fișierelor .stamp în catalogul output/build/$packagename:

Prin urmare, se pot recompila root-fs și imaginile fără recompilarea pachetelor:
rm output/build/host-gcc-final-*/.stamp_host_installed;rm -rf output/target;find output/ -name ".stamp_target_installed" |xargs rm -rf ; make.Variabile utile.
În buildroot există un set de variabile pentru configurare ușoară.
- $TOPDIR — catalogul rădăcină pentru buildroot.
- $BASEDIR — catalogul OUTPUT.
- $HOST_DIR, $STAGING_DIR, $TARGET_DIR — catalogele pentru sistemele de fișiere host, staging și target.
- $BUILD_DIR — catalogul cu pachete despachetate și compilate.
Vizualizare
În buildroot există posibilitatea de vizualizare. Se poate construi un grafic de dependențe, un grafic al timpului de compilare, un grafic al dimensiunilor pachetelor în sistemul final. Rezultatele sunt în formă de fișiere pdf (alegerea este între svn, png) în catalogul output/graph.
Exemple de comenzi pentru vizualizare:
make graph-dependsconstruiește un arbore de dependențemake -graph-dependsconstruiește arborele de dependențe pentru un anumit pachetBR2_GRAPH_OUT=png make graph-buildconstruiește un grafic al timpului de compilare cu ieșire în PNGmake graph-sizeconstruiește un grafic al dimensiunii pachetelor
Scripturi utile
În directorul buildroot există un subdirector utils cu scripturi utile. De exemplu, există un script care verifică corectitudinea descrierii pachetelor. Acest lucru poate fi util la adăugarea propriilor pachete (o voi face mai târziu). În fișierul utils/readme.txt este o descriere a acestor scripturi.
Să construim un distribuitor standard
Este important să reamintim că toate operațiunile se efectuează sub un utilizator obișnuit, nu root.
Toate comenzile se execută în rădăcina buildroot. În livrarea buildroot există deja un set de configurații pentru multe plăci și virtualizare comune.
Să vedem lista de configurații:

Trecem la configurația qemu_x86_64_defconfig
make qemu_x86_64_defconfigȘi începem compilarea
makeCompilarea se finalizează cu succes, să vedem rezultatele:
![]()
Buildroot a construit imagini care pot fi rulate în Qemu pentru a verifica funcționarea acestora.
qemu-system-x86_64 -kernel output/images/bzImage -hda output/images/rootfs.ext2 -append "root=/dev/sda rw" -s -SRezultatul — sistemul rulat în qemu:

Crearea unei configurații pentru placa proprie
Adăugarea fișierelor plăcii
Să vedem lista de configurații:

În listă vedem pc_x86_64_efi_defconfig. Vom crea propria placă, copierea acesteia din configurație:
cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfigImediat vom crea un director pentru placă pentru stocarea scripturilor proprii, rootfs-overlay și alte fișiere necesare:
mkdir board/my_x86_boardTrecem la acest defconfig:
make my_x86_board_defconfigAstfel, acum configurația de compilare (stocată în .config în rădăcina directorului buildroot) corespunde mașinii țintă x86-64 cu încărcare legacy(bios).
Să copiem configurația linux-kernel (ne va fi utilă mai departe):
cp board/pc/linux.config board/my_x86_board/Configurarea parametrilor de compilare prin KConfig
Începem configurarea:
make menuconfig Se va deschide fereastra KConfig. Există posibilitatea de a configura cu interfața grafică (make nconfig, make xconfig, make gconfig):

Intrăm în prima secțiune Opțiuni țintă. Aici putem alege arhitectura țintă pentru care se va desfășura compilarea.

Opțiuni de compilare — aici sunt diverse setări pentru compilare. Putem specifica directoarele cu cod sursă, numărul de fire de execuție pentru compilare, oglinzi pentru descărcarea codului sursă și alte setări. Vom lăsa setările implicite.
Toolchain – aici se configurează instrumentele de compilare. Vor fi discutate în detaliu.

Tipul de toolchain – tipul de toolchain utilizat. Acesta poate fi incorporat în buildroot sau un toolchain extern (se poate specifica calea către un toolchain deja compilat sau un URL pentru descărcare). Există opțiuni suplimentare pentru diferite arhitecturi. De exemplu, pentru arm se poate alege pur și simplu versiunea toolchain-ului extern Linaro.
Biblioteca C – alegerea bibliotecii C. Acesta determină funcționarea întregului sistem. De obicei, se folosește glibc, care suportă întreaga funcționalitate posibilă. Însă, aceasta poate fi prea mare pentru un sistem încorporat, de aceea se aleg frecvent uglibc sau musl. Vom alege glibc (mai departe aceasta va fi necesară pentru utilizarea systemd).
Kernel Headers și Custom Kernel Headers series – trebuie să coincidă cu versiunea kernel-ului care va fi în sistemul compilat. Pentru kernel headers se poate specifica și calea către tarball sau repository git.
VERSIUNI GCC COMPILER – alegerea versiunii compilatorului care va fi utilizată pentru compilare.
Activare suport C++ – vom alege pentru compilare suport pentru bibliotecile C++ în sistem. Aceasta ne va fi utilă mai departe.
Opțiuni suplimentare gcc – se pot specifica opțiuni suplimentare pentru compilator. Nu avem nevoie de acestea deocamdată.
Configurarea sistemului permite specificarea parametrilor viitorului sistem creat:

Majoritatea punctelor sunt clare din denumire. Să ne concentrăm asupra următoarelor puncte:
Calea către tabelele utilizatorilor — tabelul cu utilizatorii creați ().
Exemplu de fișier. Va fi creat utilizatorul user cu parola admin, gid/uid automat, shell-ul /bin/sh, grupul implicit user, membru al grupului root, comentariul Foo user.
[alexey@alexey-pc buildroot ]$ cat board/my_x86_board/users.txt
user -1 user -1 =admin /home/user /bin/sh root Foo userDirectoare suprapuse ale sistemului de fișiere rădăcină — directorul care se suprapune peste target-fs compilat. Adaugă fișiere noi și înlocuiește pe cele existente.
Scripturi personalizate pentru a rula înainte de crearea imaginilor sistemului de fișiere — Scripturi executate direct înainte de a compacta sistemul de fișiere în imagini. Îi vom lăsa momentan scriptul gol.
Să trecem la secțiunea Kernel.

Aici se stabilesc setările kernel-ului. Kernel-ul în sine este configurat prin make linux-menuconfig.
Versiunea kernel-ului poate fi specificată în mai multe moduri: alegând din cele propuse, introducând versiunea manual, specificând repository-ul sau un tarball gata pregătit.
Configurarea kernel-ului — calea către configurația kernel-ului. Se poate alege configurația implicită pentru arhitectura selectată sau defconfig din Linux. În sursele Linux există un set de defconfig-uri pentru diferite sisteme țintă. Poate fi găsit cel dorit, . De exemplu, pentru placa Beagle Bone Black, se poate .
Secțiunea Target packages permite alegerea pachetelor care vor fi instalate în sistemul construit. Deocamdată o vom lăsa neschimbată. Mai târziu vom adăuga propriile pachete în această listă.
Imaginile sistemului de fișiere — lista imaginilor sistemului de fișiere care vor fi construite. Vom adăuga o imagine ISO.

Bootloaders — alegerea bootloaderelor de construit. Vom alege isolinix.

Configurarea Systemd
Systemd devine unul dintre pilonii linux, la fel ca kernelul și glibc. De aceea, am mutat configurarea sa într-un punct separat.
Se configurează prin make menuconfig, apoi Target packages → System tools → systemd. Aici se pot specifica ce servicii systemd vor fi instalate și pornite la startul sistemului.

Salvarea configurației sistemului
Salvăm această configurație prin KConfig.
După care vom salva defconfig-ul nostru:
make savedefconfigConfigurarea kernel-ului Linux
Configurarea kernel-ului linux se invocă cu următoarea comandă:
make linux-menuconfigVom adăuga suport pentru placa grafică Virtualbox.

Vom adăuga suport pentru integrarea Virtualbox Guest.

Salvăm și ieșim. IMPORTANT: configurația va fi salvată în output/build/linux-$version/config, dar nu în board/my_x86_board/linux.config

De aceea, trebuie să copiem manual configurația în locul de stocare:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.configDupă care vom efectua o reconstruire completă a întregului sistem. Deoarece buildroot nu reconstruiește ceea ce a fost deja construit, trebuie să specificăm manual pachetele pentru reconstruire. Pentru a nu pierde timp și nervi, o mică sistem este mai simplu de reconstruit complet):
make clean;makeLa finalizarea construcției, lansăm VirtualBox (s-a verificat pe versiunile 5.2 și 6.0) cu boot de pe CD. Parametrii sistemului:

Boot de pe ISO-ul construit:

Lista materialelor utilizate
- Manual Buildroot
Sursa: habr.com
