Manual

do

Maker

.

com

Introdução a sistemas embarcados P3 SLITaz

Introdução a sistemas embarcados P3 SLITaz

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!

Fazendo um boot mínimo

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.

Processo de boot do Phantom

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.

O kernel

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.

O initrd

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.

O programa init

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.

Boot com Qemu

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.

  • Monte a iso

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:

  • Não.

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.

Dissecando um sistema: SLITaz

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!

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.