[LAB] Bootloader (U-Boot)
Baixando o U-Boot
Assim como nas atividades anteriores, os fontes do U-Boot foram previamente baixados e encontram-se no diretĆ³rio ā¼/dsle20/dl/bootloader
. Crie um diretĆ³rio chamado bootloader
dentro da pasta ā¼/dsle20
e, em seguida, extraia o U-boot no diretĆ³rio criado:
Acesse o diretĆ³rio do U-Boot e liste as configuraƧƵes prĆ©-definidas para as diversas plataformas suportadas pelo U-Boot. Devido Ć extensĆ£o da lista de configuraƧƵes, Ć© recomendado a utilizaĆ§Ć£o do comando less
. Este comando permite a visualizaĆ§Ć£o do conteĆŗdo de um arquivo ou output de algum comando, por meio de pĆ”ginas do tamanho da tela:
Use as teclas espaƧo, b e q para exibir a prĆ³xima pĆ”gina, a pĆ”gina anterior ou encerrar a visualizaĆ§Ć£o, respectivamente. Uma vez que o U-Boot suporta diversas arquiteturas de hardware diferentes, Ć© necessĆ”rio selecionar uma delas antes de compilar o programa. Selecione a configuraĆ§Ć£o rpi_3_32b_defconfig
e compile o U-Boot, indicando o prefixo do cross-compilador conforme configurado anteriormente:
Verifique o arquivo criado, u-boot.bin
, atravƩs do comando:
Gravando o U-Boot
O processo de gravaĆ§Ć£o do bootloader Ć© dependente de hardware, especĆfico para cada plataforma. Conforme visto em aula, a RPi 3 busca o bootloader e firmwares relacionados ao processo de boot na partiĆ§Ć£o boot
do cartĆ£o micro SD. Assim, dois procedimentos sĆ£o necessĆ”rios para gravar e ativar o U-Boot no processo de boot da RPi:
Copiar o binƔrio
u-boot.bin
para a partiĆ§Ć£oboot
do cartĆ£o micro SD;Configurar o arquivo
config.txt
para que o firmware da GPU,start.elf
, execute oU-Boot
no lugar do kernel Linux;
Ć possĆvel copiar o arquivo u-boot.bin
para o cartĆ£o micro SD de vĆ”rias maneiras. Visto que jĆ” existe uma configuraĆ§Ć£o de rede entre a mĆ”quina de desenvolvimento e a RPi, realizada em atividades anteriores, o arquivo serĆ” copiado via comando scp
:
Logue na RPi, via SSH, e copie o arquivo do diretĆ³rio home
para o diretĆ³rio boot
com privilƩgios de administrador:
Feito isso, adicione a seguinte linha no final do arquivo config.txt
:
O parĆ¢metro acima especifica qual imagem do kernel, o firmware start.elf
deve carregar. Neste caso, a imagem Ć© o prĆ³prio U-Boot. ApĆ³s salvar as alteraƧƵes no arquivo, renicie a RPi (sudo reboot
).
AtenĆ§Ć£o, sĆ³ reinicie a RPi se vocĆŖ possui uma conexĆ£o serial funcional entre ela e a mĆ”quina de desenvolvimento, pois a Ćŗnica interaĆ§Ć£o com o menu do U-Boot, por enquanto, Ć© via serial.
Por Ćŗltimo, interrompa o processo de boot do U-Boot pressionando uma tecla para entrar no shell:
Configurando variƔveis de ambiente no U-Boot
ApĆ³s obter acesso ao shell do U-Boot, configure algumas variĆ”veis de ambiente bĆ”sicas para manter o sistema da RPi bootĆ”vel, pois por padrĆ£o, o U-Boot nĆ£o identifica a imagem do kernel automaticamente. Inicialmente, desative o processo de autoboot:
Futuramente, o U-Boot serƔ configurado para carregar o kernel pela rede, de uma pasta de sua mƔquina de desenvolvimento. Portanto, configure o endereƧo IP da RPi e mƔquina de desenvolvimento:
Por fim, salve as alteraƧƵes realizados no disco, de tal forma que elas estejam disponĆveis na prĆ³xima inicializaĆ§Ć£o, e reinicie o RPi:
ApĆ³s enviar o comando saveenv
, o U-Boot cria um arquivo de configuraĆ§Ć£o chamado u-boot.env
que contĆ©m todas as variĆ”veis de ambiente definidas. ApĆ³s reiniciar novamente a RPi, o processo de autoboot nĆ£o deve ser inicializado e o controle do shell exibido logo em seguida. Para ābootarā o Raspbian novamente, pelo U-Boot, algumas configuraƧƵes adicionais sĆ£o necessĆ”rias. O primeiro passo, Ć© carregar um arquivo (imagem do kernel) do cartĆ£o micro SD para a RAM em um endereƧo especĆfico. Utilize o seguinte comando:
O comando acima carrega um arquivo binĆ”rio de um sistema de arquivos FAT (fatload). Os parĆ¢metros sĆ£o:
mmc: o dispositivo de armazenamento onde se encontra o binĆ”rio (cartĆ£o SD);
0: o nĆŗmero do dispositivo, pois muitas vezes o seu target pode possuir mais de um dispositivo de armazenamento;
1: o nĆŗmero da partiĆ§Ć£o no dispositivo (partiƧƵes sĆ£o enumeradas a partir de 1);
${kernel_addr_r}: o endereƧo inicial na RAM onde deseja-se carregar o binĆ”rio, neste caso a configuraĆ§Ć£o do U-Boot jĆ” fornece uma variĆ”vel de ambiente com o endereƧo inicial da RAM, para carregar o kernel (${kernel_addr_r});
kernel7.img: o binĆ”rio que se deseja carregar. Lembrando que por padrĆ£o, a partiĆ§Ć£o boot do Raspbian fornece duas imagens:
kernel.img
ekernel7.img
. A primeira Ć© para as versƵes de hw anteriores (RPi e RPi 2) e a Ćŗltima (kernel7.img
) Ć© a imagem para as placas da RPi 3 em diante;
Algumas plataformas possuem dispositivos de hardware que nĆ£o podem ser identificados dinamicamente pelo kernel. Em tais casos, Ć© necessĆ”rio um mecanismo para informar o kernel sobre dispositivos presentes no sistema. Atualmente, o mecanismo utilizado para tal funĆ§Ć£o Ć© chamado de Device Tree, que Ć© uma estrutura de dados que descreve a topologia e configuraĆ§Ć£o de hardware no sistema. Analisaremos esse mecanismo em breve durante o curso.
A RPI 3 Ć© um tipo de plataforma que utiliza esse recurso e bootloader Ć© o responsĆ”vel por passar o Device Tree para o kernel e, portanto, Ć© necessĆ”rio fazer o loading desse arquivo no U-Boot. O processo Ć© o mesmo anterior, porĆ©m com algumas alteraƧƵes nos parĆ¢metros:
Caso esteja utilizando a RPi 3B+ substitua o device tree utilizado pelo device tree bcm2710-rpi-3-b-plus.dtb
, ao longo do treinamento.
mmc: o dispositivo de armazenamento onde se encontra o binĆ”rio (cartĆ£o SD);
0: o nĆŗmero do dispositivo, pois muitas vezes o seu target pode possuir mais de um dispositivo de armazenamento;
1: o nĆŗmero da partiĆ§Ć£o no dispositivo (partiƧƵes sĆ£o enumeradas a partir de 1);
${fdt_addr_r}: o endereƧo inicial na RAM onde deseja-se carregar o binĆ”rio, neste caso a configuraĆ§Ć£o do U-Boot jĆ” fornece uma variĆ”vel de ambiente com o endereƧo inicial da RAM, para carregar o Flattened Device Tree (${fdt_addr_r});
bcm2710-rpi-3-b.dtb: arquivo compilado do Device Tree (dtb) referente Ć RPi 3 B;
Estes sĆ£o basicamente os Ćŗnicos arquivos necessĆ”rios para realizar o boot do Raspbian via U-Boot. Entretanto, alĆ©m dos arquivos, ainda Ć© necessĆ”rio configurar alguns parĆ¢metros do kernel. Configure a variĆ”vel de ambiente bootargs
, responsĆ”vel por armazenar parĆ¢metros para serem passados ao kernel:
8250.nr_uarts=1: nĆŗmero de portas seriais para serem registradas (utilizadas);
root=/dev/mmcblk0p2: path para a localizaĆ§Ć£o do RootFS (Root FileSystem);
rootwait: espera (indefinidamente) a inicializaĆ§Ć£o dispositivo onde o RootFS estĆ” localizado. mmcblk0 refere-se ao micro SD e p2 Ć partiĆ§Ć£o nĆŗmero 2, visto que a primeira Ć© a partiĆ§Ć£o de
boot
;console=ttyS0,115200: redireciona um console para a porta serial
ttyS0
(mini UART da RPi 3), e seu respectivo baudrate;
Finalmente, com as configuraƧƵes acima realizadas, ābastaā dar o comando de boot:
onde:
kernel_addr_r: Ʃ o endereƧo na RAM onde estƔ carregada a imagem do kernel;
-: seria o endereƧo na RAM da imagem initrd, que Ć© uma imagem do RootFS. Ć possĆvel carrega-lo na RAM, assim como kernel e Device Tree. No entanto, no momento a RPi nĆ£o possui nenhuma imagem desse tipo. Ela serĆ” gerada em atividades futuras. Este parĆ¢metro Ć© opcional;
fdt_addr_r Ʃ o endereƧo na RAM onde estƔ carregado o compilado do Device Tree;
Se os comandos acima foram executados corretamente, vocĆŖ deverĆ” enxergar o loading do kernel pela serial.
Criando um script de inicializaĆ§Ć£o no U-Boot
O U-Boot possui uma funcionalidade que permite que o usuĆ”rio crie scripts contendo sequĆŖncia de comandos, como os executados acima. Na sua mĆ”quina de desenvolvimento, navegue atĆ© o diretĆ³rio do U-Boot e crie o seguinte arquivo:
Digite (copie) todos os comandos novamente no arquivo aberto e em seguida salve-o:
Em seguida, dentro da pasta tools no diretĆ³rio do U-Boot, existe uma ferramenta chamada mkimage capaz de criar imagens do U-Boot, kernel, RootFS e inclusive scripts para o U-Boot. Digite o seguinte comando:
onde os argumentos representam: arquitetura do executĆ”vel (-A), sistema operacional (-O), tipo da imagem (-T), arquivo de entrada com os comandos digitados no gedit (-d) e arquivo de saĆda (boot.src
), que Ć© uma imagem do script.
ApĆ³s a execuĆ§Ć£o do comando, copie o arquivo boot.scr
para o diretĆ³rio boot
da RPi via scp
. Se tudo foi realizado corretamente, reinicie a RPi e digite o comando boot
no shell do U-Boot.
Ć possĆvel ativar o autoboot atravĆ©s da modificaĆ§Ć£o da variĆ”vel de ambiente bootdelay, que representa o delay em segundos antes de iniciar o boot pelo script boot.scr
. Se desejar, altera-a, salve as variĆ”veis de ambiente no cartĆ£o SD (saveen
) e reinicie o U-Boot.
Last updated