Muitas perguntas foram feitas sobre como encontrar meu Pi na minha rede . Outros - inclusive eu - têm problemas demorados ao tentar implantar um lote de Pi's novos.
Embora a criação de imagens personalizadas possa ser uma solução para esses problemas, pergunto-me se existem outras soluções.
Com (apenas) o /boot
diretório aberto para acesso em máquinas comuns (Win / OSX), seria possível usar /boot/cmdline.txt
para canalizar texto para um script bash, executá-lo e excluí-lo posteriormente?
Respostas:
Criei uma versão levemente modificada do Raspberian-light que atende a essa necessidade - ele executa seu script /boot/firstboot.sh personalizado na primeira inicialização:
https://github.com/nmcclain/raspberian-firstboot
fonte
Para aqueles que preferem uma solução envolvendo apenas scripts inseridos na partição de inicialização do FAT32 , veja como fazer isso. [ Edit: Os arquivos estão agora disponíveis em um projeto pi-boot-script .]
Como mencionado em outras respostas, envolve os argumentos da linha de comando com os quais o kernel do Linux é iniciado. Esses argumentos estão em /boot/cmdline.txt .
Eu testei isso no Raspbian Buster (v10.1) 2019-09-26. Ele funciona em um cartão SD recém-atualizado ou na imagem de disco .img baixada , que pode ser flash para qualquer número de cartões SD.
1. Edite os argumentos do kernel
Abra o arquivo de texto /boot/cmdline.txt , remova qualquer
init=
parte dele e adicione-o no final da linha:A última palavra nesta linha é o nome de um script a ser executado pelo kernel como o primeiro processo (PID = 1) em vez de / sbin / init . A página de ajuda dos argumentos do kernel diz apenas argumentos sem
.
serem passados para o executável init, portanto você não pode chamar o script de unattended.sh ou coisas assim.2. Coloque o script na partição de inicialização
Salve o seguinte na partição de inicialização como / autônoma (o nome que você colocou na linha de comando):
Esse script faz algumas preparações necessárias (capítulo 1), depois tudo o que você deseja fazer (2) e depois limpa e reinicia (3). Substitua o material abaixo de 2 pelos comandos que você deseja executar.
Para algumas tarefas de configuração, você provavelmente precisará de uma inicialização normal para ativar a rede e outros serviços; portanto, o exemplo nesta versão (explicado abaixo) prepara apenas um script adequado para ser executado quando o Pi for reinicializado.
3. Coloque quaisquer outros arquivos que seu script precise na partição de inicialização
...obviamente.
Exemplo
Juntamente com o meu script, coloquei uma pasta de carga / na partição de inicialização, que contém os arquivos que eu quero mover para a partição Linux. No script autônomo acima,
Esse script faz várias personalizações que eu gosto: ele cria e formata outra partição FAT32 e a adiciona ao / etc / fstab para que o usuário pi possa escrever nele (para logs de aplicativos etc.); redimensiona a partição ext4 e o sistema de arquivos para o restante do cartão SD; altera o código do idioma, fuso horário, nome do host (com base no número de série da CPU), país do WiFi; define rede WiFi e senha; ativa o SSH; corrige um problema de configurações de idioma para sessões SSH; configura a inicialização em um console sem login automático; grava alguns dados sobre o sistema em um arquivo na partição de inicialização; e, é claro, remove esse link simbólico para que não seja executado novamente na inicialização.
A maioria dos usuários acha isso desnecessário e prefere usar PiBakery , pi-init2 ou uma imagem ext4 personalizada, que são ótimas soluções. Eu prefiro isso porque posso entendê-lo completamente e não preciso executar outro software. E também funciona: com o arquivo .img em que eu inseri meus scripts, todos piscam um cartão SD + o colocam em um Pi +, permitindo que ele funcione para se configurar, leva 6 minutos.
Fonte Encontrei a idéia de um script como
init=
argumento do kernel e osmount
comandos necessários para fazê-lo funcionar no script init_resize.sh que é executado por padrão para redimensionar a partição Linux.fonte
Você PODE fazer com que o código seja executado mexendo com a linha de comando do kernel. O método mais óbvio é substituir init por outra coisa. A aplicação mais comum disso é iniciar um shell muito cedo no processo de inicialização, geralmente porque você precisa corrigir alguma coisa ou porque todo o resto está muito danificado, por exemplo:
Lembre-se de que, neste ponto do processo de inicialização, os sistemas de arquivos ainda estão todos montados somente leitura. Além disso, há um monte de coisas que simplesmente não funcionam corretamente. Como você não tem um init real em execução, o desligamento e a reinicialização não funcionarão. É necessário remontar manualmente o sistema de arquivos raiz somente leitura e chamar
reboot -f
a reinicialização, por exemplo.Não tenho idéia se você pode passar argumentos para o bash dessa maneira. Eu nunca tentei. Em teoria, se você pode passar
-c
para o bash, pode dizer ao processo do bash para fazer qualquer coisa. Mas pode se transformar em um argumento bastante longo, e não sei se o kernel permitiria essas coisas.Segunda coisa que você pode fazer. Você pode copiar um ramfs inicial (initramfs) para o sistema de arquivos e configurar o gerenciador de inicialização para usá-lo
config.txt
. Existem várias maneiras de inserir scripts em um initramfs para fazer coisas especiais. Você precisará preparar um initramfs especial para esse fim (consulte initramfs-tools (8)), portanto, não tenho certeza se esta é uma solução melhor do que uma imagem personalizada.Você pode incluir o script em / boot (eu ri de sua sugestão sobre máquinas "regulares", mas seria o pouco que você pode acessar a partir dessas máquinas) e tente iniciá-lo usando a linha init do kernel, mas os arquivos dos sistemas de arquivos não são é executável, a menos que você o faça para todo o sistema de arquivos.
Se fosse eu, eu faria uma imagem personalizada que usa dhcp para configurar a rede e que contém um script personalizado que é executado na inicialização. Este script verifica um arquivo específico que atua como um sinalizador. Se o arquivo existir, não faça nada. Caso contrário, configure as coisas e crie o arquivo de sinalizador.
Seu script de configuração pode até extrair a coisa real de um servidor http. Isso significa que você não precisa criar uma nova imagem se precisar ajustar algo.
Essa deve ser a solução menos estressante.
Uma possibilidade final, mas você terá que fazer isso em uma máquina "não-regular" :-) Você pode montar o sistema de arquivos ext4 em um dispositivo de loop e copiar arquivos para ele sem escrever primeiro no sdcard. Para uma imagem Jessie Raspbian padrão, seria algo como isto:
Eu gosto de fazer um fsck forçado nos meus sistemas de arquivos antes de fazer imagens. Define a contagem de montagem como zero na primeira inicialização :-)
EDIT : Depois de muitos meses e mais experiência. Você quer olhar para o u-boot. Substitua o carregador de inicialização por u-boot. Isso pode ser feito a partir de uma "máquina comum". Depois de inicializar o u-boot, você pode inicializar em rede uma distribuição a partir da qual pode facilmente exibir o cartão sd ou, em teoria, o cartão diretamente, embora eu não tenha ideia de quão difícil isso seria.
Essencialmente, o u-boot traz o boot de rede para o Raspberry Pi, algo que ele não suporta por si só.
fonte
init=script & init
? O script seria executado em segundo plano enquanto o init inicia normalmente. O script precisaria de alguma verificação de condição no início e, por exemplo, continuará quando o init terminar seu trabalho.Eu não recomendaria tocar em nada na área de inicialização (exceto
config.txt
), a menos que você tenha uma compreensão detalhada do que essas coisas estão fazendo.cmdline.txt
não foi projetado para executar coisas quando o RPi é iniciado. É usado para passar parâmetros para o kernel do Linux na inicialização.Eu sugeriria fazer isso tudo através do SSH. Um script na área de trabalho pode enviar por push um bash / python / java / c / qualquer programa para o RPi, executá-lo e excluí-lo quando terminar. Adicione o encadeamento ao script na área de trabalho e você poderá enviá-lo para quantos dispositivos quiser, tudo ao mesmo tempo.
fonte
Pode-se argumentar que, se você estiver bem com a modificação da imagem para executar automaticamente um script na primeira inicialização, você pode simplesmente modificar a imagem da maneira que o script faria e, em seguida, salvar o cartão SD em um arquivo de imagem e usá-lo para piscar. Cartões SD que você vai usar com os novos RPis. Por exemplo, se você deseja que todos os seus RPis tenham uma entrada específica
/etc/fstab
, você pode simplesmente se modificar/etc/fstab
em vez de escrever um script que faça a modificação.Se você precisar absolutamente de ações com script (por exemplo, se cada imagem deve ser modificada de uma maneira diferente), você pode mover
/etc/rc.local
para/etc/rc.bak
e colocar um script no/etc/rc.local
qual se substitui/etc/rc.bak
no último comando. Esse script pode executar as primeiras ações de inicialização, ou pode chamar um script específico da/boot
partição, se você preferir.É possível fazer uma execução automática tocando apenas na
/boot
partição, fornecendo uma imagem especial de ramdisk de inicialização para o kernel, conforme descrito aqui . Essa imagem conteria os scripts para modificar a partição raiz e depois excluir automaticamenteconfig.txt
. Não tenho certeza se vale a pena o problema.fonte
Você pode querer olhar para o meu projeto Nard, que tem uma solução para o seu problema:
1) Cada cartão SD pode receber uma ID exclusiva com um PC Windows regular, conforme descrito aqui:
http://www.arbetsmyra.dyndns.org/nard/#devsettingsid
2) Ligue todos os seus Pis
3) Desative o firewall do PC, se possível
4) Abra uma janela do prompt do DOS e execute ping no endereço de transmissão da sub-rede
5) Liste a tabela ARP com o comando do Windows "arp -a". Na lista, você encontrará os endereços MAC e IP de todos os Raspberry Pi nas proximidades.
6) Conecte-se a cada dispositivo com telnet (normalmente também disponível no Windows). A frase de boas-vindas exibirá o ID atribuído na etapa 1.
fonte