Iniciando o GNU/Linux em uma placa ARM do zero (usando Kali e iMX.6 como exemplo)

tl dr dr: Estou construindo uma imagem Kali Linux para um computador ARM, no programa debootstrap, linux и u-boot.

Iniciando o GNU/Linux em uma placa ARM do zero (usando Kali e iMX.6 como exemplo)

Se você comprou algum software de placa única não muito popular, poderá se deparar com a falta de uma imagem de sua distribuição favorita para ele. Aproximadamente a mesma coisa aconteceu com planejado Flipper Um. Simplesmente não existe Kali Linux para IMX6 (estou me preparando), então tenho que montá-lo sozinho.

O processo de download é bastante simples:

  1. O hardware é inicializado.
  2. De alguma área do dispositivo de armazenamento (cartão SD/eMMC/etc) o bootloader é lido e executado.
  3. O bootloader procura o kernel do sistema operacional e o carrega em alguma área da memória e o executa.
  4. O kernel carrega o resto do sistema operacional.

Este nível de detalhe é suficiente para minha tarefa, você pode ler os detalhes em outro artigo. As “algumas” áreas mencionadas acima diferem de placa para placa, o que cria algumas dificuldades de instalação. Carregando plataformas de servidor ARM tentando padronizar usando UEFI, mas embora não esteja disponível para todos, você terá que montar tudo separadamente.

Construindo o sistema de arquivos raiz

Primeiro você precisa preparar as seções. Das U-Boot suporta diferentes sistemas de arquivos, escolhi FAT32 para /boot e ext3 para root, este é o layout de imagem padrão para Kali no ARM. Usarei o GNU Parted, mas você pode fazer o mesmo de uma forma mais familiar fdisk. Você também precisará dosfstools и e2fsprogs para criar um sistema de arquivos: apt install parted dosfstools e2fsprogs.

Marcamos o cartão SD:

  1. Marque o cartão SD como usando particionamento MBR: parted -s /dev/mmcblk0 mklabel msdos
  2. Crie uma seção em /boot para 128 megabytes: parted -s /dev/mmcblk0 mkpart primary fat32 1MiB 128MiB. O primeiro megabyte perdido deve ser deixado para a própria marcação e para o bootloader.
  3. Criamos um sistema de arquivos raiz para toda a capacidade restante: parted -s /dev/mmcblk0 mkpart primary ext4 128MiB 100%
  4. Se de repente seus arquivos de partição não foram criados ou alterados, você precisa executar `partprobe`, então a tabela de partição será relida.
  5. Crie um sistema de arquivos para a partição de inicialização com o rótulo BOOT: mkfs.vfat -n BOOT -F 32 -v /dev/mmcblk0p1
  6. Crie um sistema de arquivos raiz com um rótulo ROOTFS: mkfs.ext3 -L ROOTFS /dev/mmcblk0p2

Ótimo, agora você pode preenchê-lo. Para isso você precisará adicionalmente debootstrap, um utilitário para criar sistemas de arquivos raiz para sistemas operacionais semelhantes ao Debian: apt install debootstrap.

Coletamos FS:

  1. Monte a partição em /mnt/ (use um ponto de montagem mais conveniente): mount /dev/mmcblk0p2 /mnt
  2. Na verdade, preenchemos o sistema de arquivos: debootstrap --foreign --include=qemu-user-static --arch armhf kali-rolling /mnt/ http://http.kali.org/kali. Parâmetro --include indica a instalação adicional de alguns pacotes, especifiquei um emulador QEMU construído estaticamente. Ele permite que você execute chroot no ambiente ARM. O significado das opções restantes pode ser encontrado em man debootstrap. Não esqueça que nem toda placa ARM suporta a arquitetura armhf.
  3. Devido à diferença na arquitetura debootstrap é realizado em duas etapas, a segunda é realizada assim: chroot /mnt/ /debootstrap/debootstrap --second-stage
  4. Agora você precisa estragar tudo: chroot /mnt /bin/bash
  5. Preencher /etc/hosts и /etc/hostname alvo FS. Preencha igual ao conteúdo do seu computador local, mas lembre-se de substituir o nome do host.
  6. Você pode personalizar todo o resto. Em particular, eu instalo locales (chaves de repositório), reconfigurar localidades e fuso horário (dpkg-reconfigure locales tzdata). Não se esqueça de definir a senha com o comando passwd.
  7. Defina uma senha para root a equipe passwd.
  8. A preparação da imagem para mim termina com o preenchimento /etc/fstab dentro /mnt/.

Farei o upload de acordo com as tags criadas anteriormente, então o conteúdo ficará assim:

LABEL=ROOTFS / erros automáticos=remount-ro 0 1
LABEL=BOOT /inicialização automática padrões 0 0

Finalmente, você pode montar a partição de boot, precisaremos dela para o kernel: `mount /dev/mmcblk0p1 /mnt/boot/`

Compilação Linux

Para construir o kernel (e depois o gerenciador de inicialização) no Debian Testing, você precisa instalar um conjunto padrão de arquivos de cabeçalho GCC, GNU Make e GNU C Library para a arquitetura alvo (para mim armhf), bem como cabeçalhos OpenSSL, calculadora de console bc, bison и flex: apt install crossbuild-essential-armhf bison flex libssl-dev bc. Como o carregador padrão procura o arquivo zImage no sistema de arquivos da partição de inicialização, é hora de dividir a unidade flash.

  1. Demora muito para clonar o kernel, então vou apenas baixar: wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.9.1.tar.xz. Vamos descompactar e ir para o diretório de origem: tar -xf linux-5.9.1.tar.xz && cd linux-5.9.1
  2. Configure antes da compilação: make ARCH=arm KBUILD_DEFCONFIG=imx_v6_v7_defconfig defconfig. A configuração está localizada no diretório arch/arm/configs/. Se não houver, você pode tentar encontrar e baixar um já pronto e passar o nome do arquivo neste diretório como parâmetro KBUILD_DEFCONFIG. Como último recurso, passe imediatamente para o próximo ponto.
  3. Opcionalmente, você pode ajustar as configurações: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
  4. E faça a compilação cruzada da imagem: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
  5. Agora você pode copiar o arquivo do kernel: cp arch/arm/boot/zImage /mnt/boot/
  6. E arquivos do DeviceTree (descrição do hardware na placa): cp arch/arm/boot/dts/*.dtb /mnt/boot/
  7. E instale os módulos coletados na forma de arquivos separados: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- INSTALL_MOD_PATH=/mnt/ modules_install

O kernel está pronto. Você pode desmontar tudo: umount /mnt/boot/ /mnt/

O U-Boot

Como o bootloader é interativo, tudo que você precisa para testar seu funcionamento é a própria placa, um dispositivo de armazenamento e, opcionalmente, um dispositivo USB para UART. Ou seja, você pode adiar o kernel e o sistema operacional para mais tarde.

A grande maioria dos fabricantes oferece o uso do Das U-Boot para a inicialização. O suporte completo geralmente é fornecido em seu próprio fork, mas eles não se esquecem de contribuir com o upstream. No meu caso, a placa é suportada em linha principalé por isso garfo Eu ignorei.

Vamos montar o próprio bootloader:

  1. Clonamos o branch estável do repositório: git clone https://gitlab.denx.de/u-boot/u-boot.git -b v2020.10
  2. Vamos para o próprio diretório: cd u-boot
  3. Preparando a configuração de compilação: make mx6ull_14x14_evk_defconfig. Isso só funciona se a configuração estiver no próprio Das U-Boot, caso contrário você precisará encontrar a configuração do fabricante e colocá-la na raiz do repositório em um arquivo .configou monte de qualquer outra maneira recomendada pelo fabricante.
  4. Montamos a própria imagem do bootloader usando um compilador cruzado armhf: make CROSS_COMPILE=arm-linux-gnueabihf- u-boot.imx

Como resultado obtemos o arquivo u-boot.imx, esta é uma imagem pronta que pode ser gravada em uma unidade flash. Escrevemos no cartão SD, pulando os primeiros 1024 bytes. Por que escolhi o Target u-boot.imx? Por que perdi exatamente 1024 bytes? Isto é o que eles propõem fazer em documentação. Para outras placas, o processo de construção e gravação de imagens pode ser um pouco diferente.

Pronto, você pode inicializar. O bootloader deve reportar sua própria versão, algumas informações sobre a placa e tentar encontrar a imagem do kernel na partição. Se não tiver êxito, ele tentará inicializar pela rede. Em geral, a saída é bastante detalhada, você pode encontrar o erro se houver algum problema.

Em vez de uma conclusão

Você sabia que a testa de um golfinho não é ossuda? É literalmente um terceiro olho, uma lente gordurosa para ecolocalização!

Iniciando o GNU/Linux em uma placa ARM do zero (usando Kali e iMX.6 como exemplo)

Iniciando o GNU/Linux em uma placa ARM do zero (usando Kali e iMX.6 como exemplo)

Fonte: habr.com