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 boot
commande 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 boot
manuellement?
==== 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!
la source
Réponses:
Après d' autres expériences, je l' ai découvert que les suivantes ŒUVRES :
... Mais cela échoue :
(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.
la source