Isso depende inteiramente de quais serviços você deseja ter no seu dispositivo.
Programas
Você pode fazer o Linux inicializar diretamente em um shell . Não é muito útil na produção - quem apenas gostaria de ter um shell - mas é útil como mecanismo de intervenção quando você tem um gerenciador de inicialização interativo: passe init=/bin/sh
para a linha de comando do kernel. Todos os sistemas Linux (e todos os sistemas unix) possuem um shell no estilo Bourne / POSIX /bin/sh
.
Você precisará de um conjunto de utilitários de shell . BusyBox é uma escolha muito comum; ele contém um shell e utilitários comuns de arquivo e manipulação de texto ( cp
, grep
...), configuração de rede ( ping
, ifconfig
...), manipulação de processo ( ps
, nice
...), e várias outras ferramentas de sistema ( fdisk
, mount
, syslogd
, ...). O BusyBox é extremamente configurável: você pode selecionar quais ferramentas deseja e até recursos individuais em tempo de compilação, para obter o tamanho / funcionalidade certos para o seu aplicativo. Além de sh
, o mínimo que você realmente não pode fazer nada sem é mount
, umount
e halt
, mas seria atípico para não ter também cat
, cp
, mv
, rm
,mkdir
, rmdir
, ps
, sync
E um pouco mais. O BusyBox é instalado como um único binário chamado busybox
, com um link simbólico para cada utilitário.
O primeiro processo em um sistema unix normal é chamado init
. Seu trabalho é iniciar outros serviços. BusyBox contém um sistema init. Além do init
binário (geralmente localizado em /sbin
), você precisará de seus arquivos de configuração (geralmente chamados /etc/inittab
- algumas substituições init modernas eliminam esse arquivo, mas você não os encontrará em um pequeno sistema embutido) que indicam quais serviços iniciar e quando. Para o BusyBox, /etc/inittab
é opcional; se estiver ausente, você obtém um shell raiz no console e o script /etc/init.d/rcS
(local padrão) é executado no momento da inicialização.
É tudo o que você precisa, além dos programas que tornam seu dispositivo útil. Por exemplo, no meu roteador doméstico executando uma variante OpenWrt , os únicos programas são o BusyBox nvram
(para ler e alterar as configurações na NVRAM) e os utilitários de rede.
A menos que todos os seus executáveis estejam vinculados estaticamente, você precisará do carregador dinâmico ( ld.so
que pode ser chamado por nomes diferentes, dependendo da escolha da libc e das arquiteturas do processador) e de todas as bibliotecas dinâmicas ( /lib/lib*.so
talvez algumas delas /usr/lib
) exigidas por esses executáveis.
Estrutura de diretórios
O padrão de hierarquia de sistemas de arquivos descreve a estrutura de diretórios comum dos sistemas Linux. Ele é voltado para instalações de desktop e servidor: muitas delas podem ser omitidas em um sistema incorporado. Aqui está um mínimo típico.
/bin
: programas executáveis (alguns podem estar no /usr/bin
lugar).
/dev
: nós do dispositivo (veja abaixo)
/etc
: arquivos de configuração
/lib
: bibliotecas compartilhadas, incluindo o carregador dinâmico (a menos que todos os executáveis estejam vinculados estaticamente)
/proc
: ponto de montagem para o sistema de arquivos proc
/sbin
: programas executáveis. A diferença /bin
é que /sbin
é para programas que são úteis apenas ao administrador do sistema, mas essa distinção não é significativa em dispositivos incorporados. Você pode criar /sbin
um link simbólico para /bin
.
/mnt
: prático para ter em sistemas de arquivos raiz somente leitura como um ponto de montagem inicial durante a manutenção
/sys
: ponto de montagem para o sistema de arquivos sysfs
/tmp
: local para arquivos temporários (geralmente uma tmpfs
montagem)
/usr
: Contém subdiretórios bin
, lib
e sbin
. /usr
existe para arquivos extras que não estão no sistema de arquivos raiz. Se você não tiver isso, poderá criar /usr
um link simbólico para o diretório raiz.
Arquivos de dispositivo
Aqui estão algumas entradas típicas em um mínimo /dev
:
console
full
(escrever nele sempre informa "não resta espaço no dispositivo")
log
(um soquete que os programas usam para enviar entradas de log), se você tiver um syslogd
daemon (como o do BusyBox) lendo
null
(age como um arquivo sempre vazio)
ptmx
e um pts
diretório , se você quiser usar pseudo-terminais (ou seja, qualquer outro terminal que não seja o console) - por exemplo, se o dispositivo estiver em rede e você desejar telnet ou ssh
random
(retorna bytes aleatórios, corre o risco de bloquear)
tty
(sempre designa o terminal do programa)
urandom
(retorna bytes aleatórios, nunca bloqueia, mas pode ser não aleatório em um dispositivo recém-inicializado)
zero
(contém uma sequência infinita de bytes nulos)
Além disso, você precisará de entradas para o seu hardware (exceto interfaces de rede, elas não recebem entradas /dev
): portas seriais, armazenamento etc.
Para dispositivos incorporados, você normalmente criaria as entradas do dispositivo diretamente no sistema de arquivos raiz. Os sistemas high-end têm um script chamado MAKEDEV
para criar /dev
entradas, mas em um sistema incorporado o script geralmente não é empacotado na imagem. Se algum hardware puder ser conectado a quente (por exemplo, se o dispositivo tiver uma porta host USB), ele /dev
deverá ser gerenciado pelo udev (você ainda pode ter um conjunto mínimo no sistema de arquivos raiz).
Ações de inicialização
Além do sistema de arquivos raiz, você precisa montar um pouco mais para a operação normal:
- procfs on
/proc
(praticamente indispensável)
- sysfs on
/sys
(praticamente indispensável)
tmpfs
sistema de arquivos ativado /tmp
(para permitir que os programas criem arquivos temporários que estarão na RAM, em vez de no sistema de arquivos raiz que pode estar em flash ou somente leitura)
- tmpfs, devfs ou devtmpfs on
/dev
se dinâmico (consulte udev em “Arquivos de dispositivo” acima)
- devpts sobre
/dev/pts
se você quiser usar pseudo-terminais [(ver a observação sobre pts
acima)
Você pode criar um /etc/fstab
arquivo e ligar mount -a
ou executar mount
manualmente.
Inicie um daemon syslog (assim como klogd
para logs do kernel, se o syslogd
programa não cuidar disso), se você tiver algum lugar para gravar os logs.
Depois disso, o dispositivo está pronto para iniciar serviços específicos do aplicativo.
Como criar um sistema de arquivos raiz
Esta é uma história longa e diversificada, então tudo o que farei aqui é dar algumas dicas.
O sistema de arquivos raiz pode ser mantido na RAM (carregada de uma imagem (geralmente compactada) em ROM ou flash) ou em um sistema de arquivos baseado em disco (armazenado em ROM ou flash) ou carregado na rede (geralmente através de TFTP ), se aplicável . Se o sistema de arquivos raiz estiver na RAM, torne-o initramfs - um sistema de arquivos RAM cujo conteúdo é criado no momento da inicialização.
Existem muitas estruturas para montar imagens raiz para sistemas incorporados. Existem algumas dicas na FAQ do BusyBox . O Buildroot é popular, permitindo criar uma imagem raiz inteira com uma configuração semelhante ao kernel do Linux e ao BusyBox. OpenEmbedded é outra dessas estruturas.
A Wikipedia possui uma lista (incompleta) de distribuições Linux embarcadas populares . Um exemplo de Linux incorporado que você pode ter perto de você é a família de sistemas operacionais OpenWrt para dispositivos de rede (popular nos roteadores domésticos dos consertadores). Se você quer aprender por experiência, pode experimentar o Linux a partir do Scratch , mas é voltado para sistemas de desktop para entusiastas do que para dispositivos embarcados.
Uma observação sobre o kernel Linux vs Linux
O único comportamento inserido no kernel do Linux é o primeiro programa lançado no momento da inicialização. (Não abordarei as sutilezas do initrd e initramfs aqui.) Este programa, tradicionalmente chamado de init , possui o ID do processo 1 e possui certos privilégios (imunidade a sinais KILL ) e responsabilidades (colher órfãos ). Você pode executar um sistema com um kernel Linux e iniciar o que quiser como primeiro processo, mas o que você tem é um sistema operacional baseado no kernel Linux, e não o que normalmente é chamado de "Linux" - Linux , no senso comum do termo, é um sistema operacional semelhante ao Unix cujo kernel é o kernel Linux. Por exemplo, o Android é um sistema operacional que não é semelhante ao Unix, mas baseado no kernel do Linux.