Abstract
Questa pagina spiega come modificare il modulo brain & vision di
I-droid01, distribuito in Italia ba DeAgostini e come riutilizzarla
nei tuoi progetti. Il modulo di I-droid01 (ora scheda ARM) e' basato
su un microprocessore Freescale MC9328MXL, sulla scheda ci sono
inoltre una RAM da 16MB e una Flash da 16MB per immagazzinare il
firmware. Vedremo come costruire un kernel Linux per questa scheda,
come collegarla alla Linux box, come caricare il file immagine nella
Flash e come bootare. Alla fine dovremmo avere una nuova Linux box
nella scheda stessa.
Test preliminare
La scheda che tieni in mano e' un concentrato di potenza in grado di
fare qualunque cosa tu possa immaginare (e anche di piu'): e' basata
su un microprocessore Freescale MC9328MXL, un microprocessore ARM con
un clock a 150MHz, equipaggiato con 16MB di RAM e 16MB di Flash.
Prima di fare qualsiasi altra cosa hai bisogno di qualche strumento:
hai bisogno di un
convertitore RS232-TTL e della
mia versione di miniterm (sei libero
di usare il tuo emulatore di terminale preferito ma io preferisco il
mio).
Procediamo!
1) Collega il convertitore RS232-TTL
alla linea seriale come mostrato in figura. I pins 4 e 5 sul connettore
seriale sono i segnali RTS e CTS, per il momento non abbiamo bisogno
dell'handshake quindi collegali tra di loro.
2) Collega il lato RS232 del
convertitore RS232-TTL
alla tua Linux box utilizzando un cavo pin to pin
(in questo esempio /dev/ttyS0).
3) Chiudi il jumper di programmazione al centro della scheda ARM.
4) Avvia miniterm, in questo momento
non ci interessa la velocita' del collegamento, quindi digita:
$ miniterm -d /dev/ttyS0
5) Alimenta la scheda ARM con un alimentatore stabilizzato a 3.3V.
Attenzione la tensione deve essere molto precisa, se usi un
classico alimentatore a 5V puoi distruggere la scheda. I
microprocessori ARM necessitano di un'alimentazione a 3.3V, se non
hai una sorgente stabilizzata a 3.3V puoi pensare di cannibalizzare
un alimentatore per PC e utilizzare l'uscita a 3.3V per alimentare
la scheda. In questo caso ricordati di caricare l'uscita a 3.3V
dell'alimentatore con una resistenza da 5.6ohm o meno per evitare che
l'alimentatore si spenga per mancanza di carico. Misura la tensione
in uscita con un voltmetro digitale prima di alimentare la scheda.
6) Premi il tasto a , dovresti leggere il carattere
: (duepunti). Se funziona sei a posto!
Il bootstrap loader presente all'interno dell'MC9328MXL ha ricevuto
la tua a , ha individuato la velocita' della linea ed
ha risposto con : (duepunti).
Ora sei pronto per il prossimo passo: scaricare ed installare una
toolchain per microprocessori ARM, scaricare e compilare un bootloader,
caricarlo sulla scheda, giocare un po' con esso, scaricare e
compilare il kernel di Linux, caricare il kernel di Linux sulla scheda,
caricare il filesystem, caricare altri sfronzoli, riavviare...
...niente panico! Porcederemo passo per passo.
La toolchain
Ci sono due modi per installare una toolchain per microprocessori ARM:
Primo
Andare alla pagina di
Phil Blundell e seguire le sue istruzioni per installare una
toolchain per ARM.
Secondo
Continuare a leggere questa pagina e seguire la mia esperienza,
ovviamente io preferisco questa via.
Se il tuo gcc e' gia' aggiornato puoi saltare il passo 2
e passare direttamente dal passo 1 al 3, altrimenti se hai bisogno di
aggiornare il gcc o non ce l'hai per niente, segui tutti i
passi. Attenzione: la documentazione ufficiale del gcc
raccomanda di utilizzare lo stesso gcc per compilare un
cross compiler, questo significa compilare gcc due volte.
Io mi riferiro' a gcc-3.2.3 ma tu puoi installare qualsiasi versione.
1) Scarica gcc-3.2.3.tar.gz in /usr/local/src
$ cd /usr/local/src
$ tar -zxvf gcc-3.2.3.tar.gz
2) Installa gcc come compilatore C nativo:
$ mkdir gcc-3.2.3-build
$ cd gcc-3.2.3-build
$ /usr/local/src/gcc-3.2.3/configure --prefix=/usr/local/gcc-3.2.3 --enable-languages=c++,c
$ make CFLAGS='-O' LIBCFLAGS='-g -O2' LIBCXXFLAGS='g -O2 -fno-implicit-templates' bootstrap
$ make install (come root)
Attenzione: prima di installare gcc devi installare
(o aggiornare) le binutils; io ho saltato questo passaggio
perche' nel mio sistema le avevo gia' aggiornate per altri motivi,
in caso di dubbio puoi consultare il manuale di gcc.
3) Scarica binutils-2.17.tar.gz
(o superiore) in /usr/local/src
$ tar -zxvf binutils-2.17.tar.gz
$ mkdir binutils-2.17-build-arm
$ cd binutils-2.17-build-arm
$ /usr/local/src/binutils-2.17/configure --target=arm-elf --prefix=/usr/local/gcc-3.2.3-arm --program-prefix=arm-
$ make
$ make install
4) Ricompila gcc per ARM:
$ cd /usr/local/src
$ mkdir gcc-3.2.3-build-arm
$ cd gcc-3.2.3-build-arm
$ /usr/local/src/gcc-3.2.3/configure --target=arm-elf --prefix=/usr/local/gcc-3.2.3-arm --program-prefix=arm- --disable-threads --disable-shared --with-newlib --enable-languages=c,c++
$ make
$ make install
5) Scarica newlib-1.15.0.tar.gz
in /usr/local/src
$ tar -zxvf newlib-1.15.0.tar.gz
$ mkdir newlib-1.15.0-build-arm
$ cd newlib-1.15.0-build-arm
$ /usr/local/src/newlib-1.15.0/configure --target=arm-elf --prefix=/usr/local/gcc-3.2.3-arm --program-prefix=arm- --enable-target-optspace
$ make
$ make install
Attenzione: io ho avuto qualche problema durante l'installazione
della newlib seguendo parola per parola questo processo: ho dovuto
creare alcuni link nel mio /usr/local/gcc-3.2.3-arm/bin
per far si che i binari apparissero come arm-elf-nomefile
e non come arm-nomefile . Una soluzione migliore potrebbe
essere quella di usare --program-prefix=arm-elf- nei
passi 3 e 4.
Ora dovresti avere una toolchain per microprocessori ARM
funzionante.
Il prossimo passo sara' compilare un bootloader per la nostra scheda
e caricarlo.
Un altro esempio
Ecco un'altro esempio di toolchain per ARM basata su gcc-3.3.5
(gcc-3.3.5 era gia' installato come compilatore di sistema):
$ cd
$ mkdir build
$ cd build
$ wget ftp://ftp.gnu.org/gnu/binutils/binutils-2.17.tar.gz
$ wget ftp://ftp.lip6.fr/pub/gcc/releases/gcc-3.3.5/gcc-3.3.5.tar.gz
$ wget ftp://sources.redhat.com/pub/newlib/newlib-1.15.0.tar.gz
$ tar -zxvf binutils-2.17.tar.gz
$ mkdir binutils-2.17-build-arm
$ cd binutils-2.17-build-arm
$ ../binutils-2.17/configure --target=arm-thumb-elf --prefix=/usr/local/gcc-3.3.5-arm --program-prefix=arm-
$ make
$ make install
$ cd $HOME/build
$ export PATH=$PATH:/usr/local/gcc-3.3.5-arm/bin
$ tar -zxvf gcc-3.3.5.tar.gz
$ mkdir gcc-3.3.5-build-arm
$ cd gcc-3.3.5-build-arm
$ ../gcc.3.3.5/configure --target=arm-thumb-elf --prefix=/usr/local/gcc-3.3.5-arm --program-prefix=arm- --disable-threads --disable-shared --with-newlib --enable-languages=c
$ make
$ make install
$ cd /usr/local/gcc-3.3.5-arm/bin
$ ln -s arm-thumb-elf-cpp arm-cpp
$ ln -s arm-thumb-elf-gcc arm-gcc
$ ln -s arm-thumb-elf-gcc-3.3.5 arm-gcc-3.3.5
$ ln -s arm-ar arm-thumb-elf-ar
$ ln -s arm-as arm-thumb-elf-as
$ ln -s arm-nm arm-thumb-elf-nm
$ ln -s arm-ld arm-thumb-elf-ld
$ ln -s arm-ranlib arm-thumb-elf-ranlib
$ export PATH=$PATH:/usr/local/gcc-3.3.5-arm/bin
$ cd $HOME/build
$ tar -zxvf newlib-1.15.0.tar.gz
$ mkdir newlib-1.15.0-build-arm
$ cd newlib-1.15.0-build-arm
$ ../newlib-1.15.0/configure --target=arm-thumb-elf --prefix=/usr/local/gcc-3.3.5-arm --program-prefix=arm- --enable-target-optspace
$ make
$ make install
Il bootloader
Qualcuno potrebbe chiedere: Perche' abbiamo bisogno di un
bootloader? Se vuoi installare ed eseguire un'applicazione
custom, senza usare un vero sistema operativo, si puo' fare senza
usare un bootloader. In questo caso la Flash conterra' solo la tua
applicazione e nient'altro, quindi il processore eseguira' solo questo
codice.
Se vuoi caricare ed eseguire un vero sistema operativo come Linux hai
bisogno di un bootloader, il bootloader ha due funzioni: prima di
tutto puo' essere usato come debugger, ti fornisce un interprete dei
comandi che puo' eseguire alcune operazioni come visualizzare il
contenuto della memoria, scrivere del codice nella Flash, caricare
codice o immagini della memoria, etc. Secondo puo' avviare il kernel
di Linux, questa cosa puo' essere fatta in modi diversi: per esempio
il kernel puo' essere caricato dalla Flash e scompattato nella RAM,
oppure puo' risiedere su una memory stick, caricato da li e
scompattato nella RAM. Alcuni bootloader possono scaricare l'immagine
del kernel da un server TFTP o caricarlo da disco fisso.
Come puoi vedere lo scenario e' molto ampio, l'unico limite e'
la tua immaginazione.
Possiamo dire che un bootloader puo' aiutarti qualsiasi uso tu
abbia in mente quer questa scheda.
Ci sono molti bootloader che puoi utilizzare nelle tue applicazioni
embedded, ecco qui una piccola lista:
Non tutti i link in questa lista sono affidabili, qualche link
potrebbe puntare alla pagina sbagliata.
Io sto' usando u-boot nei miei esperimenti, quindi questa pagina
illustrera come utilizzare questo bootloader con la scheda di
I-Droid01.
Quindi andiamo a creare la nostra imagine di u-boot.
1) Crea un nuovo albero per i files ARM nella tua home directory:
$ cd
$ mkdir -p micro/mc9328mx1/src
$ cd micro/mc9328mx1/src
2) Scarica u-boot
in $HOME/micro/mc9328mx1/src
$ bunzip2 u-boot-1.1.6.tar.bz2
$ tar -xvf u-boot-1.1.6.tar
3) Scarica la mia patch (la puoi rovare
nella sezione download) in
$HOME/micro/mc9328mx1/src ed applicala:
$ patch -p0 < u-boot-1.1.6-idroid-patch-0.02.diff
Questo modofichera' alcuni files di configurazione per permettere ad
u-boot di girare sulla ARM board.
Prima di compilare u-boot controlla che nel file
u-boot-1.1.6/include/configs/mx1ads.h queste due righe
non siano commentate:
#define CONFIG_SKIP_LOWLEVEL_INIT 1
#define CONFIG_SKIP_RELOCATE_UBOOT 1
4) Compila u-boot:
$ mkdir u-boot-1.1.6-build-arm
$ cd u-boot-1.1.6
$ export CROSS_COMPILE=arm-elf-
$ export BUILD_DIR=$HOME/micro/mc9328mx1/src/u-boot-1.1.6-build-arm
$ make mx1ads_config
$ make all
Ora dovresti avere una qualche immagine di u-boot nel tuo build tree.
5) Caricare u-boot.
Hai bisogno di mxldump
per caricare u-boot sulla scheda, vai alla software page e installalo,
quindi torna subito qui.
Hai bisogno anche di un'altra cosa per caricare qualsiasi software
sulla scheda ARM: hai bisogno di avviare il ciclo di rinfresco della
RAM.
Sulla scheda ARM ci sono una memoria Flash ed una RAM, la Flash e'
come una ROM e questo non e' un problema, la RAM e' una RAM dinamica
mappata ad un preciso indirizzo. Il problema e' che una RAM dinamica
deve essere rinfrescata e che in questo momento non c'e' nessuno
sulla scheda che sappia dov'e' questa RAM e come funziona.
Se vuoi mettere del codice nella RAM della scheda devi
inizializzarla e rinfrescarla.
Questo processo dipende dall'hardware, questo significa che abbiamo
bisogno di una procedura per rinfrescare questa RAM in
questa scheda. Io ho sniffato la sequenza originale
utilizzata per caricare il firmware di I-Droid01 sulla scheda, la
sequenza di caricamento incomincia con questo codice:
00220000C400400C01 ; CS0U
00220004C411110C01 ; CS0L
00221000C491020200 ; pre-charge command
08200000E4 ; special read
00221000C4A1020200 ; auto-refresh command
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
08000000E4 ; 8 special read
00221000C4B1020200 ; set mode register
08088C00E4 ; special read
00221000C481028200 ; set normal mode
Questa e' una serie di B-records spediti al firmware loader per
scrivere e leggere alcuni registri del microprocessore. Se vuoi puoi
scaricare raminit.raw qui.
Accendi la tua ARM board e da un terminale digita:
$ cd u-boot-1.1.6-build-arm
$ export MXLDUMP_SPD=8
$ export MXLDUMP_DEV=/dev/ttyS0
$ mxlsync
$ mxlraw < raminit.raw
$ mxlwrite -a 0x08400000 < u-boot.bin
$ mxlexec -a 0x08400000 ;miniterm -s 6 -d /dev/ttyS0
Questa procedura eseguira' i seguenti passi:
- sincronizzare il loader presente nel micro.
- avviare il ciclo di refresh della RAM (senza di questo non
hai una RAM).
- caricare il codice di u-boot.
- eseguire u-boot.
- eseguire miniterm.
Ora sei pronto per la tua prima esperienza con u-boot, prova i comandi,
devi prendere familiarita' con u-boot prima di installare il kernel
di Linux.
Se tutto va bene il prossimo passo sara' installare il codice di
u-boot nella memoria flash, in modo che u-boot rimanga residente sulla
ARM board.
|
Attenzione: u-boot sta funzionendo ma c'e' un
piccolo problema con la flash eprom: la memoria flash
montata su questa scheda e' diversa dalla flash montata sulla
scheda ADS. u-boot ha un driver solo per quest'ultima e non
funziona con la nostra.
Questo significa che non puoi programmare la flash utilizzando
u-boot come indicato nel capitolo Installare
u-boot , dovresti riscrivere il driver per la memoria
flash.
In questo momento sto lavorando alla soluzione ma ho molti
problemi e poco tempo. Se stai leggendo questo avviso allora
non ho ancora rimpiazzato il driver per la flash.
Qui
puoi trovare alcune note riguardo come modificare u-boot.
|
|
Installare u-boot
Prima di tutto devi ricompilare u-boot, quindi commenta queste due
righe in include/configs/mx1ads.h e ricompila u-boot
#define CONFIG_SKIP_LOWLEVEL_INIT 1
#define CONFIG_SKIP_RELOCATE_UBOOT 1
Ora dovresti avere due versioni leggermente differenti di u-boot: la
prima e la stessa senza le due linee sopra. Chiameremo la prima
verione ram-only-u-boot.bin e la seconda versione
final-u-boot.bin .
Ora resetta la scheda e digita:
$ mxlsync
$ mxlraw < raminit.raw
$ mxlwrite -a 0x08400000 < ram-only-u-boot.bin
$ mxlwrite -a 0x08420000 < final-u-boot.bin
$ mxlexec -a 0x08400000 ;miniterm -s 6 -d /dev/ttyS0
MXL$ ...(continua)
Spegni la scheda ARM, rimuovi il jumper di programmazione e riaccendi
la scheda: u-boot dovrebbe partire.
Ora abbiamo la scheda con u-boot installato, il prossimo passo
sara' costruire un kernel di Linux e installarlo sulla scheda.
Linux kernel
Il prossimo passa e' costruire, caricare ed eseguire il kernel di
Linux; questo puo' essere un pochino complicato da fare e
sicuramente lungo da spiegare, cosi' l'ho spostato in un'altra
pagina completamente dedicata al kernel di Linux e al filesystem. Se
sei interessato clicca qui.
Board pinout
Applicando una tecnica di reverse engineering ho trovato la
piedinatura completa della scheda, se sei interessato la puoi
trovare qui.
|
Warning: questa pagina non e' ancora finita!
Il lavoro e' ancora in corso.
|
|
Download
Puoi scaricare tutti i files relativi al progetto ARM diretamente
da qui.
u-boot-1.1.6-idroid-patch-0.02.diff
dab99952044e2aef6fb904e84577d6c2
|
U-boot patch: modifica i files di configurazione della board
mx1ads per adattare u-boot al nuovo hardware.
|
u-boot-1.1.6-idroid-patch-0.03.diff
ab37704e768f29808a7a4b3bbc918d06
|
U-boot patch: aggiunti i probes per controllare l'esecuzione dei
programmi ed un nuovo comando per gestire direttamente dalla
riga di comando lo stato dei probes: i probes utilizzano le 6
linee del connettore J3, col comando probe puoi cambiare
lo stato delle linee.
|
Ricorda di applicare solo l'ultima patch disponibile ad un
codice sorgente pulito con lo stesso numero di versione, non
applicare mai piu' di una patch alla volta.
Come applicare una patch
Per applicare o creare una patch segui questi passi: io assumo che
sia u-boot-1.1.6 la directory contenente i sorgenti
originali di u-boot e u-boot-1.1.6-modified la
directory contenente i sorgenti modificati.
Prima di creare la patch testa le tue modifiche.
Per creare la patch digita:
$ diff -r -C 3 u-boot-1.1.6 u-boot-1.1.6-modified >
u-boot-1.1.6-idroid-patch-0.02.diff
Per applicare la patch digita:
$ patch -p0 < u-boot-1.1.6-idroid-patch-0.02.diff
Per verificare la patch digita:
$ diff -rq u-boot-1.1.6 u-boot-1.1.6-patched
Links
Alcuni link utili riguardo questo progetto:
binutils
|
binutils ftp repository.
|
GCC
|
GCC homepage.
|
newlib
|
newlib homepage.
|
u-boot
|
u-boot repository presso sourceforge.
|
ARM Linux
|
porting del kernel di Linux per varie architetture ARM.
|
uClinux
|
La homepage del progetto uClinux: linux per mcroprocessori che
non hanno la MMU.
|
brain & vision
|
descrizione del modulo brain & vision e links ai data sheets.
|
FAQ
Q:
A:
Contatti
Se hai delle domande, suggerimenti, problemi, etc. puoi contattami
a questo indirizzo:
bit.trapper@gmail.com
Ultimo aggiornamento: 29 Dic 2012
|