U-Boot na Beaglebone
Introdução
Dando prosseguimento na minha saga por bootloader para embarcados, vou postar meus passos para usar o U-Boot com SD-Card.
Baseado no curso da Udemy ->
Embedded Linux Step by Step Using Beaglebone Black
Baixando
O repositório oficial do U-Boot é o da denx:
git clone https://source.denx.de/u-boot/u-boot.git
eles também mantém um espelho no github
git clone https://github.com/u-boot/u-boot.git
Como a maioria das placas, os criadores portaram o U-Boot para a Beaglebone
git clone https://github.com/beagleboard/u-boot.git
Buildando
Primeiro, foi preciso baixar o toolchain
sudo apt install gcc-arm-linux-gnueabihf
Tanto o U-Boot mainline quanto o U-Boot beaglebone possuem o mesmo nome de arquivo para as configurações padrões:
am335x_evm_defconfig
No meu caso, eu utilizei o U-boot mainline.
Dessa forma, para criar o .config
usei o comando:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- am335x_evm_defconfig O=out/
OBS: para limpar o ambiente compilação, basta usar o comando
make distclean
Por fim, para gerar as imagens, utilizei o comando:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 O=out/
OBS: -j é o parâmetro que define a quantidade de núcleos de processador utilizado no processo de compilação.
Se tudo ocorrer bem, uma mensagem semelhante a essa deve aparecer:
MKIMAGE MLO
MKIMAGE MLO.byteswap
DTC arch/arm/dts/am335x-pdu001.dtb
DTC arch/arm/dts/am335x-chiliboard.dtb
DTC arch/arm/dts/am335x-sl50.dtb
DTC arch/arm/dts/am335x-base0033.dtb
DTC arch/arm/dts/am335x-guardian.dtb
DTC arch/arm/dts/am335x-wega-rdk.dtb
DTC arch/arm/dts/am335x-regor-rdk.dtb
SHIPPED dts/dt.dtb
MKIMAGE u-boot.img
CAT u-boot-dtb.bin
COPY u-boot.dtb
MKIMAGE u-boot-dtb.img
COPY u-boot.bin
Mostrando que os binários MLO
e u-boot.img
foram criados.
Utilizando
Com as imagens geradas, precisamos copiá-las para o cartão SD. Para isso, devemos criar, no cartão SD, uma partição fat 16
que irá abrigar o MLO
, u-boot.img
e também a imagem do kernel (200 MB são suficientes). É necessário também marcar a flag boot
depois da criação da partição, para que a placa carregue o bootloader.
Por fim, é só colocar o cartão SD na beaglebone, segurar o botão S2
e ligar a placa.
Estágios
A forma como a Texas Instruments desenvolveu o SOC AM335x (mais detalhes), se faz necessário que o processo de boot da placa precise de 3 estágios
- BROM - que é definido pela própria Texas Instruments (não é possível modifica-lo)
- SPL ou Secondary Program Loader - No U-boot chamado de
MLO
ou Memory LOader - O U-boot em si (
u-boot.img
)
Para maiores detalhes, checar o Technical Reference manual (TRM).
No TRM também é possível verificar que existe a possibilidade de fazer o boot sem um sistema de arquivos no SD-Card/eMMC, na seção
26.1.8.5.5 MMC/SD Read Sector Procedure in Raw Mode
BROM
O BROM faz várias checagens no hardware, mas o que nos interessa nesse estágio é o que ele busca após finalizar sua execução. O TRM encontramos a seguinte informação
The next task for the ROM Code is to find the booting file named “MLO” inside
the Root Directory of the FAT12/16/32 file system. The file is not searched
in any other location.
Ou seja, no nosso SD-Card/eMMC precisamos de uma partição do tipo FAT12, FAT16 ou FAT32. Dentro da partição, um arquivo chamado MLO
.
MLO
Resumidamente, o MLO é responsável por "habilitar" a memória ram (DRAM) e carregar a imagem do U-Boot para a mesma.
Um primeiro teste foi colocar apenas o MLO
no SD-Card (sem o u-boot.img
) e ver o que aconteceria. E essa foi a mensagem que retornou:
U-Boot SPL 2022.04-rc3-00052-g6d3c46ed0e (Sep 11 2022 - 11:17:49 -0400)
Trying to boot from MMC1
spl_load_image_fat: error reading image u-boot.img, err - -2
SPL: failed to boot from all boot devices
### ERROR ### Please RESET the board ###
OBS: Para visualizar o logs de boot, cheque esse post
Uma mensagem dizendo não foi possível carregar o u-boot.img
. Vale ressaltar que esses logs são do MLO
, podemos observar referências ao SPL nos logs.
Isso já mostra os primeiros sinais de vida da Beaglebone, mostrando que o SD-Card foi formatado corretamente e a placa está conseguindo detectar o mesmo. Com essas confirmações, podemos seguir em frente.
U-boot.img
Copiando o binário u-boot.img
para o SD-Card é possível ver o u-boot carregado, como podemos ver abaixo:
U-Boot SPL 2022.04-rc3-00052-g6d3c46ed0e (Sep 11 2022 - 11:17:49 -0400)
Trying to boot from MMC1
U-Boot 2022.04-rc3-00052-g6d3c46ed0e (Sep 11 2022 - 11:17:49 -0400)
CPU : AM335X-GP rev 2.1
Model: TI AM335x BeagleBone Black
DRAM: 512 MiB
Core: 150 devices, 14 uclasses, devicetree: separate
WDT: Started wdt@44e35000 with servicing (60s timeout)
NAND: 0 MiB
MMC: OMAP SD/MMC: 0, OMAP SD/MMC: 1
Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1...
<ethaddr> not set. Validating first E-fuse MAC
Net: eth2: ethernet@4a100000, eth3: usb_ether
Hit any key to stop autoboot: 0
Dessa forma, consegui compilar e rodar o U-Boot na minha Beaglebone.
Próximos passos
Para o próximo desafio, fica carregar o kernel Linux. Procurando rapidamente, percebi o u-boot deixou de dar suporte ao arquivo uEnv.txt, o que vai dificultar as coisas um pouco mais. Algumas fontes:
- https://forum.beagleboard.org/t/u-boot-ignores-uenv-txt/30549/3
Possivelmente esse commit desabilitou o uEnv.txt
https://github.com/u-boot/u-boot/commit/ff8f277e9121c6636e21bb7d7381c4dcac2a596b\
Mas também encontrei, que existe uma outra forma de carregar as imagens do Kernel
e o DTB
. Utilizando o Distro Boot (ref)
Além de fazer da forma tradicional, que é criando o próprio script de boot (ref)
cat <<"EOF" > boot.cmd
mmc dev 0
fatload mmc 0:1 ${kernel_addr_r} zImage
setenv bootargs console=tty1 console=ttyAMA0,115200 earlyprintk root=/dev/mmcblk0p2 rootwait
bootz ${kernel_addr_r} - ${fdt_addr}
EOF
tools/mkimage -C none -A arm -T script -d boot.cmd boot.scr