Ptxdist

La scheda Micro2440-SDK arriva con il bootloader Supervivi a bordo. Supervivi è un po' limitato come funzionalità, ad esempio non consente di effettuare il bootstrap del kernel da sorgenti diverse. Io sono interessato a verifcare la procedura di boot anche da SD card, pertanto ho deciso di aggiornare il bootloader nella Nand, conservando Supervivi nella Nor flash.

Incuriosito dalla lettura dei post sul bootloader U-Boot, l’ho scaricato e compilato, sia dal DVD in dotazione, che dalla rete (git://repo.or.cz/u-boot-openmoko/mini2440.git), tuttavia non sono riuscito a farlo girare sulla RAM della scheda micro2440 (in Nand, ovviamente non ci ho neppure provato). Di tentativi ne ho fatti diversi, tutti con poca fortuna. Sono solo riuscito a scaricare dal Forum FriendlyARM un u-boot eseguibile che partiva sulla mia scheda, ma non avere la possibilità di accedere al sorgente di questo importante software di base, non era il mio obiettivo.


Barebox

Allora ho deciso di provare con il bootloader Barebox, che poi sarebbe un’evoluzione di U-Boot, tanto che inizialmente si chiamava U-Boot-V2. Ho clonato sul mio host Linux Fedora l’ambiente di sviluppo con il comando:


$ git clone git://git.pengutronix.de/git/barebox.git
Solo tre comandi per ottenere l’eseguibile barebox.bin compilato per la scheda mini2440:


$ make clean
$ make ARCH=arm  mini2440_defconfig
$ make ARCH=arm CROSS_COMPILE=arm-linux-
Per provarlo sulla scheda occorre commutare l’avvio da Nor ed entrare nel menu esteso di Supervivi, tramite il commando q del menu iniziale, quindi avviare il caricamento in ram, con il commando:


# load ram 0x31000000 0x2d5d0 u

Selezionare il file barebox.bin dall’applicazione Windows dwn.exe, USB Port->Transmit/Restore e, alla fine del caricamento, avviarne l'esecuzione:


# go 0x31000000
E barebox è partito, visualizzando la sua schermata iniziale con il prompt dei comandi.

I problemi però iniziano ora, perché tanto per cominciare, barebox non vedeva la Nand. Così mi sono ritrovato a debuggare quel firmware fino ad identificare la causa del problema, nel file nand_s3c24xx.c, linea 427, dove ho dovuto inserire l’istruzione:


host->base = (void *)S3C24X0_NAND_BASE;
e magicamente la mia Nand Samsung K9K8G8U0B da 1 GiB è stata rilevata da barebox.

Nel file di configurazione mini2440_defconfig è possibile configurare il prompt di barebox ed altre opzioni, tra cui il tipo di LCD (nel mio caso da 7”):


CONFIG_MINI2440_VIDEO_A70=y


tftp

A questo punto occorre configurare i parametri tftp, dal momento che barebox utilizza questo protocollo per caricare le immagini degli eseguibili. Per installare tftp su Fedora è sufficiente lanciare il comando da terminale:


$ yum install tftp-sever

Quindi editare il file /etc/xinetd.d/tftp, ponendo = no l’opzione disable ed eventualmente modificare il percorso della cartella tftpboot, che di default è /var/lib/tftpboot. A questa cartella vanno assegnati i permessi d’accesso e ci si deve copiare il file immagine del kernel di linux, zImage_A70, e l’esegubile barebox.bin, ma senza l’estensione .bin.

Per lanciare il server tftp, ho eseguito i seguenti comandi:


$ /sbin/chkconfig tftp on
$ /sbin/chkconfig xinetd on
$ /sbin/service xinetd start
Ricordando sempre di disabilitare il firewall con:


$ sudo lokkit –-disabled
Barebox deve essere opportunamente configurato per accedere al server tftp. Occorre quindi editare opportunamente il file di configurazione barebox/arch/arm/boards/mini2440/env/config:


#!/bin/sh

hostname=mini2440
eth0.serverip=
user=

# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
#ip=dhcp


# or set your networking parameters here
eth0.ipaddr=192.168.1.57
eth0.netmask=255.255.255.0
eth0.gateway=192.168.1.1
eth0.serverip=192.168.1.5
eth0.ethaddr=70:71:bc:cc:24:91

# can be either 'nfs', 'tftp' or 'nand'
kernel_loc=tftp
# can be either 'net', 'nand' or 'initrd'
rootfs_loc=net

# can be either 'jffs2' or 'ubifs'
rootfs_type=jffs2
rootfsimage=root-${hostname}.${rootfs_type}

kernelimage_type=zimage
#kernelimage=zImage-${hostname}kernelimage=zImage_A70
#kernelimage=uImage-$hostname
#kernelimage=Image-$hostname
#kernelimage=Image-$hostname.lzo

bareboximage=barebox
if [ -n $user ]; then
    kernelimage="${user}"-"${kernelimage}"
    nfsroot="${eth0.serverip}:/home/${user}/nfsroot/${hostname}"
    rootfsimage="${user}"-"${rootfsimage}"
else
    nfsroot="${eth0.serverip}:/opt/FriendlyARM/mini2440/rootfs_qtopia"
fi

autoboot_timeout=3

# "mini2440" kernel parameter
# 0 .. 9 = screen type
# b = backlight enabled
# t = touch enabled
# c = camera enabled
# Note: can be "minit2440= " if nothing of these components are connected
#
bootargs="console=ttySAC0,115200 mini2440=1tbc"
# NAND boot settings
# Device name used by the kernel
nand_device="nand"
nand_parts="512k(barebox),384k(bareboxenv),2048k(kernel),-(root)"
rootfs_mtdblock_nand=3
# used when manually booting with "boot nand" command
rootfs_mtdblock_type=jffs2

# MMC/SD boot settings
# partition number to read the kernel from
# (starting with # 0, Barebox's counting scheme)
kernel_mmc_part=0
# rootfs's partition number
# (starting with # 1, Kernel's counting scheme)
rootfs_mmc_part=2
# used when manually booting with "boot mmc" command
rootfs_mmc_type=ext2
Il percorso /opt/FriendlyARM/mini2440/rootfs_qtopia è lo stesso che avevamo impostato per il bootstrap via NFS.

Dopo aver ricompilato e caricato barebox in RAM lo si lancia, come visto in precedenza, questa volta senza interrompere il bootstrap. A questo punto se tutto è stato fatto a dovere, barebox caricherà l’immagine del kernel di linux via tftp, e la rootfs via nsf. Questa modalità consente di modificare agevolmente sia il kernel che la rootfs della scheda, dal PC host, velocizzando anche i caricamenti di prova.

Verificato che il bootstrap viene eseguito correttamente, si può procedere alla scrittura di barebox in Nand, dalla shell di barebox, con il comando:


 update –t barebox –d nand

Converrà anche memorizzare in maniera permanente i valori d'ambiente:

 saveenv



Un'ultima nota, con il mio server tftp, barebox andava continuamente in timeout, così ho dovuto decuplicare il numero di ritentativi, nel file sorgente di barebox, tftp.c, alla linea 357.



Bootstrap da SD card


La fase di bootstrap consiste nel caricamento dell’immagine del kernel, la sua decompressione e avvio. Il kernel deve poter trovare e montare il filesystems supportato, in un qualche supporto di memoria (concettualmente come un hard disk).

Il bootloader barebox, che risiede in flash e si avvia al power-on/reset, è in grado di caricare l’immagine del kernel da diversi supporti. Innanzi tutto dalla Nand flash, dove deve essere stato  precedentemente scritto. Può caricarlo attraverso la rete, da un server remoto, tramite il protocollo tftp o NFS. Oppure da una SD memory card. Questi ultimi modi possono risultare utili in fase di messa a punto del software, per evitare di riscrivere la Nand ad ogni prova.

I parametri necessari alle diverse opzioni di caricamento del kernel, sono contenuti nello script /env/config, eseguito all’avvio da barebox. Per il caricamento da rete occorre valorizzare i relativi parametri (eth0.netmask, eth0.gateway, eth0.serverip, eth0.ethaddr). Barebox supporta sia l’assegnazione dinamica dell’indirizzo IP (ip=dhcp), che l’IP statico (eth0.ipaddr).

Il nome (kernelimage) e il tipo di immagine del kernel (kernelimage_type=zimage/uimage) devono essere specificati nei parametri da configurare in /env/config,  come anche la stringa passata al kernel all’avvio (bootargs), che tra l’altro deve contenere il percorso della root e il tipo di filesystem.

Per lo stesso motivo per cui barebox non vedeva la Nand flash, anche nel driver specifico della MMC (s3c.c) è stato necessario inserire una patch alla linea 752, affinché venisse correttamente vista la SD:

s3c_host->base = (void *)S3C2410_SDI_BASE;

Sospetto che il problema sia dovuto al build di barebox, eseguito con la toolchain arm-linux-gcc-4.3.2, senza utilizzare l’ambiente ptxdist. Il sospetto è confermato quando decido di provare il toolkit OSELAS Pengutronix ptxdist.

Ad ogni modo, l’ostacolo principale al bootstrap da SD card consiste nel fatto che il kernel linux nativo della scheda, linux-2.6.32.2-mini2440_20110413, non riesce a vedere SD card con filesystem diverso da FAT, e siccome per il bootstrap da SD card occorre la formattazione di questa con due partizioni, una per il kernel e l’altra per la rootfs con filesystem ext2, questo tipo di bootstrap non è effettuabile con il kernel nativo, che invece consente tutti gli altri tipi di bootstrap supportati da barebox .

Per tale ragione ho deciso di provare la distribuzione Pengutronix (kernel linux 3.4.4-ptx-2012.06.0) e il build system PTXdist (versione 2012.7.0), scaricandolo da questo indirizzo. Dalla stessa pagina è possibile scaricare anche le patches (ptxdist-2010.06.1-patches), mentre da questa pagina è possibile scaricare le BSP per la scheda mini2440 (OSELAS.BSP-Pengutronix-Mini2440-2012.06.0.tgz) ed un utile manuale che vi guida nell’installazione e nel build. Infine, la toochain OSELAS.Toolchain-2011.11.1.tar.bz2 può essere scaricata da questa pagina.

Ricapitolando, il kit è composto da 4 packages:
  • la toolchain
  • la distribuzione linux-3.4.39
  • le patches
  • le BSP per la scheda mini2440.
Preparatevi a consumare diversi GiB dello spazio disco, ad installare numerosi packages richiesti sulla macchina virtuale, tipo:

yum install autoconf
yum install patch
yum install fakeroot
yum install texinfo-tex
yum install wget
yum install bison
yum install flex
yum install ncurses

e ad attendere svariato tempo per la compilazione e l’installazione di PTXdist e il build di barebox, kernel e rootfs per la scheda mini2440, seguendo scrupolosamente le istruzioni del manuale. Nel caso, potrà farvi comodo sapere come aumentare lo spazio del disco virtuale su VirtualBox.

Infine, se tutto è andato bene, ci si ritrova con l’immagine di barebox (in formato binario), del kernel (in formato uImage) e della rootfs (in formato jffs2), oltre al formato compresso (rootfs.tgz).

Caricato questo nuovo barebox in ram, tramite Supervivi, mi sono accorto subito che, a differenza di quello che avevo già compilato e installato con le mie patches, questo vedeva subito la Nand e non andava in timeout nelle connessioni tftp, tuttavia non vedeva la SD card. Così, senza perderci tempo sopra, sono tornato alla mia versione di barebox e con quella ho caricato il kernel e la roofs via tftp, nella Nand flash, e la scheda ha boostrappato al primo colpo.

Questa distribuzione è più ricca di comandi e riesce, tra l’altro, ad accedere alle SD card con filesystem ext2. Da qui, a boostrappare da SD card, il passo è stato breve. Dopo aver caricato nella prima partizione della SD card l’immagine del kernel (con il comando dd) ed aver estratto nella seconda la rootfs, così come indicato nel manuale OSELAS.BSP-Pengutronix-Mini2440-Quickstart.pdf, ho semplicemente creato uno script nell’ambiente barebox, con i seguenti comandi:

#!/bin/sh

mci0.probe=1

bootargs=”noinitrd root=/dev/mmcblk0p2 rootfstype=ext2 rootwait console=ttySAC0,115200 mini2440=1tbc ip=192.168.1.57:192.168.1.1:192.168.1.1:255.255.255.0”

bootm /dev/disk0.0


E la scheda ha finalmente bootstrappato da SD card una distribuzione linux di cui ho il pieno controllo, e che prevede anche una configurazione dello spazio utente comprensiva delle librerie Qt, configs/ptxconfig.qt, oltre a quella base, che ho inizialmente utilizzato.



Configurazione Ptxdist Qt


Queste operazioni non sono mai semplici come sembrerebbe a prima vista. Così capita che la configurazione ptxconfig.qt, per la generazione di uno spazio utente con supporto per applicazioni Qt, non sia una passeggiata.

Iniziamo col dire che il build del sistema andava in segment fault durante la compilazione dell’ambiente Qt. Dopo un po’ di debug, ho capito che era dovuto all’uso dell’opzione -pch (per la pre-compilazione degli headers) in fase di configurazione di qt-everywhere-opensource-src-4.8.2. La definizione è contenuta nel file qt4.make, nella toolchain Pengutronix. E’ bastato cambiarla in –no-pch, perché la compilazione di qt-everywhere-opensource andasse a buon fine.

Ma i problemi non sono finiti lì, perché nel frattempo il build ha esaurito  tutto lo spazio disco residuo, così ho dovuto ridefinire un nuovo disco da 17 GiB e copiarci tutto l’ambaradan, operazione che ha richiesto svariate ore. 

Infine sono riuscito a generare kernel e rootfs, lottando fino all’ultimo errore: genext2fs: couldn't allocate a block (no free space), durante il comando ptxdist images. La soluzione è stata quella di portare a 100M il parametro PTXCONF_IMAGE_ROOT_EXT_SIZE in selected_platformconfig.

Per caricare il kernel e la rootfs generati nella cartella image, sulla scheda Micro2440, è stato sufficiente copiarli nella cartella tftpboot del sistema host, rinominarli con i nomi definiti nello script /env/config di barebox (nel mio caso rispettivamente uImage-mini2440 e root-mini.jffs2) e lanciare i comandi da barebox:

update –t kernel –d nand
update –t rootfs –d nand
Riavviata la scheda alla fine del lungo caricamento tftp, il kernel e la rootfs sono partiti correttamente, ma il display non voleva saperne di funzionare, nonostante nella stringa di bootargs fosse presente la direttiva mini2440=1tbc, nella quale 1 indica il display da 7” AT070TN83.

Purtroppo ho scoperto solo dopo ciò che nella guida OSELAS.BSP-Pengutronix-Mini2440-Quickstart.pdf è riportato chiaramente, ovvero che il modello di LCD supportato dalle BSP è il LCDN3502-23B (N35) da 3,5”, con risoluzione 240x320.

Altro tempo per capire come configurare il mio LCD da 7", AT070TN83 (A70), risoluzione 800x480, pure gestito dal driver, e alla fine ho scoperto che la chiave risiede nel file build-target/linux-3.4/arch/arm/mach-s3c24xx/mach-mini2440.c, che alla linea 661 contiene lo statement:

static char mini2440_features_str[12] __initdata = "0tb";
che invece deve essere:

static char mini2440_features_str[12] __initdata = "1tb";
E via, a lanciare un nuovo lungo build. Stavolta però l’ho provato in modalità nfs per velocizzare le operazioni, e finalmente mi è apparso il quadro di calibrazione.

Una volta eseguita la calibrazione del touchscreen il sistema avvia la demo Qt perfettamente funzionante sul mio display da 7”.

A proposito del touchscreen, il puntatore risultava abbastanza instabile. Cercando sul documento di Quickstart, ho trovato come aumentare il numero di campionamenti, nel file platform-mini2440//build-target/linux-3.4/arch/arm/mach-s3c2440/mach-mini2440.c e precisamente nella struttura mini2440_ts_cfg, ho portato a 4 il parametro .oversampling_shift., e il puntatore è notevolmente migliorato.

Ora non resta che provare uno tra gli esempi di applicazioni Qt compilati in precedenza, modificando opportunamente lo script di impostatzione delle variabili d'ambiente, e lanciato sempre con l'opzione -qws:

export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/ts
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/lib/ts
export LD_LIBRARY_PATH=/usr/lib
export QTDIR=/usr
export QWS_MOUSE_PROTO=tslib:/dev/input/event0
export QWS_DISPLAY=LinuxFB:mmWidth=310:mmHeight=190


Due sistemi alternativi


La mia scheda Micro2440 è ora pronta per lavorare con due sistemi. Quello originale con il kernel Linux 2.6.32.2 e la rootfs Qtopia_qt4, e quello Pengutronix, con kernel linux 3.4.4-ptx-2012.06.0 e rootfs con librerie Qt. Il primo starà in Nand, programmando prima il kernel zImage_A70 da barebox e poi il rootfs rootfs_qtopia_qt4.img, da Supervivi avviato in Nor flash. Il secondo risiede nella SD memory card. Modificando opportunamente gli scripts d’ambiente di barebox, faccio in modo che l’avvio da SD sia automatico quando questa è presente, altrimenti viene avviato il sistema in Nand, dopo l’attesa solita di 3 secondi, per consentire di rimanere in barebox.

/env/bin/init

#!/bin/sh

PATH=/env/bin
export PATH
. /env/config
if [ -e /dev/nor0 -a -n "$nor_parts" ]; then
    addpart /dev/nor0 $nor_parts
fi
if [ -e /dev/disk0 -a -n "$disk_parts" ]; then
    addpart /dev/disk0 $disk_parts
fi
if [ -e /dev/nand0 -a -n "$nand_parts" ]; then
    addpart /dev/nand0 $nand_parts
    nand -a /dev/nand0.*
fi
if [ -f /env/bin/init_board ]; then
    . /env/bin/init_board
fi
if [ -f /env/bin/boot_board ]; then
    . /env/bin/boot_board
elif [ -n $autoboot_timeout ]; then
    echo
    echo -n "Hit any key to stop autoboot: "
    timeout -a $autoboot_timeout
    if [ $? != 0 ]; then
        exit
    fi
    boot
fi

 /env/bin/init_board

#!/bin/sh

if [ $mci0.probe = 0 ]; then
    mci0.probe=1
fi
if [ -e /dev/disk0.0 ]; then
    bootargs='noinitrd root=/dev/mmcblk0p2 rootfstype=ext2 init=/sbin/init console=ttySAC0,115200 rootwait ip=192.168.1.57 mini2440=1tbc'
    bootm /dev/disk0.0
fi

/env/config

#!/bin/sh

hostname=mini2440
#eth0.serverip=
user=
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
#ip=dhcp
# or set your networking parameters here
eth0.ipaddr=192.168.1.57
eth0.netmask=255.255.255.0
eth0.gateway=192.168.1.1
eth0.serverip=192.168.1.5
eth0.ethaddr=70:71:bc:cc:24:91
# can be either 'nfs', 'tftp' or 'nand'
kernel_loc=nand
# can be either 'net', 'nand' or 'initrd'
rootfs_loc=nand
# can be either 'jffs2' or 'ubifs'
rootfs_type=yaffs2
rootfsimage=root-${hostname}.${rootfs_type}kernelimage_type=zimage
#kernelimage=zImage-${hostname}
kernelimage=zImage_A70
#kernelimage=uImage-$hostname
#kernelimage=Image-$hostname
#kernelimage=Image-$hostname.lzo
bareboximage=barebox

if [ -n $user ]; then
    kernelimage="${user}"-"${kernelimage}"
    nfsroot="${eth0.serverip}:/home/${user}/nfsroot/${hostname}"
    rootfsimage="${user}"-"${rootfsimage}"
else
    nfsroot="${eth0.serverip}:/opt/FriendlyARM/mini2440/rootfs_qtopia"
fi
autoboot_timeout=3
#
# "mini2440" kernel parameter
# 0 .. 9 = screen type
# b = backlight enabled
# t = touch enabled
# c = camera enabled
# Note: can be "minit2440= " if nothing of these components are connected
#
bootargs="console=ttySAC0,115200 mini2440=1tbc"
# NAND boot settings
# Device name used by the kernel
nand_device="nand"
nand_parts="512k(barebox),384k(bareboxenv),4096k(kernel),-(root)"
rootfs_mtdblock_nand=3
# used when manually booting with "boot nand" command
rootfs_mtdblock_type=jffs2
# MMC/SD boot settings
# partition number to read the kernel from
# (starting with # 0, Barebox's counting scheme)
kernel_mmc_part=0
# rootfs's partition number
# (starting with # 1, Kernel's counting scheme)
rootfs_mmc_part=2
# used when manually booting with "boot mmc" command
rootfs_mmc_type=ext2

Nessun commento:

Posta un commento