FAVORITAR
FecharPlease login

Inicializando a BeagleBone Black por interface de rede

Introdução

No ambiente de desenvolvimento com Linux embarcado, dependendo dos objetivos da pessoa desenvolvedora, pode ser que seja necessário recompilar ou usar uma versão diferente do kernel, modificar a device tree de acordo com  a evolução da sua plataforma, ou realizar mudanças no sistema, como manutenção de módulos do kernel, introdução de novas aplicações, dentre outras. Normalmente, para efetivar qualquer uma dessas mudanças, seria necessário aplicá-la ao dispositivo de armazenamento que a sua plataforma embarcada está utilizando, que, em geral, é uma mídia removível (e.g. cartão SD ou pen drive). Porém, durante o processo de desenvolvimento, pode ser necessário testar mudanças de forma incremental, exigindo que o dispositivo de armazenamento seja transferido muitas vezes do dispositivo embarcado para o computador e vice-versa, consumindo muito tempo

As soluções para esse tipo de problema são diversas, mas neste tutorial será focada a abordagem de inicialização de uma plataforma embarcada utilizando interface de rede (network boot). A placa BeagleBone Black Rev. C será utilizada como base para os experimentos. Caberá a você extrapolar os conceitos mostrados aqui para a sua plataforma.

Antes de explicar a arquitetura da inicialização da BeagleBone Black (BBB) por interface de rede, é necessário entender como essa plataforma é inicializada. A Figura 1 ilustra o processo de inicialização da BBB e que se dá nos seguintes passos:

  1. RBL (ROM Bootloader): é o primeiro programa a ser executado e está armazenado permanentemente na memória ROM da placa; seu papel é carregar o bootloader secundário da memória flash, cartão SD ou outros periféricos para a memória SRAM do SoC e executá-lo;
  2. SPL (Secondary Program Loader) ou MLO (Memory Loader): é o bootloader secundário e seu papel é carregar e executar o bootloader terciário, como o U-boot, na memória RAM da placa;
  3. U-boot: é o bootloader terciário e seu papel é carregar e executar o kernel Linux;
  4. Linux: após inicialização do kernel o sistema de arquivos raiz (root file system) estará disponível para uso;

Figura 1 – Processo de inicialização da BeagleBone Black.

A BBB já vem pré-gravada com uma distribuição Debian na sua memória flash e se, durante a inicialização, o botão da placa for pressionado, os programas serão carregados do cartão SD, caso contrário, virão da memória flash pré-gravada.

Enfim, com isso definido, conseguimos entender os artefatos que podem ser modificados em uma distribuição Linux customizada para a BBB. Em um ambiente tradicional de desenvolvimento, uma das práticas seria armazenar essas imagens no cartão SD. Mas no caso deste tutorial será diferente, de modo que as imagens mais sujeitas a modificações serão carregadas via rede. A Figura 2 ilustra a arquitetura de inicialização da BBB usando interface de rede (tudo isso ficará claro de acordo com que o tutorial for evoluindo).

Figura 2 – Processo de inicialização da BeagleBone Black usando interface de rede.

Note que a arquitetura anterior foi expandida com alguns blocos a mais. Durante a inicialização por interface de rede, apenas as imagens do MLO e U-boot estarão localizados no cartão SD, pois não são comumente modificadas após introduzidas na placa. As demais imagens, como kernel, device tree blob e o sistema de arquivos raiz serão buscados diretamente da sua máquina de desenvolvimento por uma interface de rede.

O protocolo TFTP (Trivial File Transfer Protocol) é fácil e simples para usar e é útil para transferir arquivos de um servidor para um cliente TFTP. Nesse caso o cliente TFTP no U-boot vai buscar a uImage do kernel e a device tree blob do servidor TFTP na máquina local de desenvolvimento.  

Já o protocolo NFS (Network File System) permite o acesso remoto a arquivos por uma interface de rede. Esse recurso será usado para manter o sistema de arquivos raiz do sistema embarcado na máquina de desenvolvimento (onde estará o servidor TFTP)para fácil manutenção e desenvolvimento, enquanto a BeagleBone Black acessa-o remotamente sem a necessidade de que seja atualizado no cartão SD após a cada mudança.

Com o objetivo traçado, agora é hora de colocar em prática esse tipo de inicialização.

Materiais

  • Máquina Linux para desenvolvimento (o experimento foi desenvolvido utilizando Ubuntu 20.04 LTS);
  • BeagleBone Black Rev. C (será a plataforma alvo/target dos experimentos);
  • Cartão micro SD (com o mínimo de capacidade possível, pois serão utilizados apenas alguns megabytes, mas 1GB seria suficiente);
  • Cabo Ethernet (para conexão entre o BBB e computador de desenvolvimento);
  • Cabo mini USB para USB-A (para alimentação da BBB durante esse experimento; apenas o cabo USB será necessário, mas se for precisar exigir mais recursos da placa, será necessário utilizar uma fonte de alimentação DC 5V@2A);
  • Adaptador USB Serial TTL (para monitorar os logs de inicialização e interagir com o terminal da distribuição Linux embarcada);

Compilação das imagens

Para esse tutorial serão compiladas todas as imagens individualmente a partir do código-fonte, com o objetivo de dar uma visão detalhada de como é todo o processo de customização do processo de inicialização. Mas nada impede de que elas sejam geradas a partir do Buildroot, Yocto ou até baixadas de uma distribuição pronta.

As imagens que serão compiladas são: U-boot (quando compilado já vai gerar o MLO e u-boot.img), Linux kernel (será compilada a uImage e device tree blob) e Busybox como o sistema de arquivos raiz;

Baixando o código fonte

Baixe o código fonte do U-boot para a BeagleBone Black via git clone:

Em seguida baixe o código fonte para o kernel Linux da BeagleBone Black:

Para o sistema de arquivos raiz  pode ser usado o Busybox que é suficiente para as demonstrações desse tutorial (mas sinta-se à vontade para usar o sistema de arquivos raiz que preferir):

Com todo o código-fonte baixado, agora é hora da compilação das imagens. Antes disso é necessário a toolchain correta para a compilação cruzada de código para a arquitetura ARM da BeagleBone Black na sua máquina x86 (ou x86_64). A toolchain arm-linux-gnueabihf da Linaro é suficiente:

Adicione o caminho dos binários da toolchain ao caminho do sistema (variável PATH). Você pode adicionar permanentemente em seu arquivo .bashrc ou .profile, ou pode apenas exportar o caminho para cada sessão do seu terminal. Pela simplicidade, esse tutorial vai usar a última opção: 

Ao compilar o U-boot, kernel Linux e Busybox a toolchain utilizada deve ser passada com o argumento CROSS_COMPILE=arm-linux-gnueabihf-. Note que apenas o prefixo da toolchain é utilizado, já que a ferramenta a ser utilizada, como o gcc, será decidida pelo sistema de compilação.

U-boot

Primeiramente para compilar o U-boot siga os passos abaixo. Limpe todos os artefatos de compilações passadas e configurações com o comando abaixo: 

Em seguida use a configuração padrão para a placa como o seu arquivo .config de configuração:

Opcionalmente o .config pode ser editado usando o menuconfig (e só deve ser editado por meio dele), mas esse tutorial não fará modificações, portanto as configurações padrões serão usadas:

Finalmente rode o comando de compilação:

Note que foi usado o argumento opcional -j81, que significa que 8 núcleos da CPU serão utilizados para agilizar o processo de compilação. Se você precisa saber essa informação em sua máquina, rode o comando:

Kernel Linux

O kernel Linux pode ser compilado de uma maneira semelhante:

A configuração padrão pode ser a configuração padrão da comunidade BeagleBoard.org para a BeagleBone Black (bb.org_defconfig). Qualquer edição pode ser feita com o menuconfig.

Compile a uImage do kernel passando o argumento LOADADDR com o valor comumente usado em sistemas ARM (0x80008000):

Não esqueça de compilar a Device Tree Blob (dtb):

Sistema de arquivos raiz (Busybox)

Os passos para a compilação do Busybox também são semelhantes aos anteriores, com a exceção de que o caminho de instalação do sistema de arquivos deve ser passado no momento de compilação. Nesse momento não há necessidade de se preocupar com configurações da placa, mas a opção “build static binary” deve ser ativada no menuconfig para gerar binários estáticos:

A árvore do seu sistema de arquivos raiz se parecerá com isso:

Com isso pronto, na necessidade de compilar módulos do kernel, estes podem ser diretamente instalados no caminho correto: 

Configurações de inicialização

A inicialização da BeagleBone Black será feita em três partes:

  1. As imagens pouco modificadas, como o MLO e U-boot.img, serão armazenadas em uma partição BOOT no cartão SD, portanto a inicialização partirá desse dispositivo;
  2. Em seguida, após inicializado o U-boot, este será capaz de instanciar um cliente TFTP para acessar o servidor TFTP da sua máquina local para carregar a uImage do kernel e o Device Tree Blob na memória;
  3. Após o U-boot dar controle da inicialização para o kernel Linux, este será capaz de montar o sistema de arquivos raiz usando NFS;

SD card

Primeiro deve-se configurar o cartão SD. Conecte o cartão SD à sua máquina local e confira os logs para o block device alocado ao seu cartão SD:

Nesse exemplo o block device é o /dev/sda. Informações detalhadas sobre as partições dos dispositivos podem ser vistas com o comando abaixo:

O dispositivo é /dev/sda e suas partições são /dev/sdax (sendo x um número inteiro). 

Nesse caso precisaremos de uma partição BOOT de mais ou menos 32MB com sistema de arquivos do tipo FAT16 e uma partição ROOT com o tamanho restante do cartão SD e do tipo ext4. Apesar de estarmos usando um sistema de arquivos pela rede (NFS), é uma boa prática manter a partição ROOT caso decida-se usá-la  posteriormente. Antes de formatar, você deve desmontar todas as partições. O comando abaixo garante isso (x é o número da partição e esse comando deve ser executado para todas): 

Se checar novamente a saída do comando lsblk o campo MOUNTPOINT deverá estar limpo.

Para a formatação lance a ferramenta utilitária fdisk apontando para o dispositivo a ser formatado, nesse caso /dev/sda (observe que o $ foi alterado por #, significando que o comando deve ser executado com privilégios de administrador):

O comando p vai listar todas as partições:

Delete as partições com d:

Se existirem mais partições, a ferramenta solicitará que você escolha o número da partição. De toda forma, delete todas. Após isso crie as novas partições com n. A primeira partição deve ser a BOOT e deverá preencher as opções como o exemplo abaixo (partição do tipo primária; partição 1; primeiro setor 2048; último setor +32M; sim para remover as assinaturas):

Marque a partição como inicializável com o comando a:

Finalmente formate a partição BOOT para FAT16 com o comando t:

A partição ROOT pode ser criada de forma similar. Utilize as opções padrão para utilizar o armazenamento restante:

Formate-a para o tipo Linux (preparando para formatá-la para ext4):

Até esse momento as mudanças não foram salvas no cartão SD. Para isso use o comando w. Atenção, pois essa operação é irreversível, por isso verifique suas mudanças com o comando p e se satisfeito, submeta as mudanças com w:

Fora do utilitário fdisk, formate as partições BOOT e ROOT para FAT e ext4, respectivamente, também nomeando elas corretamente:

Seu cartão SD está pronto para receber as imagens necessárias.

Configuração de rede 

Antes de configurar os servidores TFTP e NFS, algumas configurações de rede devem ser feitas. Para a inicialização por interface de rede você precisará de uma conexão Ethernet entre a sua máquina local e a BeagleBone Black. Para isso você usará a interface de rede Ethernet da sua máquina. No Ubuntu instale os pacotes necessários para ativar/desativar as interfaces de rede ifup e ifdown) e para monitorar o estado delas (ifconfig):

Para esse tutorial você vai precisar de um endereço de IP estático para sua interface de rede, de forma que a BeagleBone Black possa encontrar facilmente os servidores TFTP e NFS.  Neste tutorial, será utilizada a interface eth0. O arquivo /etc/network/interfaces será editado como o endereço IPv4 192.168.42.2 (escolha arbitrária, mas que está de acordo com a Figura 2) e máscara de rede 255.255.255.0 (IP para broadcast e gateway são definidos para x.x.x.255 and x.x.x.1, respectivamente):

Após isso desative e reative a interface de rede para que as mudanças tenham efeito:

TFTP

Para configurar o TFTP, instale o servidor TFTP tftpd-hpa na máquina local:

Confira se o servidor TFTP está rodando corretamente:

Se não estiver rodando, inicie-o com systemctl start tftpd-hpa ou systemctl restart tftpd-hpa (start, stop ou restart necessitam de privilégios de administrador). Após isso o arquivo de configuração /etc/default/tftpd-hpa deve ser configurado como o exemplo abaixo, garantido de passar o diretório em que a uImage e a dtb estarão localizadas (privilégios de administrador serão necessários para editar esse arquivo):

Após isso crie o diretório tftpboot/ e modifique suas permissões e dono, então reinicia o serviço:

Seu servidor TFTP está pronto para ser usado.

NFS

Para configurar o NFS instale o servidor NFS nfs-kernel-server na sua máquina local:

Garanta que o diretório do sistema de arquivos raiz possui privilégios suficientes para ser acessado pelo sistema alvo:

Agora edite o arquivo /etc/exports para especificar informações de acesso ao diretório compartilhado (a máscara de rede a ser usada é 255.255.255.0=24, conforme aquela usada na configuração da rede da máquina local):

Cada campo significa:

  •  /home/usuario/rootfs: diretório do sistema de arquivos raiz a ser compartilhado;
  • 192.168.42.3/24: IP do cliente a usar o diretório compartilhado, nesse caso será usado um IP estático na BeagleBone Black, que será configurado mais a frente (tente ser específico sobre qual o IP dos clientes que acessarão esse diretório);
  • rw : permissões de leitura e escrita para o cliente;
  • no_root_squash: o usuário administrador do cliente também terá permissões de administrador sobre esse diretório;
  • no_subtree_check: o servidor não vai checar por permissões para cada subdiretório;

Aplique as mudanças ao exportar as configurações do arquivo /etc/exports:

Edite o arquivo /etc/default/nfs-kernel-server e adicione a opção para vincular o servidor NFS ao IP da interface eth0:

Reinicie o servidor para que as mudanças tenham efeito:

Seu servidor NFS está pronto para ser usado.

Inicialização

Configurando o uEnv.txt

O objetivo dessa configuração é que a BeagleBone Black inicialize a partir do cartão SD e que o U-boot utilize o arquivo uEnv.txt localizado na partição BOOT para executar os comandos de inicialização. Nesse caso o arquivo uEnv.txt será editado para refletir as opções de inicialização pela interface de rede. Então, de acordo com as configurações anteriores para os servidores TFTP e NFS, seu arquivo uEnv.txt deverá se parecer como abaixo (sinta-se livre para editar com suas variáveis). Uma observação é que o enderço IP estático da BBB foi definido como 192.168.42.3, que está na mesma sub-rede que o servidor e está de acordo com o valor da Figura 2.

Destinando as imagens

Como dito anteriormente, as imagens MLO and U-boot.img e o arquivo uEnv.txt deverão estar na partição BOOT do cartão SD:

A imagem do kernel e a dtb deverá ser copiada para o diretório do servidor TFTP: 

O sistema de arquivo raiz gerado pelo Busybox estará em:

Conclusão

Com tudo isso você deverá ser capaz de inicializar sua distribuição Linux embarcada pela rede usando TFTP e NFS. Alguns passos mais detalhados para garantir uma distribuição Linux embarcado totalmente funcional estão faltando, mas o foco desse tutorial foi estabelecer um ambiente para fácil e rápido desenvolvimento.

Confira abaixo os logs da inicialização da BeagleBone Black utilizando a infraestrutura construída nesse tutorial para termos de comparação:

Referências

Para mais informações, visite os links:

https://takeofftechnical.com/network-boot-embedded-linux/

https://embarcados.com.br/compilando-o-android-para-beaglebone-black/

https://www.beagleboard.org/

https://elinux.org/Building_BBB_Kernel

https://elinux.org/Panda_How_to_MLO_%26_u-boot

https://www.freecodecamp.org/news/setting-a-static-ip-in-ubuntu-linux-ip-address-tutorial/

https://sebinsebastian.hashnode.dev/creating-a-bootable-sd-card-for-beaglebone-black-using-fdisk-command-line

https://linuxhint.com/install_tftp_server_ubuntu/

https://linuxhint.com/lad-nfs-server-and-nfs-client/

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Home » Linux Embarcado » Inicializando a BeagleBone Black por interface de rede

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Comentários:
Notificações
Notificar