Introdução
Nesta série de artigos, vou discutir o sistema de construção de distribuições buildroot e compartilhar a experiência de sua customização. Aqui, abordarei a experiência prática de criar um pequeno sistema operacional com interface gráfica e funcionalidade mínima.
Antes de tudo, não devemos confundir sistema de construção e distribuição. O Buildroot pode montar um sistema a partir de um conjunto de pacotes que foram apresentados a ele. O Buildroot é baseado em arquivos make e, portanto, possui enormes possibilidades de customização. Substituir um pacote por outra versão, adicionar seu próprio pacote, alterar as regras de construção do pacote, customizar o sistema de arquivos após a instalação de todos os pacotes? Tudo isso é possível com o buildroot.
Na Rússia, o buildroot é utilizado, mas na minha opinião há poucas informações em russo para iniciantes.
O objetivo do trabalho é construir uma distribuição com inicialização ao vivo, interface icewm e navegador. A plataforma-alvo é o virtualbox.
Por que construir sua própria distribuição? Muitas vezes, é necessário um funcionalidade limitada com recursos restritos. Mais frequentemente, na automação, é preciso criar firmwares. Adaptar uma distribuição de propósito geral, removendo pacotes desnecessários e transformando-a em um firmware, é um caminho mais trabalhoso do que construir uma nova distribuição. O uso do Gentoo também tem suas limitações.
O sistema Buildroot é muito poderoso, mas não fará nada por você. Ele apenas proporciona possibilidades e automatiza o processo de construção.
Sistemas de construção alternativos (yocto, open build system e outros) não são considerados nem comparados.
Onde encontrar e como começar
Site do projeto — . Aqui você pode baixar a versão atual e ler o manual. Também é possível se conectar à comunidade, há rastreador de bugs, listas de discussão e canal irc.
O Buildroot opera com defconfigs para a placa de montagem alvo. Defconfig é um arquivo de configuração que contém apenas opções que não possuem valores padrão. Ele define o que e como será construído. É possível ajustar separadamente as configurações do busybox, linux-kernel, uClibc, bootloaders u-boot e barebox, mas todos estarão vinculados à placa alvo.
Após descompactar o arquivo baixado ou clonar do git, temos um buildroot pronto para uso. Detalhes sobre a estrutura de diretórios podem ser encontrados no manual, mas vou falar sobre os mais importantes:
board — catálogo com arquivos específicos para cada placa. Podem ser scripts para a criação de imagens do sistema (iso, sdcart, cpio e outros), catálogo overlay, configuração de kernels e mais
configs — a definição defconfig da placa. Defconfig é uma configuração incompleta da placa. Ele armazena apenas os parâmetros que diferem das configurações padrão
dl — diretório com os códigos fonte/arquivos baixados para compilar
output/target — sistema de arquivos montado do SO resultante. A partir dele, imagens para boot/instalação são criadas
output/host — utilitários host para compilar
output/build — pacotes compilados
A configuração da compilação é feita através do KConfig. Este mesmo sistema é utilizado para compilar o kernel linux. Lista dos comandos mais frequentemente utilizados (executar no diretório buildroot):
- make menuconfig — chamar a configuração da compilação. Também pode ser feito utilizando uma interface gráfica (make nconfig, make xconfig, make gconfig)
- make linux-menuconfig — chamar a configuração do kernel.
- make clean — limpar os resultados da compilação (tudo que está no output)
- make — compilar o sistema. Nesse processo, não há recompilação de processos já construídos
- make defconfig_name — mudar a configuração para um determinado defconfig
- make list-defconfigs — mostrar a lista de defconfigs
- make source — apenas baixar os arquivos de instalação, sem compilar.
- make help — exibir a lista de comandos disponíveis
Observações importantes e dicas úteis
O Buildroot não recompila pacotes já construídos! Portanto, pode haver situações em que uma recompilação completa será necessária.
É possível recompilar um pacote específico com o comando make packagename-rebuild. Por exemplo, pode-se recompilar o kernel linux:
make linux-rebuildO Buildroot armazena o estado de qualquer pacote criando arquivos .stamp no diretório output/build/$packagename:

Consequentemente, é possível recompilar o root-fs e imagens sem recompilar pacotes:
rm output/build/host-gcc-final-*/.stamp_host_installed; rm -rf output/target; find output/ -name ".stamp_target_installed" | xargs rm -rf; makeVariáveis úteis
No Buildroot há um conjunto de variáveis para facilitar a configuração
- $TOPDIR — diretório raiz do buildroot
- $BASEDIR — diretório OUTPUT
- $HOST_DIR, $STAGING_DIR, $TARGET_DIR — diretórios para compilação do host fs, staging fs, target fs.
- $BUILD_DIR — diretório com pacotes descompactados e construídos
Visualização
No Buildroot há a possibilidade de visualização. É possível construir um gráfico de dependências, um gráfico de tempo de compilação, um gráfico do tamanho dos pacotes no sistema final. Os resultados são gerados em arquivos pdf (as opções incluem svn, png) no diretório output/graph.
Exemplos de comandos de visualização:
fazer gráfico-dependênciasconstruir árvore de dependênciasfazer <pkg>-gráfico-dependênciasconstruir árvore de dependências de um pacote específicoBR2_GRAPH_OUT=png fazer gráfico-construirconstruir gráfico de tempo de construção com saída em PNGfazer gráfico-tamanhoconstruir gráfico de tamanhos de pacotes
Scripts úteis
No diretório buildroot, há um subdiretório utils com scripts úteis. Por exemplo, há um script que verifica a validade das descrições dos pacotes. Isso pode ser útil ao adicionar seus próprios pacotes (farei isso mais tarde). No arquivo utils/readme.txt há uma descrição desses scripts.
Vamos construir uma distribuição de estoque
É importante lembrar que todas as operações são realizadas em nome de um usuário comum, não root.
Todos os comandos são executados na raiz do buildroot. A distribuição do buildroot já possui um conjunto de configurações para muitas placas e virtualização comuns.
Vamos ver a lista de configurações:

Mudando para a configuração qemu_x86_64_defconfig
fazer qemu_x86_64_defconfigE iniciamos a construção
makeA construção é finalizada com sucesso, vamos olhar os resultados:
![]()
O Buildroot gerou imagens que podem ser iniciadas no Qemu para verificar se funcionam.
qemu-system-x86_64 -kernel output/images/bzImage -hda output/images/rootfs.ext2 -append "root=/dev/sda rw" -s -SO resultado é um sistema iniciado no qemu:

Criando a configuração da sua placa
Adicionando arquivos da placa
Vamos ver a lista de configurações:

Na lista, vemos pc_x86_64_efi_defconfig. Vamos criar nossa placa, copiando-a da configuração:
cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfigImediatamente criaremos o diretório da placa para armazenar nossos scripts, rootfs-overlay e outros arquivos necessários:
mkdir board/my_x86_boardMudando para este defconfig:
fazer my_x86_board_defconfigAssim, agora a configuração da construção (armazenada em .config na raiz do diretório do buildroot) corresponde à máquina alvo x86-64 legacy (bios).
Vamos copiar a configuração do kernel-linux (será útil posteriormente):
cp board/pc/linux.config board/my_x86_board/Configuração dos parâmetros de construção através do KConfig
Iniciamos a configuração:
fazer menuconfig A janela do KConfig será aberta. Há a possibilidade de configurar com interface gráfica (fazer nconfig, fazer xconfig, fazer gconfig):

Entramos na primeira seção Opções de Destino. Aqui podemos escolher a arquitetura alvo para a qual a construção será realizada.

Opções de construção — aqui há várias configurações de construção. Podemos especificar diretórios com os códigos fonte, número de threads para a construção, espelhos para download dos códigos fontes e outras configurações. Manteremos as configurações padrão.
Toolchain – aqui é onde o próprio conjunto de ferramentas de construção é configurado. Mais sobre isso a seguir.

Tipo de toolchain – o tipo de toolchain utilizado. Isso pode ser o embutido no buildroot ou um toolchain externo (pode-se especificar um diretório com o já compilado ou um URL para download). Para diferentes arquiteturas, existem opções adicionais. Por exemplo, para arm, pode-se simplesmente escolher a versão do toolchain externo Linaro.
Biblioteca C – escolha da biblioteca C. Isso afeta o funcionamento de todo o sistema. Geralmente, é utilizada a glibc, que suporta toda a funcionalidade possível. Mas ela pode ser grande demais para um sistema embutido, por isso, geralmente opta-se pela uclibc ou musl. Nós escolheremos a glibc (isso será necessário para a utilização do systemd).
Headers do Kernel e Headers do Kernel Personalizados – deve coincidir com a versão do kernel que estará no sistema construído. Para os headers do kernel, também pode-se especificar o caminho para o tarball ou um repositório git.
VERSÕES DO COMPILADOR GCC – escolha da versão do compilador que será utilizada para a construção
Habilitar suporte a C++ – vamos escolher construir com suporte às bibliotecas C++ no sistema. Isso será útil mais tarde.
Opções adicionais do gcc – é possível definir opções adicionais do compilador. Para nós, isso não é necessário por enquanto.
A configuração do sistema permite definir os parâmetros futuros do sistema criado:

A maioria dos itens é compreensível pelo nome. Vamos prestar atenção nos seguintes pontos:
Caminho para as tabelas de usuários — tabela com os usuários a serem criados ().
Exemplo de arquivo. Um usuário chamado user será criado com a senha admin, gid/uid automático, shell /bin/sh, grupo padrão user, membro do grupo root, comentário Foo user
[alexey@alexey-pc buildroot ]$ cat board/my_x86_board/users.txt
user -1 user -1 =admin /home/user /bin/sh root Foo userDiretórios de sobreposição do sistema de arquivos root — diretório que se sobrepõe ao target-fs compilado. Adiciona novos arquivos e substitui os existentes.
Scripts personalizados para serem executados antes de criar imagens do sistema de arquivos — scripts executados imediatamente antes da compactação do sistema de arquivos em imagens. Vamos deixar o script vazio por enquanto.
Vamos para a seção Kernel

Aqui são definidas as configurações do kernel. O próprio kernel é configurado através do make linux-menuconfig.
A versão do kernel pode ser definida de várias maneiras: escolher entre as opções disponíveis, inserir a versão manualmente, indicar o repositório ou um tarball pronto.
Configuração do Kernel — caminho para o arquivo de configuração do kernel. Pode-se escolher a configuração padrão para a arquitetura selecionada ou defconfig do Linux. Nos fontes do Linux há um conjunto de defconfigs para diferentes sistemas-alvo. É possível encontrar o desejado, . Por exemplo, para a placa beagle bone black pode-se .
A seção Target packages permite escolher quais pacotes serão instalados no sistema a ser criado. Por enquanto, vamos deixar sem alterações. Mais tarde, adicionaremos nossos pacotes a esta lista.
Imagens de sistema de arquivos — uma lista de imagens de sistemas de arquivos que serão criadas. Vamos adicionar a imagem iso

Bootloaders — seleção de bootloaders a serem criados. Vamos escolher isolinux

Configuração do Systemd
O Systemd se torna um dos pilares do linux, ao lado do kernel e do glibc. Portanto, coloquei sua configuração em um item separado.
É configurado através do make menuconfig, depois Target packages → System tools → systemd. Aqui você pode especificar quais serviços do systemd serão instalados e iniciados na inicialização do sistema.

Salvando a configuração do sistema
Salvamos esta configuração através do KConfig.
Depois, salvaremos nosso defconfig:
make savedefconfigConfiguração do kernel Linux
A configuração do kernel linux é chamada pelo seguinte comando:
make linux-menuconfigVamos adicionar suporte para a placa de vídeo do Virtualbox

Vamos adicionar suporte à integração do Virtualbox Guest

Salvamos e saímos. IMPORTANTE: a configuração será salva em output/build/linux-$version/config, mas não em board/my_x86_board/linux.config

Portanto, é necessário copiar manualmente a configuração para o local de armazenamento:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.configDepois disso, realizaremos uma reconstrução completa de todo o sistema. Como o buildroot não reconstruirá o que já foi construído, será necessário especificar manualmente os pacotes para reconstrução. Para não perder tempo e paciência, é mais fácil reconstruir um sistema pequeno por completo):
make clean; makeApós a conclusão da construção, iniciamos o VirtualBox (testado nas versões 5.2 e 6.0) com inicialização a partir do cd. Parâmetros do sistema:

Início a partir do iso criado:

Lista de materiais utilizados
- Manual do Buildroot
Fonte: habr.com
