O U-Bboot não será autoboot, mas a inicialização manual funciona bem

1

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!

    
por Jeremy 14.11.2017 / 20:24

1 resposta

0

Depois de mais experiências, descobri que os WORKS seguintes:

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}

... Mas isso falha :

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

(formatado em várias linhas para maior clareza). Por "falha", quero dizer que, ao ligar, ele aguarda o tempo limite de inicialização automática, carrega o kernel e o dtb, depois é interrompido em "Iniciando o Kernel ..." e deve ser desligado ou reinicializado . No entanto, se eu pressionar uma tecla para interromper a inicialização automática, digite "boot" ou "execute bootcmd", ele inicializa bem (embora esteja executando exatamente o mesmo script).

Então, por alguma razão, usando uma instrução "if" no script bootcmd (mesmo que trivial) a quebra , embora eu não saiba por quê.

Esta não é uma ótima resposta, mas pelo menos eu consegui que funcionasse. O design original tinha a instrução if verificando o resultado de "mmc rescan", mas acho que se isso falhar, provavelmente parará com algum erro.

    
por 13.12.2017 / 22:18