Es una pregunta sobre las aplicaciones de espacio de usuario, ¡pero escúchame!
Se requieren tres "aplicaciones", por así decirlo, para iniciar una distribución funcional de Linux:
Bootloader: para los embebidos, normalmente es U-Boot, aunque no es un requisito difícil.
Kernel: eso es bastante sencillo.
Sistema de archivos raíz: no se puede iniciar desde un shell sin él. Contiene el sistema de archivos al que se inicia el núcleo y dónde
init
se llama formulario.
Mi pregunta es con respecto al # 3. Si alguien quisiera construir un rootfs extremadamente mínimo (para esta pregunta, digamos que no hay GUI, solo shell), ¿qué archivos / programas se requieren para arrancar en un shell?
linux
embedded
startup
architecture
root-filesystem
MDMoore313
fuente
fuente
Respuestas:
Eso depende completamente de los servicios que desea tener en su dispositivo.
Programas
Puede hacer que Linux arranque directamente en un shell . No es muy útil en la producción, quién querría tener un shell sentado allí, pero es útil como mecanismo de intervención cuando tienes un gestor de arranque interactivo: pasa
init=/bin/sh
a la línea de comando del núcleo. Todos los sistemas Linux (y todos los sistemas unix) tienen un shell de estilo Bourne / POSIX/bin/sh
.Necesitarás un conjunto de utilidades de shell . BusyBox es una opción muy común; que contiene una concha y utilidades comunes de archivo y manipulación de texto (
cp
,grep
, ...), la configuración de red (ping
,ifconfig
, ...), la manipulación del proceso (ps
,nice
, ...), y varias otras herramientas del sistema (fdisk
,mount
,syslogd
, ...). BusyBox es extremadamente configurable: puede seleccionar las herramientas que desee e incluso las características individuales en el momento de la compilación, para obtener el compromiso de tamaño / funcionalidad adecuado para su aplicación. Aparte desh
, lo mínimo que realmente no se puede hacer nada sin esmount
,umount
yhalt
, pero sería atípica para no tener tambiéncat
,cp
,mv
,rm
,mkdir
,rmdir
,ps
,sync
Y algunos más. BusyBox se instala como un solo binario llamadobusybox
, con un enlace simbólico para cada utilidad.Se llama al primer proceso en un sistema Unix normal
init
. Su trabajo es comenzar otros servicios. BusyBox contiene un sistema init. Además delinit
binario (generalmente ubicado en/sbin
), necesitará sus archivos de configuración (generalmente llamados/etc/inittab
, algunos reemplazos de init modernos eliminan ese archivo pero no los encontrará en un pequeño sistema incrustado) que indican qué servicios iniciar y cuando. Para BusyBox,/etc/inittab
es opcional; si falta, obtienes un shell raíz en la consola y el script/etc/init.d/rcS
(ubicación predeterminada) se ejecuta en el momento del arranque.Eso es todo lo que necesita, más allá de los programas que hacen que su dispositivo haga algo útil. Por ejemplo, en mi enrutador doméstico que ejecuta una variante OpenWrt , los únicos programas son BusyBox,
nvram
(para leer y cambiar la configuración en NVRAM), y las utilidades de red.A menos que todos sus ejecutables estén vinculados estáticamente, necesitará el cargador dinámico (
ld.so
que puede ser llamado por diferentes nombres dependiendo de la elección de libc y de las arquitecturas del procesador) y todas las bibliotecas dinámicas (/lib/lib*.so
quizás algunas de ellas incluidas/usr/lib
) requeridas por Estos ejecutables.Estructura de directorios
El estándar de jerarquía del sistema de archivos describe la estructura de directorios común de los sistemas Linux. Está orientado a las instalaciones de escritorio y servidor: se puede omitir mucho en un sistema embebido. Aquí hay un mínimo típico.
/bin
: programas ejecutables (algunos pueden estar en su/usr/bin
lugar)./dev
: nodos de dispositivo (ver más abajo)/etc
: Archivos de configuración/lib
: bibliotecas compartidas, incluido el cargador dinámico (a menos que todos los ejecutables estén vinculados estáticamente)/proc
: punto de montaje para el sistema de archivos proc/sbin
: programas ejecutables. La distinción con/bin
es que/sbin
es para programas que solo son útiles para el administrador del sistema, pero esta distinción no es significativa en dispositivos integrados. Puedes hacer/sbin
un enlace simbólico a/bin
./mnt
: útil para tener en los sistemas de archivos raíz de solo lectura como punto de montaje temporal durante el mantenimiento/sys
: punto de montaje para el sistema de archivos sysfs/tmp
: ubicación de archivos temporales (a menudo untmpfs
montaje)/usr
: Contiene los subdirectoriosbin
,lib
ysbin
./usr
existe para archivos adicionales que no están en el sistema de archivos raíz. Si no tiene eso, puede hacer/usr
un enlace simbólico al directorio raíz.Archivos del dispositivo
Aquí hay algunas entradas típicas en un mínimo
/dev
:console
full
(escribir en él siempre informa "no queda espacio en el dispositivo")log
(un socket que los programas usan para enviar entradas de registro), si tiene unsyslogd
demonio (como el de BusyBox) leyendo de élnull
(actúa como un archivo que siempre está vacío)ptmx
y unpts
directorio , si desea utilizar pseudo-terminales (es decir, cualquier terminal que no sea la consola), por ejemplo, si el dispositivo está conectado en red y desea telnet o ssh enrandom
(devuelve bytes aleatorios, corre el riesgo de bloqueo)tty
(siempre designa la terminal del programa)urandom
(devuelve bytes aleatorios, nunca bloquea pero puede no ser aleatorio en un dispositivo recién iniciado)zero
(contiene una secuencia infinita de bytes nulos)Más allá de eso, necesitará entradas para su hardware (excepto las interfaces de red, estas no reciben entradas
/dev
): puertos serie, almacenamiento, etc.Para los dispositivos integrados, normalmente crearía las entradas del dispositivo directamente en el sistema de archivos raíz. Los sistemas de gama alta tienen una secuencia de comandos llamada
MAKEDEV
para crear/dev
entradas, pero en un sistema integrado, la secuencia de comandos a menudo no se incluye en la imagen. Si parte del hardware puede conectarse en caliente (por ejemplo, si el dispositivo tiene un puerto host USB), udev/dev
debe administrarlo (es posible que aún tenga un conjunto mínimo en el sistema de archivos raíz).Acciones de tiempo de arranque
Más allá del sistema de archivos raíz, debe montar algunos más para el funcionamiento normal:
/proc
(casi indispensable)/sys
(casi indispensable)tmpfs
sistema de archivos activado/tmp
(para permitir que los programas creen archivos temporales que estarán en la RAM, en lugar de en el sistema de archivos raíz que puede estar en flash o solo lectura)/dev
if dinámico (ver udev en "Archivos de dispositivo" arriba)/dev/pts
si desea utilizar [pseudo-terminales (ver el comentariopts
anterior)Puede hacer un
/etc/fstab
archivo y llamarmount -a
, o ejecutarlomount
manualmente.Inicie un demonio syslog (así como
klogd
para los registros del kernel, si elsyslogd
programa no se encarga de eso), si tiene algún lugar para escribir registros.Después de esto, el dispositivo está listo para iniciar servicios específicos de la aplicación.
Cómo hacer un sistema de archivos raíz
Esta es una historia larga y diversa, así que todo lo que haré aquí es dar algunos consejos.
El sistema de archivos raíz puede mantenerse en RAM (cargado desde una imagen (generalmente comprimida) en ROM o flash), o en un sistema de archivos basado en disco (almacenado en ROM o flash), o cargado desde la red (a menudo a través de TFTP ) si corresponde . Si el sistema de archivos raíz está en RAM, conviértalo en initramfs , un sistema de archivos RAM cuyo contenido se crea en el momento del arranque.
Existen muchos marcos para ensamblar imágenes raíz para sistemas embebidos. Hay algunos consejos en las preguntas frecuentes de BusyBox . Buildroot es muy popular, ya que le permite crear una imagen raíz completa con una configuración similar al kernel de Linux y BusyBox. OpenEmbedded es otro de esos marcos.
Wikipedia tiene una lista (incompleta) de distribuciones Linux incrustadas populares . Un ejemplo de Linux embebido que puede tener cerca de usted es la familia de sistemas operativos OpenWrt para dispositivos de red (popular en los enrutadores domésticos de tinkerers). Si desea aprender por experiencia, puede probar Linux desde cero , pero está orientado a sistemas de escritorio para aficionados, en lugar de a dispositivos integrados.
Una nota sobre Linux vs kernel de Linux
El único comportamiento que se integra en el kernel de Linux es que el primer programa que se inicia en el momento del arranque. (No entraré en las sutilezas initrd e initramfs aquí). Este programa, tradicionalmente llamado init , tiene ID de proceso 1 y tiene ciertos privilegios (inmunidad a las señales KILL ) y responsabilidades ( huérfanos cosechadores ). Puede ejecutar un sistema con un kernel de Linux e iniciar lo que quiera como primer proceso, pero luego lo que tiene es un sistema operativo basado en el kernel de Linux, y no lo que normalmente se llama "Linux" - Linux , en el sentido común del término, es un sistema operativo tipo Unix cuyo núcleo es el núcleo de Linux. Por ejemplo, Android es un sistema operativo que no es similar a Unix, sino que se basa en el kernel de Linux.
fuente
Todo lo que necesita es un ejecutable vinculado estáticamente, colocado en el sistema de archivos, de forma aislada. No necesita ningún otro archivo. Ese ejecutable es el proceso de inicio. Puede ser busybox. Eso le brinda un shell y una gran cantidad de otras utilidades, todo en sí mismo. Puede ir a un sistema completamente funcional simplemente ejecutando comandos manualmente en busybox para montar el sistema de archivos raíz de lectura-escritura, crear / nodos de desarrollo, exec real init, etc.
fuente
Si no necesita ninguna utilidad de shell, lo hará un
mksh
binario enlazado estáticamente (por ejemplo, contra klibc - 130K en Linux / i386). Se necesita una/linuxrc
o/init
o/sbin/init
script que las llamadas sólomksh -l -T!/dev/tty1
en un bucle:La
-T!$tty
opción es una adición recientemksh
que le dice que genere un nuevo shell en el terminal dado y espere. (Antes de eso, solo había-T-
que demonizar un programa y-T$tty
generar un terminal pero no esperarlo. Esto no fue tan agradable.) La-l
opción simplemente le dice que ejecute un shell de inicio de sesión (que lee/etc/profile
,~/.profile
y~/.mkshrc
).Esto supone que su terminal es
/dev/tty1
, sustituto. (Con más magia, el terminal se puede descubrir automáticamente./dev/console
No le dará control total del trabajo).Necesita algunos archivos
/dev
para que esto funcione:Arrancar con la opción del núcleo
devtmpfs.mount=1
elimina la necesidad de un relleno/dev
, solo déjelo ser un directorio vacío (adecuado para usar como punto de montaje).Normalmente querrás tener algunas utilidades (de klibc, busybox, beastiebox, toybox o toolbox), pero en realidad no son necesarias.
Es posible que desee agregar un
~/.mkshrc
archivo, que configura $ PS1 y algunos alias y funciones básicos de shell.Una vez hice un initrd comprimido de 171K (371K sin comprimir) para Linux / m68k usando mksh (y su archivo mkshrc de muestra) y solo klibc-utils. (Sin embargo, esto fue antes de que se añadiera -T! Al shell, por lo que generó el shell de inicio de sesión
/dev/tty2
y repitió un mensaje en la consola que le decía al usuario que cambiara de terminal). Funciona bien.Esta es una configuración mínima realmente básica . Las otras respuestas proporcionan excelentes consejos hacia sistemas algo más destacados. Este es un caso real de caso especial.
Descargo de responsabilidad: soy el desarrollador de mksh.
fuente
mksh
.Programa mínimo init hello world paso a paso
Compile un mundo hola sin ninguna dependencia que termine en un bucle infinito.
init.S
:No podemos usar
sys_exit
, o de lo contrario el kernel entra en pánico.Luego:
Esto crea un sistema de archivos con nuestro hello world en
/init
, que es el primer programa de usuario que ejecutará el kernel. También podríamos haber agregado más archivosd/
y serían accesibles desde el/init
programa cuando se ejecute el kernel.Luego,
cd
en el árbol del kernel de Linux, la compilación es la habitual y ejecútela en QEMU:Y deberías ver una línea:
en la pantalla del emulador! Tenga en cuenta que no es la última línea, por lo que debe buscar un poco más arriba.
También puede usar programas en C si los vincula estáticamente:
con:
Puede ejecutar en hardware real con un USB encendido
/dev/sdX
y:Gran fuente sobre este tema: http://landley.net/writing/rootfs-howto.html También explica cómo usar
gen_initramfs_list.sh
, que es un script del árbol de fuentes del kernel de Linux para ayudar a automatizar el proceso.Siguiente paso: configure BusyBox para que pueda interactuar con el sistema: https://github.com/cirosantilli/runlinux
Probado en Ubuntu 16.10, QEMU 2.6.1.
fuente