This is an old revision of the document!
Acest text vine ca supliment al laboratorului de Yocto și dorește să ofere informații pas cu pas despre îndeplinirea unor sarcini frecvente la generarea unei distribuții Linux (i.e., vă ajută la Tema 2 :P).
Pentru început, aveți nevoie de mașina virtuală furnizată la Tema 2 descărcată.
Se recomandă să aveți ultima versiune de VMWare Workstation instalată, pe care o puteți descărca gratis de pe portalul https://vmware.pub.ro/ (vă autentificați cu contul unic al facultății).
Recomandat ar fi să faceți uz de funcționalitatea de VM snapshotting pe care o pune VMWare la dispoziție, astfel încât să puteți pleca de la imaginea de bază (pe care să o țineți nemodificată!) și să aveți mai multe instanțe separate (sub forma unor snapshot-uri) pe care le puteți comuta manual după caz. De exemplu, doriți să experimentați ceva cu Yocto: faceți un snapshot nou, vă jucați liberi în acea instanță apoi, dacă experimentul a eșuat, puteți reveni mereu la starea anterioară a snapshot-ului (cu fișierele de atunci).
Pentru un ghid de folosire a snapshot-urilor în VMWare, vedeți pagina aceasta. TLDR: Ctrl+M în VMWare pentru Snapshot Manager ;)
~8 GB
(puteți oricând combina snapshoturile reușite pentru a reduce spațiul).
Considerăm starea inițială a fișierelor din VM cu următoarea structură (doar cele de interes pentru laboratorul de față, altele pot fi prezente, e.g. din toolbox-ul temei 2, însă le vom ignora momentan):
/home/student/yocto: |-- build # (generat de kas + Yocto bitbake) | |-- cache | |-- conf | |-- conf # generate automat din kas.yml | | |-- bblayers.conf | | |-- local.conf | | `-- templateconf.cfg | `-- tmp |-- layers # (descărcate prin kas) | |-- meta-raspberrypi | `-- poky |-- kas.yml
Per parcursul acestui document, vom considera strict acest director de bază (neavând treabă în alte locuri).
În VM a fost deja invocat utilitarul kas
(vedeți și documentația oficială), care a avut următoarele efecte:
repos
a fișierului kas.yml
.build/conf/{bblayers.conf,local.conf,templateconf.cfg}
.bitbake build
inițial la imaginea de bază a distribuției Poky (core-image-base
), lucru ce poate dura chiar și câteva ore (pentru compilarea atât a toolchain-ului, cât și ale kernelului și ale tuturor pachetelor instalate în distribuția de bază); din fericire, o dată compilate aceste pachete, vor rămâne în cache și vor fi refolosite la toate build-urile ulterioare (decât dacă schimbați versiunea layerelor descărcate sau doriți să upgradați pachetele – we don't do that here!).
Deși acest mic tool ne-a automatizat din munca de setup a unui proiect nou Yocto, acesta vine cu inconvenientul că, dacă dorim să modificăm unul dintre fișierele generate (din build/conf/
), va trebui s-o facem prin intermediul fișierului de configurare kas.yml
(more on this later).
De menționat ar fi faptul că imaginea de bază conține strict pachetele prevăzute de către fișierele implicite de configurare ale Poky și atât. Nu este nici măcar folosibilă în starea aceasta inițială (neavând parolă la contul de root
).
Pentru a schimba aceste lucruri avem nevoie să ne construim propriul layer, ceea ce vom și face în secțiunea următoare.
Observați faptul că nu puteți rula bitbake
(dă command not found
). Acesta un executabil care nu se află de obicei în $PATH
-ul normal al sistemelor Linux, putând fi accesat doar după inițializarea mediului Yocto.
Reamintim că utilitarul kas
ne-a descărcat codul sursă al poky
în calea layers/poky/
.
Tot aici găsim și scriptul oe-init-build-env
responsabil de inițializarea.
Astfel, dacă încărcăm acest script în shell-ul curent:
student@vm:~/yocto$ source layers/poky/oe-init-build-env ### Shell environment set up for builds. ### You can now run 'bitbake <target>' ...
… utilitarele Yocto devin accesibile (însă doar în shell-ul actual, dacă utilizați mai multe terminale sau îl re-deschideți pe acesta, va trebui să repetați comanda în fiecare). Atenție! Comanda ne schimbă directorul nostru actual în build/
, dăm cd ..
pentru a reveni în rădăcina proiectului nostru.
Un layer este, practic, o colecție de sine stătătoare de scripturi, metadate și alte resurse construcție a unui sistem Linux. O distribuție Yocto este, practic, compusă din unul sau mai multe straturi așezate unul peste altul (unde Poky, desigur, stă la baza acestora) ce aplică operații de build într-o anumită ordine pentru a obține rezultatul dorit.
Pentru a crea un layer nou, putem folosi comanda bitbake-layers
:
student@vm:~/yocto/build$ cd ../ # navigăm în afara directorului build/ student@vm:~/yocto$ bitbake-layers create-layer meta-tutorial-si NOTE: Starting bitbake server... Add your new layer with 'bitbake-layers add-layer meta-tutorial-si'
build/
pentru a stoca codul layerelor, deoarece va fi ignorat de scriptul care împachetează arhiva cu sursele. La fel și cu directorul layers/
(aici sunt stocate layerele third-party ce au fost / vor fi descărcate automat prin kas).
Această comandă va genera scheletul pentru noul nostru layer într-un director cu numele furnizat ca parametru. Structura layer-ului nou creat va fi următoarea:
meta-tutorial-si/ |-- conf | `-- layer.conf # variabile de configurație utilizate de layer |-- COPYING.MIT |-- README `-- recipes-example # ce drăguț, avem și exemplu de o rețetă ;) `-- example `-- example_0.1.bb
Un ghid oficial pentru creare layere puteți găsi aici (să îl puteți consulta ulterior).
Pentru a fi util, un layer conține una sau mai multe rețete.
O rețetă este un fișier .bb
cu sintaxă specială Bitbake ce descriu pașii de urmat de către sistemul de build pentru a genera pachete sau altera configurația unei distribuții. Apoi mai avem fișiere .bbappend
care ne permit să re-configurăm rețetele din alte layere fără a le rescrie.
Ghid oficial aici.
Rețetele se află, de obicei, într-un director cu prefixul recipes- în denumirea lor, însă comportamentul real este definit în fișierul layer.conf:
# We have recipes-* directories, add to BBFILES BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend"
A se observa regula de globbing: se caută recursiv în orice director ce urmează această convenție, precum și sufixul de versionare (obligatoriu). Desigur, nu avem de ce să o schimbăm, așa că trecem mai departe ;)
O rețetă are o sintaxă relativ similară cu o combinație de Makefile și script de shell (e.g., bash). Putem vedea asta prin exemplul generat de create-layer:
SUMMARY = "bitbake-layers recipe" DESCRIPTION = "Recipe created by bitbake-layers" ... python do_display_banner() { # ... bb.plain("* Example recipe created by bitbake-layers *"); } addtask display_banner before do_build
A se observa că este posibilă definirea de funcții în alte limbaje integrate (SHell sau chiar Python) ce se vor executa într-un anumit pas al procesului de build (vedeți diagrama din documentația oficială pentru o idee).
Pentru a folosi layer-ul nou creat, este necesar ca acesta să fie introdus în fișierul (global) de configurație al Yocto referitor la acestea: bblayers.conf
. Ne reamintim, însă, faptul că tool-ul nostru helper de build va suprascrie orice modificări vom face.
Defapt, ne generează lista de straturi pe baza unui fișier de configurație kas.yml
, deci vom adăuga layer-ul nostru acolo:
# ... repos: # adăugăm, pur și simplu, o cheie nouă (opțional, putem să modificăm calea către layer) meta-tutorial-si: path: './meta-tutorial-si' # atenție la identare! contează... yaml s-a inspirat din python :( # ... restul de layere au fost descărcate prin URL de git... meta-raspberrypi: url: git://git.yoctoproject.org/meta-raspberrypi # ...
Rulăm apoi kas build kas.yml
. Observăm că, în build/conf/bblayers.conf
ne-a apărut layer-ul:
BBLAYERS ?= " \ /home/student/yocto/layers/meta-raspberrypi \ ... /home/student/yocto/meta-tutorial-si" # <-- here it is
Doar că trebuia să ne printeze mesajul acela din rețeta Example la build, ceea ce nu se întâmplă… de ce oare? (heheee) Să facem altfel:
# REMINDER: să aveți oe-init-build-env activat! student@vm:~/yocto$ bitbake example # să aveți oe-init-build-env activat! Loading cache: 100% |##########| Time: 0:00:00 ... NOTE: Executing Tasks *********************************************** * * * Example recipe created by bitbake-layers * * * ***********************************************
Now we're getting somewhere! Mai rămâne, deci, să adăugăm această rețetă undeva să fie executată la build-ul imaginii principale (reminder: denumită core-image-base
:
student@vm:~/yocto$ cd meta-tutorial-si/ student@vm:~/yocto/meta-tutorial-si$ mkdir -p recipes-core/images/ student@vm:~/yocto/meta-tutorial-si$ vim recipes-core/images/core-image-base.bbappend # iar în fișier vom scrie: (suntem în vim, deci apăsăm un 'i' înainte pentru insert mode) IMAGE_INSTALL += " example" # :wq ca să nu rămânem blocați :P student@vm:~/yocto$ cd ../ student@vm:~/yocto$ kas build kas.yml
… et voila!
Cum funcționează: am extins rețeta imaginii de bază printr-un fișier .bbappend
(pentru asta au fost concepute). Codul nostru va fi procesat după fișierul .bb
original, astfel putând modifica variabila IMAGE_INSTALL pentru a ne fi incluse pachete custom de către task-urile rețetei generatoare de imagine.
Also check these goodies (chestii gata făcute incluzabile printr-o linie de cod).
Ca alternativă, puteam construi o nouă imagine (e.g., tutorial-si-image
) care să pornească de la prima. Doar că trebuia să build-uim noua noastră imagine (bitbake tutorial-si-image
în loc de core-image-base
).
conf/local.conf
și adăugarea unei linii:
IMAGE_INSTALL_append = " example"
… dar este, desigur, anti-practică! Vrem să avem toată funcționalitatea încapsulată în layer bine definit, păi ce facem noi aici… :P
Înainte de a continua, să aveți un layer creat (e.g., meta-tutorial-si
de la pasul anteror sau, desigur, puteți să folosiți ce altă denumire doriți) pe care îl vom extinde.
Pentru a avea o distribuție Linux utilizabilă va trebui, desigur, să avem creat un utilizator ;) Apoi vom demonstra adăugarea de resurse (fișiere) în imaginea de bază.
Se dă tutorialul acesta. Cum se procedează mai departe?
“In your image recipe:”. Deci vim meta-tutorial-si/recipes-core/images/core-image-base.bbappend
:
# vechiul conținut: IMAGE_INSTALL += "example" # mai adăugăm: inherit extrausers # pentru a schimba parola la root: EXTRA_USERS_PARAMS += "usermod -P student root;" # pentru a adăuga un utilizator nou: EXTRA_USERS_PARAMS += "useradd -P parolalastudent student;" # atenție: trebuie să muncim în plus pentru a-i da drept de sudo utilizatorului, deci recomand root-ul
Apoi construim imaginea din nou: kas build kas.yml
.
Și rulăm:
export LANG=en_US.UTF-8 # dacă runqemu se plânge că nu-l avem setat # nu uitați să faceți source la oe-init-build-env dacă nu aveți utiltarele în PATH runqemu qemuarm nographic # pentru a ieși, trebuie să apăsăm combinația Ctrl+A, c # va apărea un terminal qemu unde puteți scrie "quit"
launch.sh
, va trebui mai întâi să rulați sudo create-bridge.sh
din consola VMWare (conexiunea la rețea va pica temporar). Apoi, rulați make bin_archive
pentru a copia ultima imagine în cache-ul de arhivă (pentru distribuirea binarelor), deoarece scriptul folosește ultima imaginea salvată astfel!
Următoarea întrebare care se pune este: cum vedem conținutul unei imagini generate? Din fericire, suntem pe un sistem Linux, așadar putem folosi mount pentru a monta local partiția ext3/4 generată:
student@vm:~/yocto$ sudo mount -o loop build/tmp/deploy/images/qemuarm/core-image-base-qemuarm.ext4 /mnt student@vm:~/yocto$ ls -l /mnt student@vm:~/yocto$ cat /etc/passwd | grep student student:x:1000:1000::/home/student:/bin/sh # YEAHHH! # NU UITAȚI: să de-montați partiția la final!!! # (altfel s-ar putea să se corupă imaginea de la dublă utilizare) student@vm:~/yocto$ sudo umount /mnt
TODO
TODO