Boot via rede na Raspberry Pi - MakerHero
Boot via rede na Raspberry Pi

Boot via rede na Raspberry Pi

Deixe um comentário

Nesta aula, vamos aprender como configurar o boot via rede na Raspberry Pi, permitindo que o sistema operacional seja inicializado a partir de um servidor na rede. Você pode aprender aqui como dar um boot via cartão SD na Raspberry Pi ou boot via dispositivo USB local. O método via rede é útil para ambientes em que múltiplos dispositivos Raspberry Pi precisam ser gerenciados de maneira centralizada, facilitando atualizações e manutenção. Para isso, utilizaremos uma Raspberry Pi como servidor DHCP/TFTP e outra Raspberry Pi como cliente, que será inicializada via rede.

O que é o Boot via Rede na Raspberry Pi?

O boot via rede permite que a placa Raspberry Pi seja inicializada a partir de um servidor na rede. Essa configuração requer que o servidor funcione como um servidor DHCP/TFTP, permitindo que a Raspberry Pi cliente obtenha seu sistema operacional e arquivos de inicialização diretamente através da rede. Para configurar essa funcionalidade, você precisará de uma Raspberry Pi adicional que funcionará como servidor, e outra como cliente a ser inicializada.

Importante! Como existem muitos tipos diferentes de dispositivos e roteadores de rede, não é garantido que o boot via rede funcione com todos eles. Caso enfrente problemas, tente desabilitar STP (Spanning Tree Protocol) na sua rede.

Configurando a Raspberry Pi 3 para Boot via Rede

Antes que o Raspberry Pi 3 possa realizar o boot via rede, ele precisa ser inicializado a partir de um cartão SD com uma opção de configuração para habilitar o modo de boot USB. Isso configurará um bit na memória OTP (One Time Programmable) do SoC da Raspberry Pi, que permitirá o boot via rede. Feito isso, o Raspberry Pi 3 tentará inicializar a partir do USB e, se não conseguir, tentará pela rede.

Instale o Raspberry Pi OS no cartão SD da maneira usual. Em seguida, habilite o modo de boot USB com o seguinte comando:

echo program_usb_boot_mode=1 | sudo tee -a /boot/firmware/config.txt

Isso adiciona program_usb_boot_mode=1 ao final do arquivo /boot/firmware/config.txt. 

Reinicie a Raspberry Pi com sudo reboot:

sudo reboot

Depois que a Raspberry Pi cliente for reiniciada, verifique se o OTP foi programado com:

vcgencmd otp_dump | grep 17:

Certifique-se de que a saída seja 0x3020000a.

A configuração do cliente está quase concluída. Como passo final, desative o boot USB. Execute o seguinte comando:

sudo nano /boot/firmware/config.txt

Remova a linha que contém o texto program_usb_boot_mode=1

Por fim, desligue a Raspberry Pi cliente com:

sudo poweroff

Configurando a Raspberry Pi 4 e Raspberry Pi 5 para Boot via Rede

Para habilitar o boot via rede no Raspberry Pi 4 e na Raspberry Pi 5, utilize a ferramenta raspi-config:

sudo raspi-config

Dentro do raspi-config, escolha Advanced Options > Boot Order, e, em seguida, Network Boot. Você deve então reiniciar o dispositivo para que a mudança na ordem de boot seja programada na EEPROM do bootloader. Após a Raspberry Pi reiniciar, verifique se a ordem de boot agora é 0xf21:

vcgencmd bootloader_config

Endereço MAC Ethernet

Antes de configurar o boot via rede, anote o número de série e o endereço MAC para que a placa possa ser identificada pelo servidor TFTP/DHCP.

Na placa Raspberry Pi, o endereço MAC é programado durante a fabricação e não há ligação entre o endereço MAC e o número de série. Tanto o endereço MAC quanto o número de série são exibidos na tela de diagnóstico HDMI do bootloader.

Para encontrar o endereço MAC Ethernet:

ethtool -P eth0

Para encontrar o número de série:

grep Serial /proc/cpuinfo | cut -d ' ' -f 2 | cut -c 9-16

A imagem abaixo mostra um exemplo de saída para os dois comandos acima:

exemplo de saída para os dois comandos

Configurando o Servidor para Boot via Rede

Insira o cartão SD na placa Raspberry Pi que será usado como servidor e, em seguida, inicialize o servidor. A Raspberry Pi cliente precisará de um sistema de arquivos raiz para iniciar: vamos usar uma cópia do sistema de arquivos raiz do servidor e colocá-la em /nfs/client1:

sudo mkdir -p /nfs/client1
sudo apt install rsync
sudo rsync -xa --progress --exclude /nfs / /nfs/client1

Regenere as chaves do host SSH no sistema de arquivos do cliente utilizando o comando chroot:

cd /nfs/client1
sudo mount --bind /dev dev
sudo mount --bind /sys sys
sudo mount --bind /proc proc
sudo chroot .
rm /etc/ssh/ssh_host_*
dpkg-reconfigure openssh-server
exit
sudo umount dev sys proc

Encontre as configurações da sua rede local. Você precisará encontrar o endereço do seu roteador (ou gateway), o que pode ser feito com:

ip route | awk '/default/ {print $3}'

Em seguida, execute:

ip -4 addr show dev eth0 | grep inet

Você deverá ver uma saída semelhante a:

inet 10.42.0.211/24 brd 10.42.0.255 scope global eth0

O primeiro endereço é o endereço IP do seu servidor Raspberry Pi na rede, e a parte após a barra indica o tamanho da rede. É muito provável que o seu seja um /24. Anote também o endereço brd (broadcast) da rede. Registre a saída do comando anterior, que conterá o endereço IP do Raspberry Pi e o endereço de broadcast da rede.

Finalmente, anote o endereço do seu servidor DNS, que é o mesmo endereço do seu gateway. Você pode encontrar isso com:

cat /etc/resolv.conf

Para configurar um endereço de rede estático no seu Servidor Raspberry Pi, você precisará criar os arquivos 10-eth0.netdev e 11-eth0.network da seguinte maneira:

sudo nano /etc/systemd/network/10-eth0.netdev

Adicione as seguintes linhas:

[Match]
Name=eth0

[Network]
DHCP=no

Depois, crie o arquivo de configuração de rede:

sudo nano /etc/systemd/network/11-eth0.network

Adicione o seguinte conteúdo ao arquivo 11-eth0.network:

[Match]
Name=eth0

[Network]
Address=10.42.0.211/24
DNS=10.42.0.1

[Route]
Gateway=10.42.0.1

Neste ponto, você não terá o DNS funcionando, então será necessário adicionar o servidor que você anotou anteriormente ao arquivo systemd/resolved.conf. Neste exemplo, o endereço do gateway é 10.42.0.1.

Edite o arquivo com:

sudo nano /etc/systemd/resolved.conf

Descomente a linha DNS e adicione o endereço IP do DNS. Além disso, se você tiver um servidor DNS de fallback, adicione-o também:

[Resolve]
DNS=10.42.0.1
#FallbackDNS=

Ative o systemd-networkd e reinicie para que as mudanças tenham efeito:

sudo systemctl enable systemd-networkd
sudo reboot

Agora, instale o tcpdump para procurar pacotes DHCP enviados pelo Raspberry Pi cliente:

sudo apt install tcpdump dnsmasq
sudo systemctl enable dnsmasq
sudo tcpdump -i eth0 port bootpc

Conecte a Raspberry Pi cliente à sua rede e ligue-o. Verifique se os LEDs do cliente iluminam após cerca de 10 segundos; então, você deverá ver um pacote do cliente com “DHCP/BOOTP, Request from …​”:

IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from b8:27:eb...

Você precisará modificar a configuração do dnsmasq para permitir que o DHCP responda ao dispositivo. Pressione CTRL + C para sair do programa tcpdump e, em seguida, digite o seguinte:

echo | sudo tee /etc/dnsmasq.conf
sudo nano /etc/dnsmasq.conf

Substitua o conteúdo do dnsmasq.conf por:

# Nota: comente a porta se desejar serviços de DNS para sistemas na rede.
port=0
dhcp-range=10.42.0.255,proxy
log-dhcp
enable-tftp
tftp-root=/tftpboot
pxe-service=0,"Raspberry Pi Boot"

No campo dhcp-range, utilize o endereço de broadcast que você anotou anteriormente.

Agora, crie o diretório /tftpboot:

sudo mkdir /tftpboot
sudo chmod 777 /tftpboot
sudo systemctl enable dnsmasq.service
sudo systemctl restart dnsmasq.service

Monitore o log do dnsmasq com:

journalctl -f

Você deverá ver algo parecido com isto:

raspberrypi dnsmasq-tftp[1903]: file /tftpboot/bootcode.bin not found

Em seguida, será necessário copiar o conteúdo da pasta de boot para o diretório /tftpboot.

Primeiro, pressione CTRL + C para sair do estado de monitoramento. Em seguida, digite o seguinte comando para copiar os arquivos:

cp -r /boot/firmware/* /tftpboot

Como a localização do TFTP foi alterada, reinicie o serviço dnsmasq:

sudo systemctl restart dnsmasq

Configurando o NFS Root

Isso agora deve permitir que o cliente Raspberry Pi tente inicializar até carregar um sistema de arquivos root (que ele ainda não tem).

Neste ponto, exporte o sistema de arquivos /nfs/client1 criado anteriormente e a pasta de inicialização TFTP.

Execute os seguintes comandos:

sudo apt install nfs-kernel-server
echo "/nfs/client1 *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
echo "/tftpboot *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports

Reinicie o RPC-Bind e o servidor NFS para que eles detectem os novos arquivos:

sudo systemctl enable rpcbind
sudo systemctl restart rpcbind
sudo systemctl enable nfs-kernel-server
sudo systemctl restart nfs-kernel-server

Edite o arquivo /tftpboot/cmdline.txt e, a partir de root=, substitua com:

root=/dev/nfs nfsroot=10.42.0.211:/nfs/client1,vers=3 rw ip=dhcp rootwait

Substitua o endereço IP pelo que você anotou. Além disso, remova qualquer parte da linha de comando que comece com init=.

Por fim, edite o arquivo /nfs/client1/etc/fstab e remova as linhas referentes a /dev/mmcblk0p1 e p2 (deixando apenas proc). Depois, adicione de volta a partição de inicialização com:

echo "10.42.0.211:/tftpboot /boot/firmware/ nfs defaults,vers=3 0 0" | sudo tee -a /nfs/client1/etc/fstab

Se não inicializar na primeira tentativa, continue tentando. Pode demorar um minuto ou mais para a placa Raspberry Pi inicializar, então tenha paciência.

Faça seu comentário

Acesse sua conta e participe