Eu criei uma imagem para uma placa EVK Freescale iMX6 (baseada em ARM), usando o Buildroot. Ele arrancou bem de um cartão SD, e eu queria experimentar comandos de boot personalizados no U-Boot. Eu quero tornar a sequência de inicialização o mais simples e rápida possível, então simplifiquei algumas das verificações e testes feitos pelo U-Boot (por exemplo, removi a verificação de um script de inicialização e inicialização de rede).
Aqui está minha variável de inicialização bootcmd U-Boot (formatada para facilitar a leitura):
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
quando eu ligar a placa, após o "Hit qualquer chave para parar autoboot", eu recebo isso:
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 ...
Em seguida, ele é interrompido no estágio "Iniciando o kernel ...".
NO ENTANTO, se eu interromper o U-Boot pressionando enter, então (a partir do prompt do U-Boot) execute um destes comandos:
boot
ou
run bootcmd
Ele mostra exatamente as mesmas mensagens acima, mas o kernel inicia OK.
Eu comparei as saídas em ambos os casos e eles são idênticos até "Starting kernel". Eu também adicionei uma linha ao bootcmd para imprimir as variáveis env ( printenv
), e confirmei que as variáveis também são idênticas em ambos os casos. Aqui estão as últimas bootargs (impressas com echo ${bootargs}
) - estas também são as mesmas em ambos os casos:
console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait ro
Eu achei que o comando boot
acabou de executar bootcmd e que o processo de autoboot fez a mesma coisa se não foi interrompido.
Então, por que funciona se eu o interromper e executar boot
manualmente?
==== EDIT ====
Após comentários de serragem, fiz mais algumas experiências para esclarecer o problema.
1 / Adicionado 'earlyprintk' à compilação do kernel (opções de invasão do Kernel).
Isso fez com que o seguinte fosse impresso em uma inicialização BEM-SUCEDIDA:
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0x0
Em um boot FAILED, ele ainda pára em "Starting kernel ..." (nenhuma informação adicional do earlyprintk).
2 / Mais hacking do bootcmd para esclarecer o problema.
Aqui está a variável padrão "bootcmd env", criada por uma nova compilação (Nb: Normalmente, isso é tudo em uma linha, ou seja, "bootcmd = ...."; formatado aqui para maior clareza):
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
Isso funciona (ou seja, é iniciado automaticamente após o atraso de inicialização).
Aqui está minha modificação mínima:
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;
Tudo o que fiz foi remover a estrutura externa 'if' (se mmc reexplorar; então ...). Ele ainda chama "mmc rescan", que é bem-sucedido.
Observe que isso é salvo colocando-se o item acima em uma linha ('xxxx') e usando:
setenv bootcmd 'xxxxx'
saveenv
Isso faz com que a placa seja interrompida em "Iniciando o kernel ...", mas se eu interromper a inicialização automática, digite o prompt u-boot e use "boot", ele inicializa bem.
Eu posso voltar ao bootcmd original e ele funciona corretamente (o autoboot é OK), então acho que o método para mudar a variável está OK.
Eu vi uma coisa estranha em um ponto quando eu mudei para a minha versão:
Starting kernel ...
resetting ...
[Board Rebooted itself!]
U-Boot 2016.03 (Nov 16 2017 - 07:08:36 +1300)
[Auto-boot]
Starting kernel ...
[Hang.]
A partir daí, voltava a ser interrompido, a menos que eu interrompesse o boot e entrasse no comando "boot".
Bug in u-boot? variáveis de ambiente u-boot de alguma forma corrompidas?
Nb: Este não é um grande problema no momento, mas acho que poderíamos economizar alguns ms se livrando da inútil busca por um script de boot que eu sei que não existe, e no futuro poderíamos ter motivos para personalizar a inicialização por algum outro motivo e eu gostaria de saber que isso poderia ser feito de forma previsível!