Introduccion
En esta serie de artículos quiero considerar el sistema de distribución buildroot y compartir la experiencia de personalizarlo. Aquí habrá experiencia práctica en la creación de un sistema operativo pequeño con una interfaz gráfica y una funcionalidad mínima.
En primer lugar, no debe confundir el sistema de compilación y la distribución. Buildroot puede construir un sistema a partir del conjunto de paquetes que se le ofreció. Buildroot se basa en archivos MAKE y, por lo tanto, tiene enormes capacidades de personalización. ¿Reemplazar el paquete con otra versión, agregar su paquete, cambiar las reglas para construir el paquete, personalizar el sistema de archivos después de instalar todos los paquetes? Buildroot puede hacer todo esto.
En Rusia, se usa buildroot, pero en mi opinión hay poca información en ruso para principiantes.
El objetivo del trabajo es crear un kit de distribución con descarga en vivo, interfaz icewm y navegador. La plataforma de destino es virtualbox.
¿Por qué construir su distribución? A menudo necesita una funcionalidad limitada con recursos limitados. Más a menudo en automatización necesita crear firmware. Adaptar una distribución de uso general, limpiar paquetes adicionales y convertirlo en firmware consume más tiempo que crear una nueva distribución. Usar Gentoo también tiene sus limitaciones.
El sistema Buildroot es muy poderoso, pero no hará nada por usted. Solo puede dar oportunidades y automatizar el proceso de ensamblaje.
Los sistemas de compilación alternativos (yocto, sistema de compilación abierto, etc.) no se consideran ni se comparan.
Dónde obtener y cómo comenzar
El sitio del proyecto es buildroot.org . Aquí puede descargar la versión actual y leer el manual. También puede contactar a la comunidad allí, hay un rastreador de errores, listas de correo y un canal IRC.
Buildroot funciona con defconfig para la placa de destino del ensamblaje. Defconfig es un archivo de configuración que almacena solo opciones que no tienen valores predeterminados. Es él quien determina qué y cómo se recolectará. En este caso, puede configurar por separado las configuraciones busybox, linux-kernel, uClibc, bootloaders u-boot y barebox, pero todos estarán vinculados a la placa de destino.
Después de desempaquetar el archivo descargado o la clonación de git, preparamos el buildroot para el trabajo. Los detalles sobre la estructura del directorio se pueden encontrar en el manual, hablaré sobre lo más importante:
placa : un directorio con archivos específicos de cada placa. Estos pueden ser scripts para formar imágenes del sistema (iso, sdcart, cpio, etc.), directorio de superposición, configuración del kernel, etc.
configs - en realidad defconfig placas. Defconfig es una configuración incompleta de la placa. Solo se almacenan parámetros distintos de la configuración predeterminada.
dl - directorio con códigos fuente descargados / archivos para ensamblar
salida / destino : el sistema de archivos ensamblado del sistema operativo resultante. Posteriormente, se crean imágenes para descargar / instalar.
output / host : utilidades de host para compilar
salida / compilación - paquetes compilados
La configuración de compilación se realiza a través de KConfig. El mismo sistema se utiliza para construir el kernel de Linux. Lista de los comandos más utilizados (se ejecutan en el directorio buildroot):
- make menuconfig: llama a la configuración de compilación. También puede usar la interfaz gráfica (make nconfig, make xconfig, make gconfig)
- make linux-menuconfig - llama a la configuración del kernel.
- hacer limpio: resultados de ensamblaje claros (todo lo que se almacena en la salida)
- make - construye el sistema. No reconstruye procesos ya recopilados
- make defconfig_name - cambia la configuración a un defconfig específico
- make list-defconfigs - muestra una lista de defconfig
- make source: solo descarga los archivos de instalación, sin ensamblar.
- make help - enumera los comandos posibles
Notas importantes y consejos
¡Buildroot no reconstruye paquetes ya empaquetados! Por lo tanto, puede surgir una situación cuando se requiere un reensamblaje completo.
Puede reconstruir un solo paquete con el comando make packagename-rebuild. Por ejemplo, puede reconstruir el kernel de Linux:
make linux-rebuild
Buildroot almacena el estado de cualquier paquete creando archivos .stamp en el directorio output / build / $ packagename:

Por lo tanto, puede reconstruir root-fs e imágenes sin reconstruir paquetes:
rm output/build/host-gcc-final-*/.stamp_host_installed;rm -rf output/target;find output/ -name ".stamp_target_installed" |xargs rm -rf ; make
Variables utiles
Buildroot tiene un conjunto de variables para una fácil configuración
- $ TOPDIR - directorio raíz de buildroot
- $ BASEDIR - directorio de SALIDA
- $ HOST_DIR, $ STAGING_DIR, $ TARGET_DIR: los directorios de ensamblado alojan fs, staging fs, target fs.
- $ BUILD_DIR - directorio con paquetes desempaquetados y ensamblados
Visualización
Buildroot tiene la capacidad de visualizar: puede crear un diagrama de dependencia, una línea de tiempo de construcción, un gráfico de tamaño de paquete en el sistema final. Los resultados están en forma de archivos pdf (puede elegir entre svn, png) en el directorio de salida / gráfico.
Ejemplos de comandos de visualización:
make graph-depends
construir un árbol de dependenciamake <pkg>-graph-depends
construye un árbol de dependencias de paqueteBR2_GRAPH_OUT=png make graph-build
construye un gráfico del tiempo de ensamblaje con salida en PNGmake graph-size
paquete de diagrama de make graph-size
gráfico
Guiones útiles
El directorio buildroot tiene un subdirectorio utils con scripts útiles. Por ejemplo, hay un script que verifica la descripción correcta de los paquetes. Esto puede ser útil al agregar mis paquetes (lo haré más adelante). El archivo utils / readme.txt contiene una descripción de estos scripts.
Construyamos una distribución de stock
Es importante recordar que todas las operaciones se realizan en nombre de un usuario normal, no root.
Todos los comandos se ejecutan en la raíz de buildroot. El paquete buildroot ya tiene un conjunto de configuraciones para muchas placas comunes y virtualización.
Nos fijamos en la lista de configuraciones:

Cambie a la configuración qemu_x86_64_defconfig
make qemu_x86_64_defconfig
Y comenzamos el montaje
make
El ensamblaje se completa con éxito, nos fijamos en los resultados:

Buildroot ha compilado imágenes que puede ejecutar en Qemu y asegurarse de que funcionen.
qemu-system-x86_64 -kernel output/images/bzImage -hda \ output/images/rootfs.ext2 -append "root=/dev/sda rw" -s -S
El resultado es un sistema que se ejecuta en qemu:

Crear una configuración de placa personalizada
Agregar archivos de tablero
Nos fijamos en la lista de configuraciones:

En la lista vemos pc_x86_64_bios_defconfig. Crearemos nuestro tablero copiándolo de la configuración:
cp configs/pc_x86_64_bios_defconfig configs/my_x86_board_defconfig
Inmediatamente cree el directorio de la placa para almacenar nuestros scripts, rootfs-overlay y otros archivos necesarios:
mkdir board/my_x86_board
Cambie a este defconfig:
make my_x86_board_defconfig
Por lo tanto, ahora la configuración de compilación (almacenada en .config en la raíz del directorio buildroot) corresponde a la máquina de destino x86-64 legacy (bios) al cargar.
Copie la configuración del kernel de Linux (útil en el futuro):
cp board/pc/linux.config board/my_x86_board/
Configure las opciones de compilación a través de KConfig
Ejecute la configuración:
make menuconfig
Se abre la ventana KConfig. Es posible configurar con una interfaz gráfica (make nconfig, make xconfig, make gconfig):

Entramos en la primera sección de las Opciones de destino. Aquí puede elegir la arquitectura de destino para la que se realizará el ensamblaje.

Opciones de compilación: hay varias configuraciones de compilación aquí. Puede especificar directorios con códigos fuente, la cantidad de subprocesos de ensamblaje, espejos para descargar códigos fuente y otras configuraciones. Deje la configuración predeterminada.
Cadena de herramientas: aquí se configuran las herramientas de compilación. Más sobre él.

Tipo de cadena de herramientas: tipo de cadena de herramientas utilizada. Se puede incorporar a buildroot o una cadena de herramientas externa (puede especificar un directorio con uno preconstruido o una url para descargar). Para diferentes arquitecturas hay opciones adicionales. Por ejemplo, para armar, simplemente puede seleccionar la versión de la cadena de herramientas externa Linaro.
Biblioteca C: la elección de la biblioteca C. El funcionamiento de todo el sistema depende de esto. Usualmente se usa glibc, soportando todas las funcionalidades posibles. Pero puede ser demasiado grande para el sistema integrado, por lo que a menudo se eligen uClibc o musl. Elegiremos glibc (en el futuro será necesario usar systemd).
Cabeceras de núcleo y series de encabezados de núcleo personalizados: deben coincidir con la versión del núcleo que estará en el sistema de compilación. Para los encabezados del kernel, también puede especificar la ruta al repositorio tarball o git.
VERSIONES DEL COMPILADOR GCC: seleccione la versión del compilador que se utilizará para el ensamblaje
Habilitar soporte de C ++: seleccione para ensamblar con soporte para bibliotecas de c ++ en el sistema. En el futuro, esto será útil.
Opciones de gcc adicionales: puede configurar opciones de compilador adicionales. No necesitamos hasta ahora.
La configuración del sistema le permite establecer parámetros futuros para el sistema creado:

La mayoría de los puntos están claros por el nombre. Presta atención a los siguientes puntos:
Ruta de acceso a las tablas de usuarios: tabla con usuarios creados ( https://buildroot.org/downloads/manual/manual.html#makeuser-syntax ).
Ejemplo de archivo El usuario usuario se creará con la contraseña admin, automáticamente gid / uid, / bin / sh shell, usuario de grupo predeterminado, miembro del grupo raíz, comentario usuario de Foo
[alexey@alexey-pc buildroot ]$ cat board/my_x86_board/users.txt user -1 user -1 =admin /home/user /bin/sh root Foo user
Directorios de superposición del sistema de archivos raíz: un directorio superpuesto en la parte superior del objetivo ensamblado fs. Agrega nuevos archivos y reemplaza los existentes.
Scripts personalizados para ejecutar antes de crear imágenes del sistema de archivos: scripts que se ejecutan inmediatamente antes de que el sistema de archivos se colapse en imágenes. El script en sí se dejará en blanco por ahora.
Pasemos a la sección Kernel

La configuración del kernel se establece aquí. El núcleo mismo se configura mediante make linux-menuconfig.
Puede configurar la versión del kernel de diferentes maneras: elija una de las propuestas, ingrese la versión manualmente, especifique el repositorio o el tarball terminado.
Configuración del kernel: la ruta a la configuración del kernel. Puede elegir la configuración predeterminada para la arquitectura seleccionada o defocnfig desde Linux. Las fuentes de Linux tienen un conjunto de defconfig para diferentes sistemas de destino. Puede encontrar el correcto mirando directamente la fuente aquí . Por ejemplo, para un tablero negro de hueso beagle, puede seleccionar una configuración .
La sección Paquetes de destino le permite elegir qué paquetes se instalarán en el sistema de compilación. Déjalo sin cambios por ahora. Más adelante agregaremos nuestros paquetes a esta lista.
Imágenes del sistema de archivos: una lista de las imágenes del sistema de archivos que se compilarán. Añadir imagen iso

Cargadores de arranque: la elección de los cargadores de arranque ensamblados. Elige isolinix

Configuración de Systemd
Systemd se convierte en uno de los pilares de Linux, junto con kernel y glibc. Por lo tanto, hice su configuración en un párrafo separado.
Se configura mediante make menuconfig, luego Paquetes de destino → Herramientas del sistema → systemd. Aquí puede especificar qué servicios systemd se instalarán e iniciarán al iniciar el sistema.

Guardar configuración del sistema
Guarde esta configuración a través de KConfig.
Luego guarde nuestro defconfig:
make savedefconfig
Configuración del kernel de Linux
La configuración del kernel de Linux se invoca con el siguiente comando:
make linux-menuconfig
Agregue soporte para la tarjeta gráfica Virtualbox

Agregar soporte de integración de Virtualbox Guest

Guardar y salir. IMPORTANTE : la configuración se guardará en output / build / linux- $ version / config, pero no en board / my_x86_board / linux.config

Por lo tanto, debe copiar manualmente la configuración en la ubicación de almacenamiento:
cp output/build/linux-4.19.25/.config board/my_x86_board/linux.config
Con este comando copio la configuración de kernel COMPLETA, que no siempre es necesaria. Una forma más correcta es mantener el kernel defconfig:
make linux-update-defconfig
Después de eso, realizamos un reensamblaje completo de todo el sistema. Dado que buildroot no vuelve a ensamblar el ya ensamblado, debe especificar manualmente los paquetes para el reensamblado. Para no perder tiempo y nervios, es más fácil reconstruir todo el sistema pequeño):
make clean;make
Una vez completada la compilación, ejecute VirtualBox (probado en las versiones 5.2 y 6.0) con el arranque desde la unidad de CD. Parámetros del sistema:

A partir de la iso ensamblada:

Listado de materiales utilizados
- Manual de Buildroot