Ambiente de Desenvolvimento
WSL (Ubuntu 22.04)
Criação da Imagem de Disco
Para alocar espaço para a imagem de disco, utilize o comando fallocate ou gere um arquivo de zeros com dd if=/dev/zero of=$imagem bs=1M count=$tamanho_MB.
Formate o arquivo de imagem com mkfs.ext4 e monte-o com mount -o loop $imagem /mnt.
Caso necessite particionar a imagem, utilize fdisk ou cfdisk para criar as partições. Em seguida, use losetup -fP $imagem para associá-la a um dispositivo de loop. O parâmetro -f encontra automaticamente um dispositivo disponível, e -P faz com que as partições dentro da imagem sejam reconhecidas. Após a associação, monte as partições usando comandos como mount $dispositivo_loop1 /mnt/ponto_montagem.
Compilando o BusyBox
Obtenha o código-fonte do BusyBox. Esta demonstração utiliza a versão 1.36.1.
Opções de compilação principais:
- Binário estático: Ative a opção
STATIC(Build static binary (no shared libs)) emSettingspara gerar binários independentes. - Suporte a Unicode: As opções
UNICODE_SUPPORTeUNICODE_WIDE_WCHARSjá vêm ativadas por padrão nesta versão, oferecendo suporte a caracteres Unicode.
Execute make para compilar e make install para instalar os binários e links simbólicos. Para instalar em um diretório específico (como o nosso ponto de montagem), use make install CONFIG_PREFIX=$mnt.
Compilando o Kernel Linux
Obtenha o código-fonte do kernel. Este guia utiliza o Linux 6.12.7. Configure o kernel conforme suas necessidades com make menuconfig ou similar.
Criando o Sistema de Arquivos Raiz (rootfs)
A instalação do BusyBox fornece apenas os diretórios bin, sbin, usr e o link simbólico linuxrc. É necessário criar a estrutura completa de diretórios do sistema:
bin boot dev etc home lib mnt opt proc root run sbin sys tmp usr var
Crie esses diretórios dentro do ponto de montagem $mnt. Como as operações de montagem requerem privilégios elevados, é provável que seja necessário usar sudo para criar os arquivos. Teste o ambiente com chroot $mnt /bin/sh.
Executando com QEMU
Crie um script para iniciar a VM com o QEMU:
#!/bin/sh
qemu-system-x86_64 \
-kernel /caminho/para/bzImage \
-hda /caminho/para/rootfs.img \
-nographic \
-append "console=ttyS0 root=/dev/sda init=/linuxrc"
Parâmetros principais:
-kernel: Define o arquivo de imagem do kernel (bzImage).-hda: Especifica a imagem de disco rígido virtual.-nographic: Redireciona a saída para o terminal em vez de abrir uma janela gráfica.-append: Passa argumentos para o kernel na inicialização.console=ttyS0: Redireciona a saída do console para a porta serial, visível no terminal do host.root=/dev/sda: Indica o dispositivo da partição raiz (geralmentesdaem VMs).init=/linuxrc: Especifica o processo inicial a ser executado, que é o BusyBox.
Configuração da Inicialização
O BusyBox, ao atuar como init, procura pelo arquivo /etc/inittab. Crie-o com o seguinte conteúdo básico:
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
Formato: <id>:<runlevel>:<ação>:<processo>
A primeira linha instrui o sistema a executar o script /etc/init.d/rcS durante a inicialização (sysinit). A segunda abre um shell interativo (respawn).
Crie e configure o script /etc/init.d/rcS:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
# Montagem de sistemas de arquivos
mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
mount -o remount,rw /
# Popule o diretório /dev com base no kernel
mdev -s
Lembre-se de tornar o script executável: chmod +x /etc/init.d/rcS. Após esta configuração, a VM deve iniciar e fornecer um shell.
Configurações Adicionais
Usuário e Login
Para identificar o usuário root, crie o arquivo /etc/passwd:
root:x:0:0::/root:/bin/sh
Crie também o arquivo /etc/shadow para definir senhas:
root::1::::::
Uma senha vazia no campo :: permite login sem senha. Use o comando passwd dentro da VM para definir uma senha segura, que será gravada neste arquivo.
Modifique o /etc/inittab para exigir login:
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty -L console 0 vt100
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
Nome do Host
Defina o nome do host no arquivo /etc/hostname (ex: meu-host). Carregue-o adicionando a seguinte linha ao final do script /etc/init.d/rcS:
hostname -F /etc/hostname
Configuração de Rede (dentro da VM)
Adicione as seguintes linhas ao /etc/init.d/rcS para configurar a interface de loopback e uma interface de rede estática:
# Rede
ifconfig lo up
ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
route add default gw 192.168.1.1 eth0
Configure um servidor DNS editando /etc/resolv.conf:
nameserver 8.8.8.8
Configuração da Rede no Host (WSL)
No host WL, execute os seguintes comandos para criar um dispositivo TAP que atuará como gateway para a VM:
ip tuntap add dev tap0 mode tap
ip link set dev tap0 up
ip addr add 192.168.1.1/24 dev tap0
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.1/24 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
Isso configura o tap0 com o IP 192.168.1.1 (o gateway para a VM) e habilita o mascaraemnto de rede (NAT), permitindo que a VM acesse a rede externa. Teste a conectividade da VM com ping 192.168.1.1 e, após configurar o DNS, com ping www.example.com.