Manual
do
Maker
.
com
Linux embedded e SLITaz - Se não conheceu esse modelo, está perdendo uma boa oportunidade de ver um embarcado multi-boot com diversas ferramentas interessantes!
SLITaz - Seguindo o cronograma, vamos primeiramente visualizar como acontece um boot com o mínimo de recursos possíveis. O processo é muito simples, mas servirá como base para o que vem por ai.
Primeiramente procure por uma imagem do Phantom, qualquer versão.
Basicamente o Phantom é um kernel, um initrd e um bootloader - no caso, o syslinux. O processo para gerar uma iso 'bootável' não é o mesmo para efetuar boot por um HD por exemplo. Já quando se faz o boot pelo pendrive, o processo é bastante parecido. O processo de boot de um sistema operacional está brevemente descrito no primeiro post da série, mas agora vamos direcioná-lo ao Phantom.
Quando o boot é efetuado por um CD, o dispositivo deve estar referenciado na sequência de boot do hardware como dispositivo de boot primário. Para tal, é necessário entrar no menu da BIOS. Diversas motherboards permitem que se acesse o menu de boot através da tecla F8 enquanto a máquina está em processo de POST (Power On Self Test). Selecionado esse dispositivo, então é iniciado o menu de boot, que foi configurado de forma a ser exibido e com um timeout de 10 segundos.
Ao selecionar uma das entradas do menu, o kernel e o initrd são carregados para a memória. O Kernel se auto-descomprime seguidamente fazendo o mesmo processo com o initrd. Após a descompressão do initrd em uma área reservada de memória, o kernel chama o programa init e finaliza sua parte na tarefa de boot inicial.
Como explicado no primeiro post, o initrd é uma estrutura raiz mínima necessária para preparação de um boot inicial. Ele é utilizado para preparar o ambiente para o sistema raiz instalado em disco. O initrd possui as rotinas de preparação do hardware, modulos que devem ser pré-carregados, criação dos dispositivos e então monta a raiz do disco.
Inicialmente parece obscuro o processo de boot inicial porque não se vê realmente a origem desse processo. Sabendo que o processo é iniciado pelo programa init, tem-se agora alguma pista; mas vamos além da pista.
Quando o programa init é chamado pelo kernel, ele lê em /etc/init/ os scripts lá contidos. O primeiro é o boot.conf, com o seguinte conteúdo:
# Phantom startup
start on startup
console output
task
script
echo "Booting Phantom ..."
exec /etc/init.d/boot
end script
Ou seja, a primeira tarefa do startup é chamar o /etc/init.d/boot. Esse script de boot poderia ter outro nome e outro conteúdo dependendo do propósito, então para não entrar em detalhes nesse momento (que não é o propósito), resumidamente esse script de boot faz todo o processo de inicialização do Phantom e chama a interface.
Então, para o boot mínimo vamos utilizar apenas o kernel e o initrd.
Durante o desenvolvimento pode ser uma tarefa desagradável efetuar os testes se não tiver disponível uma ferramenta pra agilizar o processo de testes. O Qemu é uma ferramenta essencial para tais testes, mas o bom mesmo é compilá-lo, porque quando instalado via ferramentas do sistema é muito comum que o pacote principal contenha apenas o boot para a plataforma x86. Compilando-o você garantirá suporte a outras arquiteturas como ARM por exemplo.
Baixe-o daqui e compile-o. Em seu site também se encontra toda a documentação para sanar suas dúvidas, sendo que aqui veremos apenas alguns comandos, requeridos para o teste.
Como citado lá em cima, nesse momento da leitura seu download do Phantom já deve ter terminado. Todo o ambiente é (obviamente) Linux, assim como todos os comandos de sistema disponíveis aqui.
Algumas pessoas não sabem, mas para montar o arquivo iso deve-se utilizar o dispositivo loop. O comando é simples e normalmente só é possível executá-lo como root. Execute-o e faça a copia do kernel e initrd para /tmp:
mount -o loop phantom-1.5.iso /mnt
cp /mnt/phantom/* /tmp/
umount /mnt
Agora façamos o boot com o Qemu que você já deve ter a compilação concluída:
qemu-system-i386 -kernel /tmp/vmlinuz -initrd /tmp/initrd.lz -append vga=0x314
Esse comando faz com que a máquina virtual use seu gerenciador de boot com os parâmetros passados por linha. Essa é uma boa forma de efetuar um boot para quem está desenvolvendo e certamente você o preferirá quando for testar a sua compilação de sistema. Para testar um boot diretamente da iso, é um pouco mais simples:
qemu-system-i386 -cdrom phantom-1.5.iso
Para desenvolvimento, você talvez queira um disco para testes. Esse disco pode ser criado com o programa qemu-img.
Então, quando se pensa em um boot, pensa-se em kernel+initrd. Fechado? - Eu respondo:
Um boot pode iniciar diversos initrd de uma vez. Vamos a um exemplo, desmantelando um sistema pequeno muito legal chamado SLITaz, que você encontra aqui. Baixa a iso e vamos dissecá-la.
Alguns sistemas utilizam basicamente o kernel e initrd. Outros utilizam também Cloop, Squashfs, Unionfs, mas não vamos entrar em muitos detalhes sobre isso. De fato é necessário saber que recursos cada peça do sistema está utilizando, portanto entra em ação uma ferramenta do sistema importantíssima - o programa file.
O file é um programa utilizado para recolher informações do arquivo pretendido, seja um programa, um arquivo texto, uma imagem ou qualquer outra coisa hospedada sobre o sistema de arquivos. Vamos iniciar a análise do sistema SLITaz:
mount -o loop,ro slitaz-4.0.iso /mnt
ls -s /mnt/boot
Com isso já vemos algumas coisas interessantes:
total 37319
2435 bzImage 8 isolinux 8293 rootfs3.gz
170 gpxe 12650 rootfs1.gz 4993 rootfs4.gz
2 grub 6335 rootfs2.gz 2435 vmlinuz-2.6.37-slitaz
O arquivo bzImage e o arquivo vmlinuz-2.6.37-slitaz possuem o mesmo tamanho. Presumo que sejam o mesmo arquivo, mas para confirmar, podemos utilizar o programa md5sum (sha256sum, ou outro) para verificar o hash do arquivo:
$ md5sum boot/bzImage boot/vmlinuz-2.6.37-slitaz
0de74e822e00a62ad0eeba3c52903153 boot/bzImage
0de74e822e00a62ad0eeba3c52903153 boot/vmlinuz-2.6.37-slitaz
São o mesmo arquivo. E porque? - não sei. Olhando o arquivo de menu de boot em boot/isolinux/isolinux.cfg do SLITaz. Não há referências para o arquivo vmlinuz-2.6.37-slitaz e realmente não vejo o porque, então pelo visto duplicaram sem querer. Mas já que falamos do menu de boot, vamos ver a primeira entrada que referencia os initrd:
LABEL core
MENU LABEL SliTaz core Live
KERNEL /boot/bzImage
append initrd=/boot/rootfs4.gz,/boot/rootfs3.gz,/boot/rootfs2.gz,/boot/rootfs1.gz rw root=/dev/null vga=normal autologin
Olha que legal! Basta separar os initrds por vírgula!
Isso é útil para modularizar o boot, sendo que a última opção do menu de boot é um sistema mínimo, onde a descompressão é feita apenas com o rootfs1.gz. Para verificar o que a iso oferece, faça um boot com o Qemu em cada uma das entradas.
Agora será necessário descomprimir o rootfs para ver seu conteúdo. Olhando para ele, bastaria usar gzip -d rootfs1.gz, mas na verdade não é bem assim:
$ gzip -d rootfs1.gz
gzip: rootfs1.gz: not in gzip format
E nesse caso o comando file também não ajudou:
# file rootfs1.gz
rootfs1.gz: data
Aqui poderia parecer o fim da linha; parece então que o rootfs não está comprido, e foi o que pensei da primeira vez que estava fazendo a descompressão. Esse arquivo sem compressão é um arquivo cpio. Um arquivo gerado com cpio contém metadados; você encontrará mais informações pelo google, mas dê uma lida no manual (digite 'man 5 cpio' no terminal).
De fato o arquivo contém uma compressão, que é o novo formato suportado pelo kernel, o lzma. O que causou a confusão foi o sufixo .gz, bastando renomeá-o antes de fazer a descompressão:
mkdir /tmp/taz
cp boot/rootfs* /tmp/taz/
cd /tmp/taz
mv rootfs1.gz rootfs1.lzma
lzma -d rootfs1.lzma
E agora, a extração do arquivo resultante, precedido pela verificação do tipo do arquivo:
$ file rootfs1
rootfs1: ASCII cpio archive (SVR4 with no CRC)
$cpio -idmuv <rootfs1
Observe a descompressão acontecendo e pronto! Uma raiz no diretório taz! Opa, estão faltando diretórios para chamar isso de raiz. Extraia os demais rootfs juntos então e digite o comando ls. Como se pode ver, lá está o init. nesse caso, um script shell que chama o /sbin/init, ou seja, um processo de boot diferente do Phantom.
Explorando um pouco a estrutura, podemos coletar informações sobre a construção do sistema; biblioteca C utilizada e arquitetura, por exemplo:
$ file bin/ntfs-3g
ntfs-3g: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.30, stripped
strings ntfs-3g |grep libc
libc.so.6
__libc_start_main
Ou seja, o sistema é baseado na mesma arquitetura e biblioteca de um desktop 32 bits padrão. Desse modo, é possível incluir seus próprios programas sem precisar compilar nada, apenas copiando-os do seu sistema de 32 bits. Depois disso, basta fechar um arquivo cpio, comprimí-lo, substituí-lo na iso e efetuar o boot.
A reconstrução será explicada no próximo post, onde trataremos de compilar um sistema baseado no buildroot.
Boa diversão com seus testes!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.