Laboratorul 08. Yocto extended content

Asa cum am mentionat si laboratoarelor trecute si vom reitera si cu aceasta ocazie Yocto este o colecție de utilitare, metadate și șabloane ce permit construirea/compilarea distribuțiilor de Linux pentru platforme embedded ce oferă posibilitatea de a crea distribuții personalizate pornind de la 0 sau de la imagini scheletice. In cadrul acestui ultim laborator vom continua si vom adauga context si exemple informatiei dobandite pana acum. Printre conceptele pe care le vom acoperi putem include: notiunea de pachet (package) si grup de pachete (packagegroups), care desi diferite au un scop diferit, sunt extrem de importante ca si concepte, vom detalia despre cum se poate lucra cu ele, care este rolul fiecareia dintre notiuni si cum putem lucra cu ele si de asemenea vom adauga aici si notiundea de module de kernel si modul in care putem integra aceasta notiune intr-o infrastructura precum Yocto Project.

Pana acum am introdus conceptele esentiale de task, reteta (.bb), imagine. Am explicat care este rolul build engine-ului Bitbake si a diferitelor fisiere de configuratie specifice: fie ca discutam de clase (.bbclass), fisierul layer.conf responsabil cu descrierea structurii layer-ului nostru, local.conf unde regasim configuratia specifica build-ului, bblayers.conf ce descrie layerele folosite pentru procesul de build, configuratia specifica masinii selectate, in cazul nostru qemuarm.conf sau cea a politicilor de distributie folosite cunoscuta ca si poky.conf.

In cele ce urmeaza vom extinde suportul cunostiintelor dobandite cu notiuni despre pachete, grupuri de pachete, notiunea de server web si cum se poate adauga suportul pentru un asfel de utilitar iar nu in ultimul rand vom discuta despre cum putem adauga suport pentru module de kernel. Acestea pot fi buildate impreuna cu restul retetelor iar pentru procesul de dezvoltare se poate folosi SDK-ul pus la dispozitie de catre Yocto. Asa cum am mentionat deja SDK-ul contine următoarele:

  • Cross-Development Toolchain: acest lanț de instrumente conține un compilator, un debugger și diverse instrumente asociate.
  • Biblioteci, anteturi și simboluri: bibliotecile, anteturile și simbolurile sunt specifice imaginii (adică se potrivesc cu imaginea cu care a fost construit SDK-ul).
  • Script de configurare a mediului: Acest fișier *.sh, odată preluat, configurează mediul de dezvoltare prin definirea variabilelor și pregătirea pentru utilizarea SDK.

Notiunea de meta-toolchain este un subset al SDK-ului si include Cross-Development Toolchain respectiv Scriptul de configurare a mediului si este o varianta light-weight pentru compilarea modulelor de kernel deoarece acestea nu depind de utilizare bibliotecilor asociate aplicatiilor disponibile in imaginea sistemului de operare buildat cu Bitbake.

Sursele codului

Pentru ca sistemul de compilare Bitbake să creeze o imagine sau orice pachet, trebuie să poată accesa fișierele sursă. Asa cum a fost descris in fluxul de lucru fișierele sursă sunt fie descarcate dintr-un „Upstream Project Releases”, „Local Projects” și/sau „SCMs (opțional)”.

Metoda prin care fișierele sursă sunt organizate în cele din urmă este o funcție a proiectului. De exemplu, pentru release-uri, proiectele tind să utilizeze tarball-uri sau alte fișiere arhivate care pot surprinde starea unei ediții, garantând că aceasta este reprezentată static. Pe de altă parte, pentru un proiect care este mai dinamic sau experimental în natură, un proiect poate păstra fișierele sursă într-o locatie controlata de un manager de control sursă (SCM), cum ar fi Git. Extragerea sursei dintr-o astfel de locatie vă permite să controlați revizia din care doriți să construiți software. O combinație a celor două este, de asemenea, posibilă.

BitBake folosește variabila SRC_URI pentru a indica fișierele sursă, indiferent de locația acestora. Fiecare rețetă trebuie să aibă o variabilă SRC_URI care să indice sursa.

O altă zonă care joacă un rol semnificativ în ceea ce privește provenienta fișierele sursă este indicată de variabila DL_DIR. Această zonă este un cache care poate stoca sursa descărcată anterior. De asemenea, puteți instrui sistemul de compilare Bitbake să creeze tarball-uri din depozitele Git, care nu este comportamentul implicit, și să le stocați în DL_DIR utilizând variabila BB_GENERATE_MIRROR_TARBALLS.

Utilizarea judicioasă a unui director DL_DIR poate salva sistemul de compilare o călătorie pe Internet atunci când caută fișiere. O metodă bună de utilizare a unui director de descărcare este ca DL_DIR să indice o zonă din afara directorului dvs. de compilare. Acest lucru vă permite să ștergeți în siguranță directorul de compilare, dacă este necesar, fără teama de a elimina orice fișier sursă descărcat.

Proiectele locale sunt fragmente personalizate de software pe care utilizatorul le oferă. Acestea se află undeva la nivel local unui proiect - poate un director în interiorul layer-ului personal.

Metoda standard prin care să includeți un proiect local este să utilizați clasa externalsrc pentru a include acel proiect local. Folosiți fie local.conf, fie fișierul .bbappend al unei rețete pentru a suprascrie sau pentru a reconfigura rețeta să indice directorul local de pe disc pentru a extrage codul sursă.

Un alt loc din care sistemul de compilare poate obține fișiere sursă este Fetchers care utilizează diverși Manageri de Control cod Sursă (SCM), cum ar fi Git sau Subversion. În astfel de cazuri, un repository este clonat sau verificat. Sarcina do_fetch din BitBake utilizează variabila SRC_URI și prefixul argumentului pentru a determina modulul de preluare corect. Când preia un repository, BitBake folosește variabila SRCREV pentru a determina revizia specifică din care să construiască.

Există două tipuri de oglinzi: pre-oglinzi și oglinzi obișnuite. Variabilele PREMIRRORS și, respectiv, MIRRORS indică locatiile acestea. BitBake verifică pre-oglinzile înainte de a căuta în amonte orice fișier sursă. Pre-oglinzile sunt adecvate atunci când aveți un director partajat care nu este un director definit de variabila DL_DIR. O oglindă prealabilă indică de obicei un director partajat care este local pentru organizația dvs.

Oglinzile obișnuite pot fi orice site de pe Internet care este folosit ca locație alternativă pentru codul sursă în cazul în care site-ul principal nu funcționează dintr-un motiv sau altul.

Fluxul de pachete

Când sistemul de compilare Bitbake generează o imagine sau un SDK, primește pachetele dintr-o zonă de alimentare a pachetelor situată în directorul de build, in general intitulat build. Această secțiune explica puțin mai îndeaproape fluxul de pachete utilizat de sistemul de build. Iată o privire mai detaliată asupra zonei:

Fluxurile de pachete sunt un pas intermediar în procesul de construire a unei imagini. Sistemul de compilare Bitbake oferă clase pentru a genera diferite tipuri de pachete și astfel puteti specifica ce clase să activați prin intermediul variabilei PACKAGE_CLASSES. Înainte de a plasa pachetele în fluxuri de pachete, procesul de compilare le validează cu verificări generate de asigurarea calității rezultatelor prin clasa insane.bbclass.

Zona de alimentare a pachetelor se află în directorul de build, locul folosit pentru a stoca temporar pachetele este determinat de o combinație de variabile și de managerul de pachete specific utilizat. Consultați imaginea de mai sus și observati informațiile din dreapta imaginii. În special, următoarele definitii sunt relevante pentru păstrarea fișierele pachetului:

  • DEPLOY_DIR: Definit ca tmp/deploy în directorul de build.
  • DEPLOY_DIR_*: În funcție de managerul de pachete utilizat, subdosarul tip pachet. Având în vedere ambalarea RPM, IPK sau DEB și crearea tarballului, sunt utilizate variabilele DEPLOY_DIR_RPM, DEPLOY_DIR_IPK, DEPLOY_DIR_DEB respectiv, DEPLOY_DIR_TAR.
  • PACKAGE_ARCH: Definește subfolderele specifice arhitecturii. De exemplu, pachetele ar putea fi disponibile pentru arhitecturile i586 sau qemux86.

BitBake folosește sarcinile do_package_write_* pentru a genera pachete și a le plasa în zona de depozitare a pachetelor (de exemplu, do_package_write_ipk pentru pachetele IPK). De exemplu, luați în considerare un scenariu în care este utilizat un manager de ambalare IPK și există suport pentru arhitectura de pachete atât pentru i586, cât și pentru qemux86. Pachetele pentru arhitectura i586 sunt plasate în build/tmp/deploy/ipk/i586, în timp ce pachetele pentru arhitectura qemux86 sunt plasate în build/tmp/deploy/ipk/qemux86.

Consultați secțiunile „do_package_write_*” asociata din manualul de referință al proiectului Yocto pentru informații suplimentare.

Grup de pachete

Pentru imagini personalizate complexe, cea mai bună abordare pentru personalizarea unei imagini este crearea unei rețete de grup de pachete personalizate care este utilizată pentru a construi imaginea sau imaginile. Un bun exemplu de rețetă de grup de pachete este meta/recipes-core/packagegroups/packagegroup-base.bb.

Dacă examinați acea rețetă, vedeți că variabila PACKAGES listează pachetele de grup de pachete de produs. Declarația inherit packagegroup setează valori implicite adecvate și adaugă automat pachetele complementare -dev, -dbg și -ptest pentru fiecare pachet specificat în instrucțiunea PACKAGES.

Instructiunea inherit packages ar trebui să fie situate în partea de sus a rețetei, cu siguranță înainte de instrucțiunea PACKAGES.

Pentru fiecare pachet pe care îl specificați în PACKAGES, puteți utiliza intrările RDEPENDS și RRECOMMENDS pentru a furniza o listă de pachete pe care ar trebui să le conțină pachetul de sarcini părinte. Puteți vedea exemple ale acestora mai jos în rețeta packagegroup-base.bb.

Iată un exemplu scurt, care arată configuratia de bază pentru acest grup de pachete:

DESCRIPTION = „Grupul meu personalizat de pachete”

inherit packagegroup

PACKAGES = "\
    ${PN}-apps \
    ${PN}-tools \
    "

RDEPENDS:${PN}-apps = "\
    dropbear \
    portmap \
    psplash"

RDEPENDS:${PN}-tools = "\
    oprofile \
    oprofileui-server \
    lttng-tools"

RRECOMMENDS:${PN}-tools = "\
    kernel-module-oprofile"

În exemplul anterior, două pachete de grup de pachete sunt create cu dependențele lor și dependențele recomandate de pachete dupa cum urmeaza: packagegroup-custom-apps și packagegroup-custom-tools. Pentru a construi o imagine folosind aceste pachete de grup de pachete, trebuie să adăugați packagegroup-custom-apps și/sau packagegroup-custom-tools la IMAGE_INSTALL.

Module de kernel

Deși este întotdeauna de preferat să lucrați cu surse integrate în sursele kernel-ului Linux, dacă aveți nevoie de un modul kernel extern, rețeta hello-mod.bb este disponibilă ca șablon din care vă puteți crea propriul modul de kernel Linux disponibil separat de reteta de kernel deja existenta in layer-ul de BSP mostenit.

Această rețetă șablon se află în repo-ul git al lui Poky din proiectului Yocto: meta-skeleton/recipes-kernel/hello-mod/hello-mod_0.1.bb

Pentru a începe, copiați această rețetă în layer-ul dvs. și dați-i un nume semnificativ (de exemplu, mymodule_1.0.bb). În același director, creați un director nou numit files în care puteți stoca orice fișiere sursă, patch-uri sau alte fișiere necesare pentru construirea modulului care nu vin cu sursele. În cele din urmă, actualizați rețeta după cum este necesar pentru modul. De obicei, va trebui să setați următoarele variabile: DESCRIPTION, LICENSE*, SRC_URI, PV etc.

În funcție de sistemul de build utilizat de sursele modulelor, este posibil să fie nevoie să faceți unele ajustări. De exemplu, un modul tipic Makefile seamănă mult cu cel furnizat cu șablonul hello-mod:

obj-m := hello.o

SRC := $(shell pwd)

all:
     $(MAKE) -C $(KERNEL_SRC) M=$(SRC)

modules_install:
     $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
...

Punctul important de remarcat aici este variabila KERNEL_SRC. Clasa module setează această variabilă și variabila KERNEL_PATH la ${STAGING_KERNEL_DIR} cu informațiile necesare de construire a kernel-ului Linux pentru a construi module. Dacă modulul Makefile folosește o variabilă diferită, poate doriți să înlocuiți pasul do_compile sau să creați un patch pentru Makefile pentru a lucra cu variabilele KERNEL_SRC sau KERNEL_PATH mai tipice.

După ce ați pregătit rețeta, probabil că veți dori să includeți modulul în imagini. Pentru a face acest lucru, consultați documentația pentru următoarele variabile din manualul de referință al proiectului Yocto și setați una dintre ele în mod corespunzător pentru fișierul de configurare a mașinii dvs.:

  • MACHINE_ESSENTIAL_EXTRA_RDEPENDS
  • MACHINE_ESSENTIAL_EXTRA_RRECOMMENDS
  • MACHINE_EXTRA_RDEPENDS
  • MACHINE_EXTRA_RRECOMMENDS

Modulele nu sunt adesea necesare pentru pornire și pot fi excluse din anumite configurații de build. Următoarea optiune oferă cea mai mare flexibilitate:

MACHINE_EXTRA_RRECOMMENDS += „kernel-module-mymodule”

Valoarea este derivată prin adăugarea numelui de fișier al modulului fără extensia .ko la șirul „kernel-module-“.

Deoarece variabila este RRECOMMENDS și nu o variabilă RDEPENDS, compilarea nu va eșua dacă acest modul nu este disponibil pentru a fi inclus în imagine.

Exercitii

  • Adaugati suport pentru serverul web python-flask. Pentru a realiza acest lucru, va trebui sa includem un nou layer:
cd yocto/layers
git clone https://github.com/openembedded/meta-openembedded.git
cd meta-openembedded
git checkout kirkstone

vim yocto/kas.yml
# Adaugati layer-ele meta-oe si meta-python
  • Folosind examplul de mai sus si referinta merandom creati o reteta cu un modul kernel care scrie un caracter random in /dev/merandom
    • Incercati initial sa folositi SDK-ul pentru a compila si a fixa erorile din codul disponibil.
    • Compilati alternativ cu SDK-ul imaginii respectiv varianta de meta-toolchain.
  • (Bonus) Creati un packagegroup pentru aceste pachete create.
si/lab/2022/laboratoare/08.txt · Last modified: 2023/09/26 14:15 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0