AVR32 Grasshopper
Über das Board
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
- Schaltplan PDF
- Howto für die ersten Schritte
- Tutorial: GPIOs über ein Webinterface steuern (Dateien dazu)
- OpenWrt für den Grasshopper (Infos und Sourcecode dazu)
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)...