AVR32 Grasshopper

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Über das Board

AVR32 Grasshopper.jpg

AVR32-Board, ab 85 Euro - nicht mehr erhältlich!

Technische Daten:

  • 140 MHz (max. 200 MHz möglich)
  • 64 MB SDRAM (32 Bit breit angeschlossen)
  • 8 MB Flash
  • 10/100 MBit/s Netzwerk
  • On-Chip Display Controller
  • 1 USB Highspeed Anschluss
  • 8 LED
  • 1 Taster
  • Power LED (kann auch angesteuert werden)
  • Reset Taster
  • Spannungsversorgung: 5-10V verpolungssicher oder USB Kabel oder über Pinleisten
  • über die Pinleisten sind alle wichtigen Ports herausgeführt


Ressourcen

Speicherlayout

  • Flash: 8MB ab Adresse 0x00000000
  • RAM: 64MB ab Adresse 0x10000000

Austausch von Dateien mit dem Board

Es gibt verschiedene Wege, Dateien mit dem Board auszutauschen. Standardmäßig läuft ein Webserver, der die Dateien unterhalb von /var/www bereitstellt. Auf dem Board ist wget installiert, mit dem Dateien von einem Webserver auf das Board geladen werden können. Ein TFTP-Server ist ebenfalls vorhanden. (Hinweis: Außer dem Namen hat TFTP (Trivial File Transfer Protocol) nichts mit dem bekannteren FTP gemeinsam.) Standardmäßig läuft der Server nicht. Man startet ihn mit folgendem Kommando und begrenzt den Zugriff sicherheitshalber auf Dateien in /tmp:

in.tftpd -l -c -s /tmp

Windows und die gängigen Linux-Distributionen bringen einen TFTP-Client mit, so dass man nun Dateien austauschen kann.

Sollte im LAN bereits ein NFS-Server (Network File System) existieren, kann auch er zum Datenaustausch mit dem Grasshopper dienen. Dazu muss auf dem Board nur portmap gestartet werden. Danach ist ein Mounten von NFS-Freigaben möglich.

Beschreiben des Flash-Speichers

Die 8 MiB Flash-Speicher auf dem Board sind in drei Bereiche aufgeteilt: In den untersten 128 kiB befindet sich der Bootloader U-Boot. Der Bereich von 128 - 192 kiB ist für die Umgebungsvariablen (environment) des Bootloaders reserviert. Das JFFS2-Dateisystem mit der Linuxumgebung (root file system) belegt den Rest.

Am sichersten lässt sich der Flash-Speicher über die auf dem Board vorhandene JTAG-Schnittstelle beschreiben. Offiziell unterstützt Atmel nur den firmeneigenen JTAGICE mkII. Es existieren auch Softwarelösungen, um das Board über ein JTAG-Interface nach Wiggler-Bauart anzusprechen: [[1]].

Ferner lässt sich der Flash-Speicher auch aus dem laufenden Linux heraus (als Benutzer root) oder durch den Bootloader U-Boot beschreiben. Hierbei besteht allerdings ein Risiko. Wird ein defektes JFFS2-Dateisystem geflasht, so läuft Linux nicht mehr, ist gar U-Boot gelöscht oder beschädigt, so startet u.U. das Board nicht einmal mehr. Dann kann es nur noch über JTAG erneut geflasht werden.

Flashen des JFFS2-Dateisystems unter Linux

Zunächst muss das neue Root-Dateisystem in das /tmp-Verzeichnis auf das Board geladen werden, z. B. mit wget oder über tftp. Dann wird das alte Dateisystem zur Sicherheit schreibgeschützt gemountet und durch das neue ersetzt. Danach ist Reset nötig.

mount / -o remount,ro
dd if=/tmp/neues-root-fs of=/dev/mtdblock2 bs=64k

Flashen des Bootloaders unter Linux

Aus Sicherheitsgründen ist der Bereich des Flashs, in dem sich U-Boot befindet, standardmäßig unter Linux schreibgeschützt. Vor dem Booten des Linuxkernels muss daher im alten U-Boot der Inhalt der Environmentvariable bootargs geändert werden. Der Teil

mtdparts=physmap-flash.0:128k(boot)ro,64k(env)ro,-(root)

muss durch

mtdparts=physmap-flash.0:128k(boot),64k(env)ro,-(root)

ersetzt werden. Insgesamt ergeben sich für ein U-Boot im Auslieferungszustand folgende zwei Zeilen, die am U-Boot-Prompt eingegeben werden müssen:

setenv bootargs console=ttyS0 root=1F02 rootfstype=jffs2 mtdparts=physmap-flash.0:128k(boot),64k(env)ro,-(root)
boot

Nun kann U-Boot unter Linux geladen und geflasht werden:

dd if=/tmp/neues-u-boot.bin of=/dev/mtdblock0 bs=4k
  • Achtung: Sollte bei dem letzten Befehl etwas schief laufen oder die neue U-Boot-Version defekt sein, so bootet das Board danach nicht mehr.
  • Hinweis: "Das U-Boot" hat unter Umständen Probleme damit, längere Einträge mit "setenv" zu übernehmen. Das "askenv" Kommando kennt diese Beschränkung nicht und sollte in diesen Fällen verwendet werden.


Flashen des JFFS2-Dateisystems mit U-Boot

Sollte Linux nicht mehr starten, ist es auch möglich, ein neues Dateisystem mit U-Boot in den Flash-Speicher zu schreiben. Allerdings ist die auf dem Board ausgelieferte Version von U-Boot (U-Boot 1.3.1-gd2cbfd4b-dirty (Apr 1 2008 - 18:26:02)) fehlerbehaftet und bricht sowohl beim Löschen des Flashs als auch beim Beschreiben oft mit einer Fehlermeldung ab. Eine compilierte Version ohne diesen Bug steht unter [[2]] zum Download bereit. (Ein Patch für den Quellcode von U-Boot ist ebenfalls verfügbar: [[3]])

Zunächst muss das neue Dateisystem mit U-Boot in den RAM geladen werden. Dies kann z. B. von einem TFTP-Server erfolgen, nachdem IP-Adresse des Boards (x.x.x.x) und des TFTP-Servers (y.y.y.y) gesetzt wurden. neues-root-fs ist hierbei der Name der Datei auf dem Server.

setenv ipaddr x.x.x.x
setenv serverip y.y.y.y
tftp 11000000 neues-root-fs

Ebenso ist das Laden von einer NFS-Freigabe (Kommando nfs) oder über die serielle Schnittstelle (Kommandos loadb, loads, loady) möglich. Dann wird der Flash-Speicher gelöscht und das neue Dateisystem wird in den Speicher geschrieben:

erase 30000 7fffff
cp.b 11000000 30000 7d0000

Booten via NFS

Man kann auch ein Rootfs über NFS mounten. Dieser Hinweis bezieht sich auf feste IP, nicht auf die Konfiguration mit DHCP. Mittels DHCP hab ich es nicht hinbekommen :(. Der Grasshopper ist im Beispiel auf die IP 10.10.10.23 und der Server auf 10.10.10.1 gesetzt.

Dazu sind ein laufender NFS-Server mit einer Freigabe mit der Option no_root_squash (RTFM ;) ) und ein Rootfs im ext2 Format nötig. Dass ein solches erstellt werden soll, kann man in der Buildroot-Umgebung mittels "make menuconfig" einstellen.

Die Datei rootfs.avr32.ext2 wird an z. B. /mnt gemountet

mount -o loop rootfs.avr32.ext /mnt

Sollte man das /mnt-Verzeichnis nicht direkt freigeben wollen, ist danach der Inhalt des Verzeichnisses in das über NFS freigegebene Verzeichnis zu kopieren (hier /nfs/root):

cp -avr /mnt/* /nfs/root/

Um die eingestellte IP zu nutzen, darf die Netzkonfiguration des Rootfs nicht gestartet werden:

rm /nfs/root/etc/rc.d/S10network.sh

Danach im Terminal am U-Boot-Prompt auf dem Hopper:

nfs 11000000 10.10.10.1:/nfs/root/boot/uImage
setenv bootargs root=nfs nfsroot=10.10.10.1:/nfs/root ip=10.10.10.23:10.10.10.1::255.255.255.0::eth0:none

Zu guter Letzt: bootm Thats all  ;)

(Die absolut angegebenen Pfade beziehen sich auf meine eigene Einstellung. Mein Hopper hängt an einer eigenen Netzwerkkarte.)

Solange der Hopper das rootfs gemounted hat, kann man es neu überschreiben auf dem Server, und der Hopper hat gleich die neue Version ohne ihn neustarten zu müssen. Funktioniert natürlich nicht mit dem Kernel.


Etwas einfacher geht es das rootfs direkt in das NFS-Root zu mounten, ohne Kopiererei. Dabei (TODO: Lösung wie es auch in tieferen Verzeichnissen funktioniert) sollte beachtet werden, daß nicht nach z. B. /nfs/root/ sondern nach /nfs gemounted wird, sonst gehts (noch) nicht. Der rest bleibt gleich, nur die Pfade muessen selbstverständlich angepasst werden. Wird der Hopper neugestartet, nachdem er via nfs gebootet hat, kann der Mountpunkt nur noch durch ein restart des Servers gelöst werden, sonst kommt die Meldung, daß er busy ist.


Booten via NFS Beispiel

Falls man sein Kernel zerschossen hat und auch ein altes U-Boot mit dem man kein neues image per tftp laden und vor allem einbrennen kann, hat die Chance per nfs zu booten um von dort dann ein rootfs per dd zu schreiben.

Hier ein Beispiel zum Booten per NFS:

U-Boot 1.3.1-gd2cbfd4b-dirty (Apr  1 2008 - 18:26:02)                           
                                                                               
U-Boot code: 00000000 -> 0000e820  data: 00014010 -> 0001a658                   
SDRAM: 64 MB at address 0x10000000                                              
Testing  SDRAM...OK                                                              
malloc: Using memory from 0x13fa5000 to 0x13fe5000                              
DMA: Using memory from 0x13fa1000 to 0x13fa5000                                 
Flash:  8 MB at address 0x00000000                                              
DRAM Configuration:                                                             
Bank #0: 10000000 64 MB                                                         
In:    serial                                                                   
Out:    serial                                                                   
Err:   serial                                                                   
Net:   macb0 
Press SPACE to abort autoboot in 3 seconds                                      
ICNova> setenv ipaddr 192.168.1.9                                               
ICNova> setenv serverip 192.168.1.2                                             
ICNova> nfs 11000000 192.168.1.2:/srv/nfs/boot/uImage                           
macb0: Starting autonegotiation...                                              
macb0: Autonegotiation complete                                                 
macb0: link up, 100Mbps full-duplex (lpa: 0x45e1)                               
Using macb0 device                                                              
File transfer via NFS from server 192.168.1.2; our IP address is 192.168.1.9    
Filename '/srv/nfs/boot/uImage'.                                                
Load address: 0x11000000                                                        
Loading: #################################################################      
         #################################################################      
         #################################################################      
         #############################################   
done                                                                            
Bytes transferred = 1226370 (12b682 hex)                                        
ICNova> setenv bootargs root=nfs nfsroot=192.168.1.2:/srv/nfs ip=192.168.1.9:192

.168.1.2::255.255.255.0::eth0:none

ICNova> boot                                                                    
Unknown command 'boot' - try 'help'                                             
ICNova>                                                                         
ICNova> boot                                                                    
partition changed to nor0,2                                                     
### JFFS2 loading '/boot/uImage' to 0x11000000                                  
Scanning JFFS2 FS: .| Unknown node type: e002 len 3029 offset 0x4f684           
Unknown node type: e002 len 3360 offset 0x6ffc0                                 
/ Unknown node type: e002 len 3357 offset 0x8fa78                               
....... done.                                                                   
### JFFS2 load complete: 1226370 bytes loaded to 0x11000000                     
## Booting image at 11000000 ...                                                
  Image Name:   Linux-2.6.25.10.atmel.2                                        
  Image Type:   AVR32 Linux Kernel Image (gzip compressed)                     
  Data Size:    1226306 Bytes =  1.2 MB                                        
  Load Address: 10000000                                                       
  Entry Point:  90000000          
  Verifying Checksum ... OK                                                    
  Uncompressing Kernel Image ... OK                                            
                                                                               
Starting kernel at 90000000 (params at 13fa5008)...