U-Bboot startet nicht automatisch, aber das manuelle Booten funktioniert einwandfrei

501
Jeremy

Ich habe mit Buildroot ein Image für ein Freescale iMX6 EVK-Board (ARM-basiert) erstellt. Es wurde gut von einer SD-Karte gebootet, und ich wollte mit benutzerdefinierten Boot-Befehlen in U-Boot experimentieren. Ich möchte die Startsequenz so schlank und schnell wie möglich gestalten, daher habe ich einige der von U-Boot durchgeführten Prüfungen und Tests optimiert (z. B. die Überprüfung auf ein Startskript und Netzwerkstart entfernt).

Hier ist meine bootcmd U-Boot- Env -Variable (formatiert zum leichteren Lesen):

bootcmd= echo Booting from SD...; mmc dev $; if mmc rescan; then setenv mmcroot /dev/mmcblk1p2 rootwait ro; setenv bootargs console=$,$ root=$; fatload mmc $:$ $ $; setenv fdt_file imx6ull-14x14-evk.dtb; fatload mmc $:$ $ $; bootz $ - $; else  echo Boot FAILED: Couldnt find kernel or dtb; fi 

Wenn ich das Board einschalte, nach dem Drücken einer beliebigen Taste, um den automatischen Start zu stoppen, erhalte ich Folgendes:

Hit any key to stop autoboot: 0  Booting from SD... switch to partitions #0, OK mmc1 is current device reading zImage 4652504 bytes read in 369 ms (12 MiB/s) reading imx6ull-14x14-evk.dtb 33755 bytes read in 30 ms (1.1 MiB/s) Kernel image @ 0x80800000 [ 0x000000 - 0x46fdd8 ] ## Flattened Device Tree blob at 83000000 Booting using the fdt blob at 0x83000000 Using Device Tree in place at 83000000, end 8300b3da  Starting kernel ... 

Es hängt dann im Stadium "Starting Kernel ...".

Wenn ich jedoch U-Boot durch Drücken der Eingabetaste unterbreche, führen Sie (an der U-Boot-Eingabeaufforderung) einen der folgenden Befehle aus:

boot 

oder

run bootcmd 

Es zeigt genau die gleichen Nachrichten wie oben, aber der Kernel startet OK.

Ich habe die Ausgaben in beiden Fällen verglichen und sie sind bis "Starting Kernel" identisch. Ich habe auch eine Zeile zu bootcmd hinzugefügt, um die Umgebungsvariablen ( printenv) auszudrucken, und habe bestätigt, dass die Variablen in beiden Fällen auch identisch sind. Hier sind die endgültigen Bootargs (gedruckt mit echo $) - auch diese sind in beiden Fällen gleich:

console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait ro 

Ich dachte, dass der bootBefehl gerade bootcmd ausgeführt hat und dass der Autoboot-Vorgang dasselbe tat, wenn er nicht unterbrochen wurde.

Warum funktioniert es dann, wenn ich es unterbreche und bootmanuell ablaufe?

==== BEARBEITEN ====

Nach den Bemerkungen von Sägemehl habe ich einige weitere Experimente durchgeführt, um das Problem zu klären.

1 / 'earlyprintk' zum Kernel-Build hinzugefügt (Optionen für Kernel-Hacker).

Dies führte dazu, dass Folgendes auf einem SUCCESSFUL-Startvorgang gedruckt wurde:

Starting kernel ... Uncompressing Linux... done, booting the kernel. Booting Linux on physical CPU 0x0 

Bei einem FAILED-Boot stoppt es immer noch bei "Starting Kernel ..." (keine zusätzlichen Informationen von earlyprintk).

2 / Weitere Hacken von bootcmd, um das Problem zu klären.

Hier ist die voreingestellte "bootcmd" -Env-Variable, die von einem neuen Build erstellt wird (Anmerkung: Normalerweise ist dies alles in einer Zeile, dh "bootcmd = ...."; hier ist der Übersichtlichkeit halber formatiert):

run findfdt; mmc dev $; mmc dev $; if mmc rescan; then  if run loadbootscript; then run bootscript; else  if run loadimage; then run mmcboot; else run netboot; fi; fi; else  run netboot; fi 

Dies funktioniert (dh das automatische Booten nach der Bootverzögerung).

Hier ist meine minimale Modifikation:

run findfdt; mmc dev $; mmc dev $; mmc rescan; if run loadbootscript; then run bootscript; else  if run loadimage; then run mmcboot; else run netboot; fi; fi; 

Alles, was ich tat, war, die äußere 'if'-Struktur zu entfernen (wenn mmc erneut scannt; dann ...). Es nennt sich immer noch "mmc rescan", was gelingt.

Beachten Sie, dass dies gespeichert wird, indem Sie das Obige in eine Zeile ('xxxx') schreiben und Folgendes verwenden:

setenv bootcmd 'xxxxx' saveenv 

Dies führt dazu, dass die Karte bei "Starting Kernel ..." hängt, aber wenn ich den Auto-Start unterbreche, gebe die U-Boot-Eingabeaufforderung ein und benutze "Boot".

Ich kann wieder zum ursprünglichen bootcmd wechseln und es funktioniert korrekt (Autoboot ist OK), also denke ich, dass die Methode zum Ändern der Variablen OK ist.

Ich habe etwas seltsames gesehen, als ich es auf meine Version umgestellt habe:

Starting kernel ... resetting ...  [Board Rebooted itself!]  U-Boot 2016.03 (Nov 16 2017 - 07:08:36 +1300)  [Auto-boot]  Starting kernel ...  [Hang.] 

Von da an war es wieder so lange, bis ich das Booten unterbreche und den Befehl "boot" eingebe.

Fehler in u-boot U-Boot-Umgebungsvariablen irgendwie beschädigt?

Nb: Dies ist momentan kein großes Problem, aber ich denke, wir könnten ein paar MS sparen, indem wir die sinnlose Suche nach einem Boot-Skript loswerden, von dem ich weiß, dass es nicht da ist, und in der Zukunft könnten wir den Booten anpassen aus einem anderen Grund und ich würde gerne wissen, dass es vorhersehbar sein könnte!

1
Ihre Annahmen zu den CLI-Startbefehlen und zum automatischen Booten sind korrekt. Was hast du * "gestrafft" * und * "entfernt" *? War das alles in der Umgebung? Es gibt einen Unterschied zwischen den beiden Szenarien, einen Zeitunterschied. Sie können versuchen, die ** bootdelay ** zu erhöhen, um die zusätzliche Zeit zum Abbruch des automatischen Bootens zu simulieren und "boot" + Enter einzugeben. Verfügt Ihr Kernel über eine stumme oder ausführliche Dekomprimierung (siehe https://stackoverflow.com/questions/46930346/uncompressing-is-not-happening-with-zimage-while-bootingupwith-u-boot/47009714#47009714) ? sawdust vor 6 Jahren 0
Ich habe die "Bootdelay" auf 6 Sekunden gesetzt, aber das hat nicht geholfen. Für das "Rationalisieren" habe ich die Standardvariable "bootcmd" aufgehoben und Bits entfernt, die ich nicht verwendet habe (zB nach einem Boot-Skript suchen, von dem ich weiß, dass es nicht da ist). In der Theorie sollte es funktional genauso sein wie zuvor. Ich konnte verstehen, ob beim Entnehmen ein Fehler aufgetreten ist, aber ich kann nicht herausfinden, warum es funktioniert, wenn ich es manuell mit dem Befehl "boot" aufrufe. Könnte es einen anderen Unterschied als die Verzögerung geben? Jeremy vor 6 Jahren 0
Der Kernel verwendet die unbeaufsichtigte Komprimierung, da er direkt vom Starten des Kernels bis zum Booten von Linux auf der physischen CPU 0x0 (wenn ich den Boot-Vorgang manuell ausführe) geht. Jeremy vor 6 Jahren 0
Wenn ** earlyprintk ** bereits im Kernel konfiguriert ist, aktivieren Sie es in der Kernel-Befehlszeile über die Variable ** bootargs **. Können Sie den Kernel neu aufbauen, damit Sie die Komprimierung ausführlich erklären können? Das könnte helfen zu sagen, wie weit die Boot-Sequenz fortgeschritten ist (da dies ein Zwischenschritt ist, bevor der Kernel startet), wenn Sie mit ** earlyprintk ** nichts erhalten. sawdust vor 6 Jahren 0
Um klar zu sein, AutoBoot funktionierte früher einwandfrei (mit den gleichen U-Boot- und Kernel-Images), bevor Sie das "Streamlining" * durchgeführt haben. sawdust vor 6 Jahren 0
Ja, der Autoboot funktionierte gut - obwohl es einige Fehler gab, zum Beispiel boot.scr nicht zu finden (erwartet). Ich habe dies gerade bestätigt (setzen Sie das SD-Karten-Image auf den Standard zurück, testen Sie das Booten und wiederholen Sie dann die oben genannten Änderungen). Ich habe "earlyprintk" in diesem Kernel-Build nicht aktiviert, aber es hört sich interessant an, also werde ich versuchen, es neu aufzubauen. Jeremy vor 6 Jahren 0
Lassen Sie uns [diese Diskussion im Chat fortsetzen] (http://chat.stackexchange.com/rooms/68772/discussion-between-jeremy-and-sawdust). Jeremy vor 6 Jahren 0
Entschuldigung, ich habe Ihren Beitrag nicht sorgfältig genug gelesen. Da Sie sich nach dem "Hang" durch Eingabe der Eingabetaste erholen und zur U-Boot-Eingabeaufforderung zurückkehren können, bedeutet dies, dass U-Boot nie versucht hat, den Kernel zu booten; das ist eine einfache Fahrkarte. Der Hang ist irgendwo (in U-Boot), während er ** bootcmd ** ausführt, bevor der (letzte) Sprung zum Kernel erfolgt. Übrigens ist das nachgestellte Semikolon in Ihrem modifizierten ** bootcmd ** nicht erforderlich. Das Semikolon ist ein Befehlstrennzeichen und kein Abschlusszeichen. sawdust vor 6 Jahren 0
Entschuldigung, das habe ich nicht gemeint. Ich kann den Hang NICHT entkommen, sobald er passiert ist (hing an "Starting Kernel ..."). Ich meinte, dass ich einen Neustart durchführen kann, "Enter" drücken, um den Autostart zu unterbrechen, dann "Boot" manuell ausführen, und es funktioniert gut. Wenn ich das Auto-Boot-Timeout beendet habe, versucht es zu booten und hängt dann wie beschrieben (und kann nur mit einem Reset / Aus- / Wiedereinschalten behoben werden). Ich habe versucht, das zusätzliche Semikolon in meinem Startbefehl zu entfernen (gut erkannt!), Aber das hat keinen Unterschied gemacht. Jeremy vor 6 Jahren 0

1 Antwort auf die Frage

0
Jeremy

Nach weiteren Experimenten habe ich entdeckt, dass die folgenden FUNKTIONEN :

bootcmd= setenv fdt_file imx6ull-14x14-evk.dtb;  setenv bootargs console=$,$ root=$;  mmc dev $; mmc rescan; fatload mmc $:$ $ $;  fatload mmc $:$ $ $;  bootz $ - $ 

... aber diese Fehler :

bootcmd= setenv fdt_file imx6ull-14x14-evk.dtb;  setenv bootargs console=$,$ root=$;  mmc dev $; if true; then  mmc rescan;  fatload mmc $:$ $ $;  fatload mmc $:$ $ $;  bootz $ - $;  else  echo Boot FAILED: Couldnt find kernel or dtb; fi 

(Zur besseren Übersichtlichkeit auf mehrere Zeilen formatiert). Mit "nicht bestanden" meine ich, dass es beim Einschalten auf das Auto-Boot-Timeout wartet, den Kernel und die dtb lädt, dann bei "Starting Kernel ..." hängt und ausgeschaltet oder zurückgesetzt werden muss . Wenn ich jedoch eine Taste drücke, um den Autostart zu unterbrechen, dann "boot" oder "run bootcmd" eingeben, wird der Bootvorgang ordnungsgemäß gestartet (obwohl genau das gleiche Skript ausgeführt wird).

Aus irgendeinem Grund bricht die Verwendung einer "if" -Anweisung im bootcmd-Skript (sogar ein triviales), obwohl ich nicht weiß, warum.

Dies ist keine großartige Antwort, aber zumindest habe ich es zum Laufen gebracht. Das ursprüngliche Design hatte die if-Anweisung, um das Ergebnis von "mmc rescan" zu überprüfen, aber ich denke, wenn dies fehlschlägt, wird es wahrscheinlich mit einem Fehler aufhören.