Openembedded: la distribuzione «ristretta» per Linux

logoQuando le risorse di un sistema sono limitate non è possibile usare una distribuzione classica (Ubuntu, Debian e via discorrendo) ma occorre usare una distribuzione che abbia un footprint (cioè una occupazione di memoria di massa) molto ridotto.

Una distribuzione abbastanza versatile e diffusa è OpenEmbedded che è la distribuzione alla base di altre distribuzioni più note come, ad esempio, OpenMoko e Angstrom.

OpenEmbedded, al momento, supporta diverse architetture (x86, arm, powerpc, mips, ecc.) e CPU ed è in grado di generare, per queste macchine, una distribuzione completa (e pronta da caricare sul sistema) con il relativo SDK! Non c’è che dire: servizio completo.

Installazione

Installare OpenEmbedded è relativamente facile poiché si fa tutto con GIT. Basta clonare il repository con il comando:

$ mkdir OE && cd OE
$ git clone git://git.openembedded.org/openembedded
Initialized empty Git repository in /home/giometti/OE/openembedded/.git/
remote: Counting objects: 418106, done.
remote: Compressing objects: 100% (118843/118843), done.
Receiving objects:   0% (124/418106), 36.00 KiB | 3 KiB/s

Una volta finito (e ci vorrà un bel po’…) dobbiamo installare il motore di OpenEmbedded: BitBake.

BitBbake è un tool per la gestione e la compilazione di pacchetti software il quale tiene conto anche delle dipendenze che intercorrono tra di essi, ad esempio, se il pacchetto A dipende dal pacchetto B, e se si chiede a BitBake di compilare A, allora egli provvederà a compilare prima B e poi A. Non solo, BitBake si occupa anche di scaricare i sorgenti ed utilizzare un cross compilatore nel caso che il sistema su cui si compila sia di architettura diversa da quella del sistema embedded.

Sul mio sistema basato su Ubuntu il pacchetto di BitBake che viene fornito è obsoleto e quindi devo installarmelo scaricando i sorgenti direttamente dal sito ufficiale:

$ wget http://download.berlios.de/bitbake/bitbake-1.10.2.tar.gz
$ tar xvfz bitbake-1.10.2.tar.gz
$ ln -s bitbake-1.10.2 bitbake

In fine occorre installare un po’ di pacchetti di supporto; sulla mia Ubuntu ho usato:

$ sudo aptitude install python-psyco texinfo chrpath diffstat texi2html cvs subversion

Una nota finale, verificate che la shell di default sia bash e non dash, cioè:

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh

Generazione immagine

A questo punto siamo pronti, ora non ci resta che decidere quale sistema utilizzare per un test di base.

Io, in questo articolo, utilizzerò un sistema basato su CPU arm, nello specifico di un sistema Cirrus EP9307A.

Per dire ad OpenEmbedded di creare una immagine del rootfs per il mio sistema basta che crei alcuni file di configurazione:

$ install -d build/conf
$ cp openembedded/conf/local.conf.sample build/conf/local.conf

e quindi apportare le seguenti modifiche:

-DL_DIR = “${HOME}/sources”
+DL_DIR = “${OEBASE}/sources”
-BBFILES := “${@bb.fatal(‘Edit your conf/local.conf: BBFILES’)}”

+BBFILES := “${OEBASE}/openembedded/recipes/*/*.bb
+MACHINE = “ep93xx”
+DISTRO = “minimal”
-REMOVE_THIS_LINE:=”${@bb.fatal(‘Read the comments in your conf/local.conf’)}”

Dove con la variabile OEBASE ho specificato la directory di lavoro /home/giometti/OE usata prima in fase di download dei sorgenti.

La spiegazione delle impostazioni è abbastanza banale, con DL_DIR specifico dove salvare i file dei sorgenti dei pacchetti che verranno di volta in volta scaricati per essere compilati, con BBFILES dico a BitBake dove sono le ricette di OpenEmbedded, mentre con MACHINE e DISTRO specifico proprio la configurazione del mio sistema embedded e il tipo di distribuzione che voglio metterci su (esistono diverse distribuzioni generabili e minimal è quella minimale con solo la console seriale più un server SSH).

In fine, cancellando la linea che definisce la variabile REMOVE_THIS_LINE dico a BitBake che il file di configurazione è usabile.

A questo punto non mi resta che generare l’immagine, ma prima di lanciare BitBake devo configurare alcune variabili d’ambiente:

export OEBASE=/home/giometti/OE
export PATH=$OEBASE/bitbake/bin:$PATH
export BBPATH=$OEBASE/build:$OEBASE/openembedded
export BB_ENV_EXTRAWHITE=”OEBASE”

quindi faccio partire la compilazione con il comando:

$ bitbake minimal-image

se abbiamo configurato tutto bene dovremmo vedere qualcosa tipo:

$ bitbake minimal-image
NOTE: Handling BitBake files: (7289/7289) [100 %]
Parsing of 7289 .bb files complete (0 cached, 7289 parsed). 7654 targets, 343 skipped, 0 masked, 0 errors.

Build Configuration:
BB_VERSION        = “1.10.2”
METADATA_BRANCH   = “master”
METADATA_REVISION = “e152587”
TARGET_ARCH       = “arm”
TARGET_OS         = “linux-gnueabi”
MACHINE           = “ep93xx”
DISTRO            = “minimal”
DISTRO_VERSION    = “dev-snapshot-20110207”
TARGET_FPU        = “soft”

NOTE: Resolving any missing task queue dependencies
NOTE: Preparing runqueue
NOTE: Executing runqueue

Ora mettevi pure comodi o, meglio, prendetevi una bella pausa perché ci vuole parecchio tempo prima che la creazione del filesystem finisca. Ovviamente questo dipende dalla macchina che utilizzate, ma giusto per darvi un’idea sul mio povero dualcore (che però ha un disco via NFS) ci son volute più di 8 ore… è chiaro che queste cose si fanno su una macchina con multe CPU, tanta RAM e un disco veloce, ma è anche vero che una volta creata l’immagine di base la si mette da parte e non la si ricrea più (a meno di modifiche sostanziali).

Il test

Una volta finito, nella directory tmp troviamo i risultati del nostro lavoro:

$ ls tmp/
abi_version    deploy/      pkgdata/  rootfs/         stamps/    usr/
cache/         distro_pr    pstage/   saved_tmpdir    sysroots/  work/

Non sto qui a spiegare a cosa servono tutte le directory (rimando il lettore curioso al manuale di OpenEmbedded), quello che però ci interessa è la directory tmp/deploy:

$ ls tmp/deploy/
images/  ipk/  sources/

In tale directory infatti ci sta l’immagine del rootfs del sistema (directory images) e i file ipkg (directory ipkg) di ogni pacchetto software installato nella rootfs creata. Questi ultimi sono molto importanti perché sono già in una forma esportabile via HTTP in modo tale da costituire un repository di base del sistema dal quale poter scaricare nuovo software e/o aggiornamenti; infatti nella directory tmp/deploy/ipk/ si ha:

$ ls tmp/deploy/ipk/
Packages           Packages.gz        all/     ep93xx/
Packages.filelist  Packages.stamps    armv4t/

Se configuriamo un server HTPP che punta a questa directory, basterà allora configurare il tool opkg nel sistema embedded in modo tale che punti al nostro server e i pacchetti saranno aggiungibili via rete nè più nè meno di come si fa per una distribuzione classica!.

Ma vediamo una prova di funzionamento. Prima di tutto prendo l’immagine in formato JFFS2 e la metto in flash (qui la procedura dipende dal sistema utilizzato e quindi non la riporterò), poi accendo il sistema e, dopo i primi messaggi del kernel, via console seriale vedo:

VFS: Mounted root (jffs2 filesystem).
Freeing init memory: 112K
INIT: version 2.86 booting
Please wait: booting…
Error opening /dev/fb0: No such device or address
Starting udev
error initializing netlink socket
Root filesystem already rw, not remounting
Caching udev devnodes
Populating dev cache
root: mount: mount point /dev/shm does not exist
Configuring network interfaces… ifup: can’t open ‘/var/run/ifstate’: No such file or directory
done.
Setting up IP spoofing protection: rp_filter.
Tue Feb  8 09:05:00 UTC 2011

touch: /var/log/wtmp: No such file or directory
INIT: Entering runlevel: 5
mkdir: can’t create directory ‘/var/lock/’: No such file or directory
chown: /var/lock/subsys: No such file or directory
chmod: /var/lock/subsys: No such file or directory
chown: /var/log/wtmp: No such file or directory
chmod: /var/log/wtmp: No such file or directory
Creating Dropbear SSH server RSA host key.
Will output 1024 bit rsa secret key to ‘/etc/dropbear/dropbear_rsa_host_key’
Generating key, this may take a while…
Public key portion is:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgwCDP7S/6c6+DSdQcSP8/ni+gUQqL8Setj1PkrtYS2AENEuA5H0DrQsNtbNufCgcKB/e2R82WaXPHmC+BBbF+53aMem95ygktEdR9/61LoFJv/oLgZ55Uirp4w1ycAv4E5NlpKz2mUCSstczqcfFCQfoPjOdiwzBZIExKEVgPOgMLQmx root@ep93xx
Fingerprint: md5 21:1a:06:17:a1:18:77:0c:1d:8f:67:f5:4a:c6:be:64
Starting Dropbear SSH server: dropbear.
Starting syslogd/klogd: done

OpenEmbedded Linux ep93xx ttyAM0

minimal dev-snapshot-20110207 ep93xx ttyAM0

ep93xx login:

Aggiungere un pacchetto

Creare una distribuzione di base, ovviamente, è cosa buona e giusta, ma fare questo senza poter aggiungere nuovi pacchetti è diabolico! Vediamo allora come si può aggiungere un pacchetto al nostro sistema nuovo di pacca.

Ci sono due strade:

  1. appoggiarsi ad una distro già consolidata e che esporta i suoi pacchetti in rete e quindi scaricarli da lì (ad esempio Angstrom), oppure
  2. ricompilarsi di volta in volta i pacchetti che ci servono e quindi installarli nel sistema via HTTP o a mano.

Vediamo un esempio di quest’ultima ipotesi utilizzando un server HTTP (precedentemente configurato).

Supponiamo ad esempio di voler aggiungere il supporto per il linguaggio PHP al sistema, prima di tutto dobbiamo compilarci il pacchetto php con BitBake:

$ bitbake php

Una volta finito, nella solita directory tmp/deploy dovremmo trovare i file ipkg relativi a PHP:

$ ls tmp/deploy/ipk/armv4t/php*
tmp/deploy/ipk/armv4t/php-cgi_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php-cli_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php-dbg_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php-dev_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php-doc_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php-pear_5.2.13-r7.4_armv4t.ipk
tmp/deploy/ipk/armv4t/php_5.2.13-r7.4_armv4t.ipk

Quindi rigenero i file di indice per il repository su HTTP:

$ bitbake package-index

Ora, per installare il supporto per PHP basta andare sul sistema embedded e dare il comando:

root@ep93xx:~# opkg update
Downloading http://gundam/remote-feed//all/Packages.gz.
Inflating http://gundam/remote-feed//all/Packages.gz.
Updated list of available packages in /var/lib/opkg/remote-all.
Downloading http://gundam/remote-feed//armv4/Packages.gz.
wget: server returned error: HTTP/1.1 404 Not Found
Downloading http://gundam/remote-feed//armv4t/Packages.gz.
Inflating http://gundam/remote-feed//armv4t/Packages.gz.
Updated list of available packages in /var/lib/opkg/remote-armv4t.
Downloading http://gundam/remote-feed//ep93xx/Packages.gz.
Inflating http://gundam/remote-feed//ep93xx/Packages.gz.
Updated list of available packages in /var/lib/opkg/remote-ep93xx.
Collected errors:
* opkg_download: Failed to download http://gundam/remote-feed//armv4/Packages.gz, wget returned 1.

Per aggoirnare il sistema, e quindi, per installare PHP uso:

root@ep93xx:~# opkg install php
Installing php (5.2.13-r7.4) to root…
Downloading http://gundam/remote-feed//armv4t/php_5.2.13-r7.4_armv4t.ipk.
Configuring php.

Strabiliante!

Su Rodolfo Giometti

Ingegnere informatico libero professionista ed esperto GNU/Linux offre supporto per: - device drivers; - sistemi embedded; - sviluppo applicazioni industriali per controllo automatico e monitoraggio remoto; - corsi di formazione dedicati. Manutentore del progetto LinuxPPS (il sottosistema Pulse Per Second di Linux) contribuisce attivamente allo sviluppo del kernel Linux con diverse patch riguardanti varie applicazioni del kernel e dispositivi (switch, fisici di rete, RTC, USB, I2C, network, ecc.). Nei 15+ anni di esperienza su Linux ha lavorato con le piattaforme x86, ARM, MIPS & PowerPC.

Lascia un commento

Utilizzando il sito, accetti l'utilizzo dei cookie da parte nostra. maggiori informazioni

Questo sito utilizza i cookie per fonire la migliore esperienza di navigazione possibile. Continuando a utilizzare questo sito senza modificare le impostazioni dei cookie o clicchi su "Accetta" permetti al loro utilizzo.

Chiudi