Teil 2: Bau eines Mainline u-Boot für RIoTboard

Post von selsinork in RIoTboard, 28. April 2014, 21:05:00

Dies ist der zweite von mehreren Posts zum RIoTboard. Die anderen Beiträge können über die folgenden Links aufgerufen werden:

Teil 1: Boot-Schalter am RIoTboard

Teil 3: Bau eines Mainline Linux-Kernel für RIoTboard

Teil 4: Pinmux-Einstellungen für RIoTboard Erweiterungssteckverbinder

Teil 5: Bau eines Debian armhf Root-Dateisystem für RIoTboard

Teil 6: Debian auf RIoTboard. Endmontage.

 

Hallo zu Teil 2 meiner Anleitung zum Bau einer aktuellen u-Boot-Version.  Später erkläre ich in einem anderen Post, wie man einen 3.15-rc-Kernel der allerneuesten Art baut. Am Ende soll eine voll bootfähige Debian-Installation für das RIoTboard stehen.

 

Auf dem RIoTboard ist standardmäßig u-Boot 2009.08 installiert. Diese Version kam im August 2009 heraus, lange vor dem i.MX 6-SoC, dem Herzstück des RIoTboard und noch länger vor dem RIoTboard selbst.

Ganz schön alte Version. Wundert sich darüber noch jemand  außer mir?

 

In diesem Post baue ich ein u-Boot auf Grundlage von Version 2014.04 vom 14. April 2014: Gmane-Website: [ANN]  U Boot v2014.04 verfügbar

 

Es geht gleich gut los: v2014.04 ist nicht mit dem RIoTboard kompatibel. Die Patches von Eric Bénard Gmane-Website: PATCH v2 4/8  – Support für neue Boards RiOTboard und MarSBoard kamen leider zu spät, um in Version 2014.04 aufgenommen zu werden.  Meine Hoffnung war, dass die Patches bald nach der Veröffentlichung zusammengeführt werden und ich dann auf eine offizielle Version verweisen könnte. Aber das dauert zu lange.  Die Leute hier wollen jetzt loslegen, nicht erst in sechs Monaten.

 

Also, los geht's!  Weil ich den Code auf einem Sabre-Lite-Board mit i.MX 6 Quad-Core-Prozessor erstelle, werde ich nicht cross-kompilieren. Dadurch sparen wir uns unnötige Komplexität. Außerdem schafft Cross-Kompilieren stets Verwirrung. Unsere Arbeit bleibt somit klar nachvollziehbar.

 

Erstellen Sie zuerst ein neues Verzeichnis:

root@sl3:~# mkdir riot
root@sl3:~# cd riot

 

Jetzt klonen Sie mein u-Boot-Repository auf Github. Es enthält die Patches von Eric sowie ein paar Fixes und Bereinigungen von mir. Auf die Gründe dafür komme ich später zu sprechen.

root@sl3:~/riot# git clone -b riotboard2 git://github.com/selsinork/u-boot.git
Cloning into 'u-boot'...
remote: Counting objects: 253477, done.
remote: Compressing objects: 100% (46120/46120), done.
remote: Total 253477 (delta 203284), reused 253299 (delta 203106)
Receiving objects: 100% (253477/253477), 60.65 MiB | 373.00 KiB/s, done.
Resolving deltas: 100% (203284/203284), done.
Checking connectivity... done.
Checking out files: 100% (7987/7987), done.

Wenn Sie nur die Patches von Eric wollen, schreiben Sie in der git clone-Zeile an Stelle von „riotboard2“  „embest“.

 

Wechseln Sie jetzt ins u-Boot-Verzeichnis und prüfen Sie, ob das richtige Verzeichnis geöffnet ist:

root@sl3:~/riot# cd u-boot
root@sl3:~/riot/u-boot# git branch
* riotboard2

 

Jetzt kann's losgehen. Wir konfigurieren u-Boot für das RIoTboard.

root@sl3:~/riot/u-boot# make riotboard_config
Configuring for riotboard - Board: embestmx6boards, Options:
IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s1g.cfg,MX6S,DDR_MB=1024,ENV_IS_IN_MMC

 

Wenn bislang alles geklappt hat, können wir jetzt u-Boot selbst kompilieren. Der nachfolgende Code ist nicht vollständig. Scrollen Sie der Einfachheit halber einfach nach unten.

Weil mein Buildcomputer einen Quad-Core-Prozessor hat, kann ich mit dem Befehl „-j 4“ u-Boot parallel auf bis zu vier Kernen gleichzeitig erstellen und ich komme damit etwas schneller voran. Wenn Ihr Computer nur 1 Prozessorkern hat, lassen Sie „-j 4“ einfach aus.

root@sl3:~/riot/u-boot# make -j 4
  GEN     include/autoconf.mk.dep
  GEN     include/autoconf.mk
  CHK     include/config/uboot.release
  CHK include/generated/timestamp_autogenerated.h
  UPD include/generated/timestamp_autogenerated.h

 

[...]

 

CC      net/ping.o
  CC      net/tftp.o
  LD      net/built-in.o
  LD      lib/built-in.o
  CC examples/standalone/stubs.o
  CC examples/standalone/hello_world.o  
  LD examples/standalone/libstubs.o
  LD examples/standalone/hello_world
  OBJCOPY examples/standalone/hello_world.srec
  OBJCOPY examples/standalone/hello_world.bin
  LD      u-boot
  OBJCOPY u-boot.bin
  OBJCOPY u-boot.srec
  CFGS board/boundary/nitrogen6x/nitrogen6s1g.cfg.cfgtmp
  MKIMAGE u-boot.imx

 

Sehen wir uns an, was wir programmiert haben:

root@sl3:~/riot/u-boot# ls -l u-boot.imx
-rw-r--r-- 1 root root 330752 Apr 28 18:09 u-boot.imx

 

Alles klar, das wäre erledigt.

 

Jetzt können wir  den Code ausprobieren.

Ich fange mit einer microSD-Karte mit 4 GB an. Ob auf der Karte etwas drauf ist, spielt jetzt keine Rolle, denn als Erstes löschen wir alles von der Karte.

 

root@sl3:~/riot/u-boot# dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 17,2134 s, 6,1 MB/s

Die microSD-Karte wird im Sabre-Lite microSD-Steckplatz als /dev/mmcblk0 angezeigt. Der dd-Befehl schreibt auf die ersten 100 MB nur Nullen. Das reicht, um die Partitionstabellen und sämtliche Daten am Beginn der Karte zu löschen. Die Karte ist damit praktisch leer.

Jetzt können wir die neu erstellte u-boot.imx-Datei auf die Karte schreiben.

root@sl3:~/riot/u-boot# dd if=u-boot.imx of=/dev/mmcblk0 bs=1k seek=1
323+0 records in
323+0 records out
330752 bytes (331 kB) copied, 0,116274 s, 2,8 MB/s

Die wirklich wichtigen Befehle stehen am Ende der dd-Befehlszeile.

bs=1k legt die Blockgröße auf 1.024 Byte fest

seek=1 bedeutet, dass wir * Blockgröße-Bytes am Beginn der microSD-Karte auslassen.

 

Das ist nötig, weil der Boot-ROM des i.MX 6 bei 1.024 Bytes damit beginnt, Daten zu lesen.  Das Datenformat ist sehr genau festgelegt. Stimmt das Format nicht, behandelt der Boot-ROM die Daten als ungültig und springt weiter.  Nähere Angaben zum Format entnehmen Sie dem Referenzhandbuch zum Prozessor: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX6S&fpsp=1&tab=Documentation_Tab. Öffnen Sie Datei IMX6SDLRM.pdf und lesen Sie Kapitel 8.

 

Die genauen Einzelheiten sind für uns nicht so wichtig. Wichtig ist, dass u-Boot sich darum kümmert.

 

Die Daten auf der Karte müssten in etwa so aussehen:

root@sl3:~/riot/u-boot# hexdump -n 1040 -C /dev/mmcblk0
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  d1 00 20 40 00 00 80 17  00 00 00 00 2c f4 7f 17  |.. @........,...|
00000410

Wir sehen, dass die ersten 1.024 Byte (bis 400 hexadezimal) Nullen sind und danach u-Boot startet.

 

Sonst ist nichts auf der Karte. Also können wir u-Boot selbst zur Ausführung bringen und so nachweisen, dass es funktioniert.

 

Stellen Sie die Boot-Schalter so, dass das Board von der microSD-Karte startet. Wer den vorherigen Post nicht gelesen hat: Diese Konfiguration ist dafür nötig.

 

Wenn Sie eine SD-Karte verwenden möchten,  lesen Sie den vorherigen Post mit den Details zu den Boot-Schaltern: Teil 1: Boot-Schalter am RIoTboard

 

Setzen Sie die Karte ein (serielle Konsole muss angeschlossen sein) und schalten Sie ein.

U-Boot 2014.07-rc3-00065-ge606136-dirty (Jun 14 2014 - 13:33:50)

 

CPU:   Freescale i.MX6SOLO rev1.1 at 792 MHz
Reset cause: POR
Board: RIoTboard
I2C:   ready
DRAM:  1 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
*** Warning - bad CRC, using default environment

 

No panel detected: default to HDMI
Display: HDMI (1024x768)
In:    serial
Out:   serial
Err:   serial
Net:   FEC [PRIME]
Warning: failed to set MAC address

 

Hit any key to stop autoboot: 0
MMC: no card present
mmc0(part 0) is current device
MMC: no card present
** Bad device mmc 0 **
mmc1 is current device
** No partition table - mmc 1 **
mmc2(part 0) is current device
Failed to mount ext2 filesystem...
** Unrecognized filesystem type **
## Error inserting "stdout" variable, errno=22

 

bootscript not found

 

serial console at 115200, 8N1

 

=>

 

Weil sonst nichts auf der Karte ist (nicht einmal eine Partition), überrascht es nicht, dass wir nicht weiter kommen. Kein Problem, denn als Version wird 2014.04 angezeigt. Wir haben also nachgewiesen, dass wir die neueste u-Boot-Version bauen können und dass sie funktioniert.

 

Wenn Sie keine serielle Konsole haben, sollte auf Monitoren mit HDMI-Anschluss oder auf LCD8000-97C das Logo von Denx Software Engineering und ein String mit der u-Boot-Version zu sehen sein. Letzteres bestätigt, dass u-Boot geladen wurde.

 

Das war's.  Nächstes Mal bauen wir einen Mainline-Kernel für das RIoTboard.

 

Update vom 31. Mai 2014: Ich habe ein paar zusätzliche Commits auf die Github-Verzweigung gestellt. Die einzelnen Schritte zur Erstellung eines u-Boot bleiben gleich. Wenn Sie anschließend einen 3.15-rc*-Kernel bauen möchten, pullen Sie am besten die Veränderungen und erstellen ein neues u-Boot, weil eines der Updates den standardmäßigen Namen der Gerätestruktur an den Namen anpasst, der im Kernel verwendet wird.

Update vom 14. Juni 2014: Ich habe diesen Post aktualisiert, weil sich zuletzt ein paar Änderungen ergeben haben. Wenn Sie bereits u-Boot für das RIoTboard programmiert haben, sollten Sie sich ein paar Minuten für die neuere Konfiguration nehmen. Denken Sie aber daran, dass auch in der neuen Konfiguration /bootscript angepasst werden muss.