Se han hecho muchas preguntas sobre cómo encontrar mi Pi en mi red . Otros, incluyéndome a mí, tienen problemas que requieren mucho tiempo mientras intentan desplegar un lote de Pi nuevos.
Si bien la creación de imágenes personalizadas podría ser una solución para estos problemas, me pregunto si hay otras soluciones.
Con (sólo) el /boot
directorio abierto para el acceso en regulares máquinas (Win / OSX), ¿sería posible utilizar /boot/cmdline.txt
al texto tubo a una escritura del golpe, ejecutarlo y eliminarlo después?
Respuestas:
Creé una versión ligeramente modificada de Raspberian-light que responde a esta necesidad: ejecuta su script /boot/firstboot.sh personalizado en el primer arranque:
https://github.com/nmcclain/raspberian-firstboot
fuente
Para aquellos que prefieren una solución que involucre solo scripts que se hayan caído en la partición de arranque FAT32 , aquí es cómo hacerlo. [ Editar: los archivos ahora están disponibles en un proyecto pi-boot-script .]
Como se menciona en otras respuestas, involucra los argumentos de la línea de comandos con los que se inicia el kernel de Linux. Esos argumentos están en /boot/cmdline.txt .
He probado esto en Raspbian Buster (v10.1) 2019-09-26. Funciona en una tarjeta SD recién flasheada o en la imagen de disco .img descargada , que luego puede flashear en cualquier cantidad de tarjetas SD.
1. Edite los argumentos del kernel
Abra el archivo de texto /boot/cmdline.txt , elimine cualquier
init=
parte de él y agréguelo al final de la línea:La última palabra en esta línea es el nombre de un script que debe ejecutar el núcleo como primer proceso (PID = 1) en lugar de / sbin / init . La página de ayuda de argumentos del núcleo solo dice argumentos sin
.
pasar al ejecutable init, por lo que no puede llamar al script desatendido.sh o cosas así.2. Ponga el script en la partición de arranque
Guarde lo siguiente en la partición de arranque como / desatendido (el nombre que puso en la línea de comando):
Este script hace una preparación necesaria (capítulo 1), luego cualquier cosa que desee hacer (2) y luego limpie y reinicie (3). Reemplace las cosas debajo de 2 con los comandos que desea ejecutar.
Para algunas tareas de configuración, es probable que necesite un arranque normal para que aparezca la red y otros servicios, por lo que el ejemplo en esta versión (explicado a continuación) solo se prepara para ejecutar una secuencia de comandos adecuada cuando se reinicia el Pi.
3. Coloque cualquier otro archivo que su script necesite en la partición de arranque
...obviamente.
Ejemplo
Junto con mi script, pongo una carpeta de carga útil / en la partición de arranque, que contiene los archivos que quiero mover a la partición de Linux. En el script desatendido arriba,
Ese script hace varias personalizaciones que me gustan: crea y formatea otra partición FAT32 y la agrega a / etc / fstab para que el usuario pi pueda escribir en ella (para registros de aplicaciones, etc.); cambia el tamaño de la partición ext4 y el sistema de archivos al resto de la tarjeta SD; cambia la configuración regional, la zona horaria, el nombre de host (según el número de serie de la CPU), el país de WiFi; establece la red WiFi y la frase de contraseña; enciende SSH; corrige un problema de configuración de idioma para sesiones SSH; configura el arranque en una consola sin inicio de sesión automático; escribe algunos datos sobre el sistema en un archivo en la partición de arranque; y, por supuesto, elimina ese enlace simbólico para que no se vuelva a ejecutar en el arranque.
La mayoría de los usuarios encontrarán esto innecesario y preferirán usar PiBakery , pi-init2 o una imagen ext4 personalizada, que son excelentes soluciones. Prefiero esto porque puedo entenderlo completamente y no tengo que ejecutar otro software. Y también funciona: con el archivo .img en el que he puesto mis scripts, flashear una tarjeta SD + ponerla en un Pi + y dejar que se ejecute para configurarse solo lleva 6 minutos.
Fuente Encontré la idea de un script como
init=
argumento del núcleo, y losmount
comandos necesarios para que funcione, en el script init_resize.sh que se ejecuta por defecto para cambiar el tamaño de la partición de Linux.fuente
PUEDE hacer que el código se ejecute jugando con la línea de comando del núcleo. El método más obvio es reemplazar init con otra cosa. La aplicación más común de esto es lanzar un shell muy temprano en el proceso de arranque, generalmente porque necesita arreglar algo o porque todo lo demás está muy dañado, por ejemplo:
Tenga en cuenta que en este punto del proceso de arranque, todos los sistemas de archivos todavía están montados de solo lectura. Además, hay un montón de cosas que simplemente no funcionarán correctamente. Debido a que no tiene un verdadero init ejecutándose, el apagado y el reinicio no funcionarán. Debe
reboot -f
volver a montar manualmente el sistema de archivos raíz de solo lectura y llamar para reiniciar, por ejemplo.No tengo idea si puedes pasar argumentos para golpear de esta manera. Nunca lo he intentado. En teoría, si puede pasar
-c
a bash, puede decirle a ese proceso de bash que haga cualquier cosa. Pero podría convertirse en un argumento bastante largo, y no sé si el núcleo permitiría tales cosas.Lo segundo que puedes hacer. Puede copiar un ramfs inicial (initramfs) al sistema de archivos y configurar el gestor de arranque para usarlo
config.txt
. Hay varias formas de obtener scripts en un initramfs para hacer cosas especiales. Sin embargo, tendrá que preparar un initramfs especial para este propósito (vea initramfs-tools (8)), por lo que no estoy seguro de si esta es una mejor solución que una imagen personalizada.Podrías incluir el script en / boot (me reí de tu sugerencia sobre máquinas "normales", pero esto sería el bit al que puedes acceder desde esas máquinas) e intentar iniciarlo usando la línea de inicio del kernel, pero los archivos en los sistemas de archivos DOS no son No es ejecutable a menos que lo haga para todo el sistema de archivos.
Si fuera yo, crearía una imagen personalizada que usa dhcp para configurar la red y que contiene un script personalizado que se ejecuta en el arranque. Este script busca un archivo específico que actúe como un indicador. Si el archivo existe, no haga nada. Si no, configure las cosas, luego cree el archivo de bandera.
Su script de configuración podría incluso extraer lo real de un servidor http. Esto significa que no tiene que hacer una nueva imagen si tiene que modificar algo.
Esa debería ser la solución menos estresante.
Una última posibilidad, pero tendrá que hacer esto en una máquina "no regular" :-) Puede montar el sistema de archivos ext4 en un dispositivo de bucle y copiar archivos en él sin escribirlo primero en la tarjeta SD. Para una imagen estándar de Raspbian Jessie, sería algo como esto:
Me gusta hacer un fsck forzado en mis sistemas de archivos antes de hacer imágenes. Establece el recuento de montaje en cero en el primer arranque :-)
EDITAR : Después de muchos meses y más experiencia. Quieres mirar u-boot. Reemplace el cargador de arranque con u-boot. Esto se puede hacer desde una "máquina normal". Una vez que tiene u-boot en su lugar, puede arrancar en red una distribución desde la que puede flashear fácilmente la tarjeta sd, o en teoría podría flashear la tarjeta directamente, aunque no tengo idea de lo difícil que sería.
Esencialmente, u-boot trae arranque de red a la Raspberry Pi, algo que no admite por sí solo.
fuente
init=script & init
? El script se ejecutará en segundo plano mientras init se inicia normalmente. El script necesitaría alguna comprobación de condición al principio y, por ejemplo, continuar cuando init haya terminado su trabajo.No recomendaría tocar nada en el área de arranque (excepto
config.txt
) a menos que tenga una comprensión detallada de lo que está haciendo ese material.cmdline.txt
no está diseñado para ejecutar cosas cuando comienza el RPi. Se utiliza para pasar parámetros al kernel de Linux en el arranque.Sugeriría hacer esto a través de SSH. Un script en su escritorio podría empujar un bash / python / java / c / cualquier programa al RPi, ejecutarlo y luego eliminarlo cuando haya terminado. Agregue hilos al script en su escritorio y puede enviarlo a tantos dispositivos como desee al mismo tiempo.
fuente
Podría decirse que si está de acuerdo con modificar la imagen para ejecutar automáticamente un script en el primer arranque, simplemente puede modificar la imagen de la manera en que lo haría su script, y luego guardar esa tarjeta SD en un archivo de imagen y usarla para flashear Tarjetas SD que vas a usar con nuevos RPis. Por ejemplo, si desea que todos sus RPis tengan una determinada entrada
/etc/fstab
, simplemente puede modificarse/etc/fstab
en lugar de escribir un script que realice la modificación.Si es absolutamente necesario acciones de secuencias de comandos (por ejemplo, si cada imagen debe ser modificado de una manera diferente), se podía mover su
/etc/rc.local
a/etc/rc.bak
y poner un guión en/etc/rc.local
el que se reemplaza con/etc/rc.bak
el último comando. Ese script podría realizar las primeras acciones de arranque por sí mismo, o podría llamar a un script particular desde la/boot
partición si lo prefiere.Es posible realizar una ejecución automática tocando solo la
/boot
partición, proporcionando una imagen de disco de arranque especial al núcleo como se describe aquí . Esa imagen contendría los scripts para modificar la partición raíz y luego se eliminaría automáticamenteconfig.txt
. Sin embargo, no estoy seguro de si vale la pena.fuente
Es posible que desee ver mi proyecto Nard, que tiene una solución para su problema:
1) A cada tarjeta SD se le puede asignar una identificación única con una PC con Windows normal como se describe aquí:
http://www.arbetsmyra.dyndns.org/nard/#devsettingsid
2) Enciende todos tus Pis
3) Desactiva el firewall de la PC si es posible
4) Abra una ventana de solicitud de DOS y haga ping a la dirección de transmisión de subred
5) Enumere la tabla ARP con el comando de Windows "arp -a". En la lista encontrará las direcciones MAC e IP de todas las Raspberry Pi cercanas.
6) Conéctese a cada dispositivo con telnet (generalmente también disponible en Windows). La frase de bienvenida mostrará la ID asignada en el paso 1.
fuente