U-Bboot ne démarre pas automatiquement mais le démarrage manuel fonctionne bien

1

J'ai construit une image pour une carte Freescale iMX6 EVK (basée sur ARM), à l'aide de Buildroot. Il a bien démarré avec une carte SD et je voulais expérimenter des commandes de démarrage personnalisées dans U-Boot. Je souhaite que la séquence de démarrage soit aussi légère et rapide que possible, aussi j’ai rationalisé certains contrôles et tests effectués par U-Boot (par exemple, suppression de la vérification du script de démarrage et du démarrage réseau).

Voici ma variable d'environnement bootcmd U-Boot (formatée pour une lecture facile):

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

quand j'allume le tableau, après le "Appuyez sur une touche pour arrêter l'autoboot", je reçois ceci:

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 ...

Il se bloque ensuite à l'étape "Noyau de démarrage ...".

CEPENDANT, si j'interromps U-Boot en appuyant sur Entrée, alors (à partir de l'invite de U-Boot), exécutez l'une de ces commandes:

boot

ou

run bootcmd

Il affiche exactement les mêmes messages que ci-dessus, mais le noyau démarre ensuite correctement.

J'ai comparé les sorties dans les deux cas et elles sont identiques jusqu'au "Noyau de démarrage". J'ai également ajouté une ligne à bootcmd pour afficher les variables env ( printenv) et confirmé que les variables sont également identiques dans les deux cas. Voici les arguments finaux (imprimés avec echo ${bootargs}) - ceux-ci sont également les mêmes dans les deux cas:

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

Je pensais que la bootcommande venait d'exécuter bootcmd et que le processus de démarrage automatique faisait la même chose s'il n'était pas interrompu.

Alors, pourquoi ça marche si je l’interromps et je cours bootmanuellement?

==== EDIT ====

Suite aux commentaires de la sciure de bois, j'ai fait quelques expériences supplémentaires pour clarifier le problème.

1 / Ajout de 'earlyprintk' à la construction du noyau (options de piratage du noyau).

Cela a provoqué l'impression suivante sur un démarrage SUCCESSFUL:

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

Sur un démarrage FAILED, il s’arrête toujours à "Démarrage du noyau ..." (pas d’informations supplémentaires de earlyprintk).

2 / Nouveau piratage de bootcmd pour clarifier le problème.

Voici la variable env "bootcmd" par défaut, créée par une nouvelle construction (Nb: Normalement, tout cela est sur une seule ligne, c'est-à-dire "bootcmd = ...."; formaté ici pour plus de clarté):

run findfdt;
mmc dev ${mmcdev};
mmc dev ${mmcdev};
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

Cela fonctionne (c.-à-d. Démarrage automatique après le délai de démarrage).

Voici ma modification minimale:

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

Tout ce que j'ai fait est de supprimer la structure externe 'if' (si mmc rescan; alors ...). Il appelle toujours "mmc rescan", qui réussit.

Notez que ceci est sauvegardé en mettant ce qui précède sur une ligne ('xxxx') et en utilisant:

setenv bootcmd 'xxxxx'
saveenv

Cela a pour effet de bloquer la carte au démarrage du noyau ..., mais si j'interromps le démarrage automatique, entrez l'invite u-boot, puis utilisez "boot".

Je peux revenir au bootcmd d'origine et cela fonctionne correctement (le démarrage automatique est OK), donc je pense que la méthode de modification de la variable est OK.

J'ai vu une chose étrange à un moment donné lorsque j'ai changé de version:

Starting kernel ...
resetting ...

[Board Rebooted itself!]

U-Boot 2016.03 (Nov 16 2017 - 07:08:36 +1300)

[Auto-boot]

Starting kernel ...    
[Hang.]

À partir de ce moment-là, il était de nouveau suspendu sauf si j'interrompais le démarrage et que j'entrais dans la commande "boot".

Bug dans U-Boot? Les variables d'environnement u-boot sont-elles corrompues?

Nb: Ce n'est pas un problème majeur pour le moment, mais je pense que nous pourrions économiser quelques ms en nous débarrassant de la recherche inutile d'un script de démarrage qui, à ce que je sache, n'existe pas et, à l'avenir, nous pourrions avoir des raisons de personnaliser le démarrage. pour une autre raison et j'aimerais savoir que cela pourrait être fait de manière prévisible!

Jeremy
la source
Vos hypothèses concernant les commandes de démarrage de la CLI et l'autoboot sont correctes. Qu'avez-vous "rationalisé" et "supprimer" ? Est-ce que tout cela était dans l'environnement? Il y a une différence entre les deux scénarios, une différence dans le temps. Vous pouvez essayer d’augmenter le délai d’ initialisation pour simuler le temps supplémentaire nécessaire pour annuler l’auto-démarrage et taper "boot" + Entrée. Votre noyau a-t-il une décompression silencieuse ou commentée (voir stackoverflow.com/questions/46930346/… )?
sciure de bois
J'ai réglé le "bootdelay" à 6 secondes, mais cela n'a pas aidé. Pour "rationaliser", ce que j’ai fait, c’est de décocher la variable d’env "bootcmd" par défaut et de supprimer les bits que je n’utilisais pas (par exemple, la recherche d’un script de démarrage dont je sais qu’il n’existe pas). Il devrait être fonctionnellement le même que précédemment, en théorie. Je pouvais comprendre s'il y avait une erreur lors de ma désinscription, mais ce que je ne comprends pas, c'est pourquoi cela fonctionne lorsque je l'appelle manuellement avec la commande "boot". Pourrait-il y avoir une autre différence que le délai?
Jeremy
Le noyau utilise une décompression silencieuse, car il passe directement de "Démarrage du noyau ..." à "Amorcer Linux sur un CPU physique 0x0" (lorsque je lance manuellement le démarrage).
Jeremy
Si earlyprintk est déjà configuré dans le noyau, activez-le dans la ligne de commande du noyau via la variable bootargs . Pouvez-vous reconstruire le noyau de manière à avoir une décompression détaillée? Cela pourrait aider à déterminer l'état d'avancement de la séquence d'amorçage (puisqu'il s'agit d'une étape intermédiaire avant le démarrage du noyau) si rien ne se passe avec earlyprintk .
sciure de bois
Pour être clair, autoboot fonctionnait très bien (avec les mêmes images de U-Boot et du noyau) avant la "rationalisation" ?
sciure de bois

Réponses:

0

Après d' autres expériences, je l' ai découvert que les suivantes ŒUVRES :

bootcmd=
setenv fdt_file imx6ull-14x14-evk.dtb; 
setenv bootargs console=${console},${baudrate} root=${mmcroot}; 
mmc dev ${mmcdev};
mmc rescan;
fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}; 
fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}; 
bootz ${loadaddr} - ${fdt_addr}

... Mais cela échoue :

bootcmd=
setenv fdt_file imx6ull-14x14-evk.dtb; 
setenv bootargs console=${console},${baudrate} root=${mmcroot}; 
mmc dev ${mmcdev};
if true; then 
 mmc rescan; 
 fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}; 
 fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}; 
 bootz ${loadaddr} - ${fdt_addr}; 
else 
 echo Boot FAILED: Couldnt find kernel or dtb;
fi

(Formaté sur plusieurs lignes pour plus de clarté). Par "échec", je veux dire que lors de la mise sous tension, il attend le délai d’initialisation automatique, charge le noyau et le fichier dtb, puis se bloque à "Démarrage du noyau ..." et doit être mis hors tension ou réinitialisé . Cependant, si j'appuie sur une touche pour interrompre le démarrage automatique, tapez "boot" ou "run bootcmd", il démarre correctement (même s'il exécute exactement le même script).

Donc, pour une raison quelconque, utiliser une instruction "if" dans le script bootcmd (même trivial) la casse , bien que je ne sache pas pourquoi.

Ce n'est pas une bonne réponse, mais au moins je l'ai mise au travail. La conception originale contenait l'instruction if qui vérifiait le résultat de "mmc rescan", mais je suppose que si cela échoue, il y aura probablement une erreur quand même.

Jeremy
la source