La gestione dei pacchetti di OpenWRT

openwrt

openwrtUna distribuzione embedded è quanto più versatile quanti più pacchetti software offre ai suoi utenti… ma non solo, è molto versatile anche se è (relativamente) facile aggiungere nuovi pacchetti (sia nello spazio utente che nel kernel).

OpenWRT, una distribuzione embedded già illustrata in diversi miei articoli (si veda ad esempio Portare la BeagleBone su OpenWRT), è sicuramente versatile. Il grande numero di pacchetti software disponibile e la facilità di aggiungerne di nuovi la caratterizzano senz’altro in questo modo.

In questo articolo vedremo come si gestiscono i pacchetti software di OpenWRT, siano essi già disponibili nella distro, ovvero se ne vogliano aggiungere di nuovi.

Nell’articolo darò per scontato che il lettore sappia come si scrive un Makefile.

Innanzi tutto scarichiamoci i sorgenti di OpenWRT con il comando:

$ git clone git://nbd.name/openwrt.git

quindi analizziamo l’albero dei sorgenti:

$ ls trunk/
BSDmakefile  Makefile  feeds.conf.default  rules.mk  toolchain/
Config.in    README    include/            scripts/  tools/
LICENSE      docs/     package/            target/

La directory che contiene i pacchetti disponibili è package:

$ ls package/
Makefile       boot/           hotplug2/   mkelfimage/ procd/      ubus/
acx-mac80211/  broadcom-diag/  kernel/     mountd/     px5g/       uci/
admswconfig/   broadcom-wl/    libs/       mtd/        switch/     udev/
apex/          busybox/        linux-atm/  network/    system/     util-linux/
base-files/    devel/          lua/        opkg/       toolchain/  zram-swap/
block-mount/   fuse/           mac80211/   platform/   trelay/

Ad una prima occhiata possono non sembrare così tanti ma basta lanciare i menu di configurazione di OpenWRT per capire che, in realtà, abbiamo a disposizione già molte funzionalità di base e molto comuni! Se poi non bastasse OpenWRT ha un sistema di feeds con il quale è possibile scaricarsi vi a rete dei pacchetti supplementari da installare al volo.

Ma facciamo un passo alla volta, prima vediamo cosa c’è di già pronto guardando nel menu di configurazione:

$ make menuconfig

Se andiamo nelle voci Base system e Network vediamo già un bel numero di applicazioni gia pronte all’uso.

I feed

Se però, come accennavo prima, questi non fossero sufficienti il sistema di feeds di OpenWRT permette di aggiungere nuovi pacchetti gia pronti alla nostra distribuzione di base. Per attivarlo basta dare il comando:

$ scripts/feeds update

A questo punto il sistema di build di openWRT si collegherà a dei server esterni ed inizierà a scaricarsi la lista di tutti i pacchetti remoti disponibili. Alla fine possiamo ottenere la lista dei nuovi pacchetti con il comando:

$ scripts/feeds list

Facendo un conto grossolano:

$ scripts/feeds list | wc -l
3231

Come si vede, ora il numero di pacchetti software disponibile è decisamente più alto! Per avere un’idea delle potenzialità dei feeds diamo il comando:

$ scripts/feeds help        
Usage: scripts/feeds <command> [options]

Commands:
    list [options]: List feeds, their content and revisions (if installed)
    Options:
        -s :            List of feed names and their URL.
        -r <feedname>:  List packages of specified feed.
        -d <delimiter>: Use specified delimiter to distinguish rows (default: spaces)

    install [options] <package>: Install a package
    Options:
        -a :           Install all packages from all feeds or from the specified feed using the -p option.
        -p <feedname>: Prefer this feed when installing packages.
        -d <y|m|n>:    Set default for newly installed packages.

    search [options] <substring>: Search for a package
    Options:
        -r <feedname>: Only search in this feed

    uninstall -a|<package>: Uninstall a package
    Options:
        -a :           Uninstalls all packages.

    update -a|<feedname(s)>: Update packages and lists of feeds in feeds.conf .
    Options:
        -a :           Update all feeds listed within feeds.conf. Otherwise the specified feeds will be updated.
        -i :           Recreate the index only. No feed update from repository is performed.

    clean:             Remove downloaded/generated files.

se ne deduce che, per cercare uno specifico pacchetto, si può usare il comando search. Ad esempio se voglio vedere se c’è il supporto PHP basta che usi:

$ scripts/feeds search php
Search results in feed ‘packages’:
aodv-uu                      Ad-hoc On-demand Distance Vector Routing (daemon)
chaosvpn                     Config generator for chaos vpn
cifsmount                    CIFS mount utilities
cmdpad                       execute commands when a key is pressed, released or hold down
kmod-aodv-uu                 Ad-hoc On-demand Distance Vector Routing (kernel module)
libortp                      Real-time Transport Protocol (RTP) library
libshout                     Library which can be used to write a source client like ices
libvorbisidec                A fixed-point Ogg/Vorbis decoder library
mpc                          Music Player Daemon Console Client
mpd-full                     Music Player Daemon (full)
mpd-mini                     Music Player Daemon (mini)
php-pear                     PEAR
php-pear-db                  PEAR DB module
php-pear-xmlrpc              PEAR XML-RPC module
php4                         PHP4 Hypertext preprocessor
php4-cgi                     PHP4 Hypertext preprocessor (CGI)
php4-cli                     PHP4 Hypertext preprocessor (CLI)
php4-fastcgi                 PHP4 Hypertext preprocessor (FastCGI)
php4-mod-curl                cURL module
php4-mod-ftp                 FTP module
php4-mod-gd                  GD graphics module
php4-mod-gmp                 GMP module
php4-mod-ldap                LDAP module
php4-mod-mysql               MySQL module
php4-mod-openssl             OpenSSL module
php4-mod-pcre                PCRE module
php4-mod-pgsql               PostgreSQL module
php4-mod-session             Session module
php4-mod-sockets             Sockets module
php4-mod-xml                 XML module
php5                         PHP5 Hypertext preprocessor

Quindi per installare il support PHP5 posso usare:

$ scripts/feeds install php5

Ora se riandiamo nel menu di configurazione con make menuconfig ed andiamo in Languages otteniamo:

OpenWrt Barrier Breaker (r35691) Configuration
 ??????????????????????????????????????????????????????????????????????????????
  ???????????????????????????????? Languages ????????????????????????????????
  ?  Arrow keys navigate the menu.  <Enter> selects submenus —>.          ?  
  ?  Highlighted letters are hotkeys.  Pressing <Y> includes, <N> excludes, ?  
  ?  <M> builds as package.  Press <Esc><Esc> to exit, <?> for Help, </>    ?  
  ?  for Search.  Legend: [*] built-in  [ ] excluded  <M> package  < >      ?  
  ? ??????????????????????????????????????????????????????????????????????? ?  
  ? ?     Lua  —>                                                       ? ?  
  ? ?     PHP  —>                                                       ? ?

Aggiungere un programma

Può succedere però che OpenWRT non supporti un determinato pacchetto software, cioè che non si trovi nemmeno nei feeds; in questo caso, quindi, dobbiamo aggiungerlo noi. L’operazione di per se non è difficile, basta avere un minimo di conoscenza di make e dei Makefile.

Nell’esempio utilizzerò un programmino dummy (cioè che non fa nulla di speciale se non servire alla spiegazione) ma il concetto si estende a qualsiasi applicazione Unix/Linux.

Il nostro programma consta di un Makefile e di un file contenete un programma C. Questo il corpo del programma:

$ cat
package/helloworld/src/helloworld.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf(“hello world!n”);

    return 0;
}

Mentre il Makefile è:

$ cat package/helloworld/src/Makefile     
PROGRAMS := helloworld

CFLAGS += -Wall -O2

all: $(PROGRAMS)

clean: FORCE
    rm -Rf $(PROGRAMS) *.o

FORCE:

Come si vede, entrambi sono stati messi nella directory helloworld in package. Il contenuto della directory è:

$ tree package/helloworld/
package/helloworld/
|– Makefile
`– src
    |– Makefile
    `– helloworld.c

1 directory, 3 files

In src quindi ci sono i sorgenti veri propri del programma da aggiungere mentre il Makefile nella directory padre è quello che definisce i paramteri del programma all’interno di OpenWRT. Analizziamolo bene, perché, stringi-stringi è lui la parte notevole del nostro esempio.

$ cat package/helloworld/Makefile
include $(TOPDIR)/rules.mk

PKG_NAME:=helloworld
PKG_VERSION:=0.1
PKG_RELEASE:=1

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk

EXTRA_CFLAGS +=

Fino a qui non abbiamo fatto altro che definire alcune variabili notevi del pacchetto software che si spiegano palesemente da sole.

define Package/helloworld
    SECTION:=utils
    CATEGORY:=Utilities
    TITLE:=Hello world
    DEPENDS:=
endef

define Package/helloworld/description
  Dummy package
endef

Qui invece si definisce il titolo e la sezione/categoria sotto la quale il pacchetto dovrà apparire nel menu di configurazione. Sono solo parametri descrittivi.

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

Qua, invece, ci sono i comandi preparativi alla compilazione, cioè la creazione della directory di compiazione del pacchetto e la copia in essa dei sorgenti. Questi comandi verranno eseguiti prima del comando make che servirà alla compilazione vera e propria del pacchetto.

define Package/helloworld/install
    $(INSTALL_DIR) $(1)/usr/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin/
endef

$(eval $(call BuildPackage,helloworld))

Se abbiamo fatto tutto bene, con il comando make menuconfig andando nella voce Utilities si vedrà il nostro nuovo pacchetto nella lista delle applicazioni disponibili.

Aggiungere un modulo

L’aggiunta di un modulo del kernel è molto simile a quanto visto prima per un programma, c’è solo da modificare un po’ la descrizoine del pacchetto e i parametri di compilazione. E’ da notare che qui si potrebbe anche optare per aggiungere il nostro modulo direttamente nel kernel della piattaforma; è una soluzione, ma il fatto di creare un pacchetto ad hoc può in alcuni casi rendere l’aggiunta del software più veloce e più versatile (se il modulo è scritto bene può essere usato in diversi kernel/piattaforme).

Anche per questo esempio userò un modulo dummy. Il corpo del modulo è il seguente:

$ cat
package/khelloworld/src/khelloworld.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/err.h>

#define DRIVER_NAME    “khelloworld”

static int __init khelloworld_init(void)
{
    pr_info(DRIVER_NAME “: hello world!n”);

        return 0;
}

static void __exit khelloworld_exit(void)
{
        pr_info(DRIVER_NAME “: bye!n”);
}

module_init(khelloworld_init);
module_exit(khelloworld_exit);

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“Rodolfo Giometti <giometti@linux.it>”);
MODULE_DESCRIPTION(“Dummy kernel package”);
MODULE_ALIAS(“platform:khelloworld”);

Mentre il corpo del Makefile è:

$ cat package/khelloworld/src/Makefile      
obj-${CONFIG_KHELLOWORLD} += khelloworld.o

Analogamente a prima anche qui abbiamo creato una directory ad hoc per il nuovo pacchetto:

$ tree package/khelloworld/
package/khelloworld/
|– Makefile
`– src
    |– Makefile
    `– khelloworld.c

1 directory, 3 files

Il Makefile di OpenWRT è fatto come segue:

$ cat package/khelloworld/Makefile
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=khelloworld
PKG_RELEASE:=1

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk

define KernelPackage/khelloworld
    SUBMENU:=Other modules
    TITLE:=Kernel hello world
    DEPENDS:=@LINUX_3_8
    FILES:=$(PKG_BUILD_DIR)/khelloworld.$(LINUX_KMOD_SUFFIX)
endef

define KernelPackage/khelloworld/description
  Dummy kernel package
endef

Fino a qui è come per il programma illustrato prima, si definiscono una serie di variabili notevoli che descrivono il pacchetto software.

EXTRA_KCONFIG:=
    CONFIG_KHELLOWORLD=m

MAKE_OPTS:=
    ARCH=”$(LINUX_KARCH)”
    CROSS_COMPILE=”$(TARGET_CROSS)”
    SUBDIRS=”$(PKG_BUILD_DIR)”
    EXTRA_CFLAGS=”$(EXTRA_CFLAGS)”
    LINUXINCLUDE=”-I$(LINUX_DIR)/include -I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include -include linux/autoconf.h”
    $(EXTRA_KCONFIG)

Qui invece si definiscono i parametri di compilazione.

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

Qui si preparano i sorgenti per la compilazione.

define Build/Compile
    $(MAKE) -C “$(LINUX_DIR)”
        $(MAKE_OPTS)
        modules
endef

$(eval $(call KernelPackage,khelloworld))

In fine il comando di compilazione del nostro modulo del kernel.

Ora, per verificare se abbiamo fatto tutto bene, con il solito comando make menuconfig e andando nella voce Kernel modules e Other modules vedremo il nostro nuovo modulo nella lista chiamato kmod-khelloworld.

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