Linux embebido personalizado con BuildRoot

Construye tú propio SO personalizado para un Sistema embebido con arquitectura ARM con BuilRoot

SISTEMAS EMBEBIDOS

Biblioman

2/3/20247 min read

La compilación cruzada en sistemas embebidos con arquitectura ARM es esencial para desarrollar aplicaciones y sistemas operativos para plataformas de pocos recursos hardware. Buildroot y Yocto son dos frameworks populares que ofrecen herramientas y scripts para simplificar este proceso. Buildroot es una opción más ligera y fácil de usar, mientras que Yocto ofrece mayor flexibilidad y personalización.

Además, existen otros frameworks disponibles como Crosstool-ng, OpenEmbedded y PTXdist, que también pueden ser considerados.

En este tutorial utilizaremos Builroot para crear un sistema operativo completo (de consola) para el procesador RV1106 de Rockchip montado en la placa de desarrollo LuckFox Pico Max pero podríamos utilizar cualquier otro procesador y placa, en otro tutorial utilizaremos Yocto para crear un sistema operativo personalizado para la Orange Pi 5 Plus.

Instalación del entorno de desarrollo (SDK)

Necesitamos un sistema operativo Linux en un ordenador con arquitectura x86_64 en mi caso voy a utilizar Ubuntu 22.04 LTS pero probablemente funciones en otras distribuciones como Debian.

  1. Instalación de aplicaciones y dependencia necesarias:

sudo apt update
sudo apt-get install -y git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk texinfo libssl-dev bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5- dev pkg-config bc python-is-python3 passwd openssl openssh-server openssh-client vim file cpio rsync

  1. Clonamos el SDK mas reciente:

git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git

Una vez copiado el repositorio nos quedará la siguiente estructura de carpetas:

├── build.sh -> project/build.sh ----> script de compilación
├── media --->Multimedia encoding/decoding, ISP, etc. (Puede ser compilado independientemente)
├── sysdrv -->U-Boot, kernel, directorio rootfs (Puede ser compilado independientemente)
├── project --> Aplicaciones de referencia, configuraciones de compilación y directorio de scrips
├── output --> Directorio para almacenar los archivos de la imagen después de la compilación
└── tools ----> Herramientas de grabación

El archivo de configuración con extensión .mk es el primero que tendremos que modificar para empezar a personalizar nuestro sistema operativo, en este archivo se especifican las opciones de compilación, las dependencias y las rutas de instalación para cada paquete

Los archivos de configuración del SDK de la serie Luckfox-Pico se encuentran en el directorio: proyect/cfg/BoardConfig_IPC.

En esta carpeta tenemos varias opciones que dependen del tipo procesador que tiene nuestra placa en nuestro caso un RV1106 y para que medio queremos crear la imagen en este ejemplo lo haremos sobre la SPI-FLASH que viene integrada en la placa de desarrollo, por tanto editaremos con nano el archivo: BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk

Lo primero que vamos a cambiar es la memoria asignada a la cámara CSI ya que de momento nos sirve para poco sin drivers, por defecto tiene asignada una memoria de 64M lo dejaremos en 1M según se muestra en la figura de abajo.

Especificamos el sistema raíz de archivos, en el comentario nos indica que Ubuntu solo está disponible para su instalación en la micro-SD

Configuración del kernel

Para personalizar el kernel de Linux utilizaremos la herramienta menuconfig que proporciona una interfaz gráfica basada en la terminal y que nos permite manejar intuitivamente las opciones de modificación del kernel de Linux. Para lanzar la herramienta tendremos que ir al directorio donde están las fuentes del kernel y ejecutar los siguientes comandos en la terminal:

cd <Directorio SDK>/sysdrv/source/kernel
cp ./arch/arm/configs/luckfox_rv1106_linux_defconfig .config
make ARCH=arm menuconfig

Una vez abierta la herramienta en la parte superior nos muestra la forma de navegar por los diferentes menús a través del teclado. Una opción muy interesante es el menú Device Drivers --> Industrial I/O support donde podremos ver los dispositivos hardware con un driver disponible para añadir al kernel si seleccionamos humidity Sensors y nos posicionamos con la flechas en el sensor de humedad DHT11 podremos seleccionarlo tecleando la letra <y>.

Para guardar la nueva configuración nos desplazamos con las flechas hasta <Save> y seleccionamos <Ok> en la ventana que nos sale dejamos el nombre por defecto .config y seleccionamos <Ok>

Una vez que salgamos de menuconfig en el mismo directorio deberemos ejecutar los siguientes comandos:

make ARCH=arm savedefconfig
cp defconfig ./arch/arm/configs/luckfox_rv1106_linux_defconfig

Llegado a este punto nos queda volver a compilar el nuevo kernel para ello tendremos que seleccionar nuestra placa de desarrollo, vamos al directorio raíz del proyecto y ejecutamos:

./build.sh lunch

En el menú que nos sale seleccionamos la rama que hemos elegido anteriormente para nuestra placa que corresponde a la opción <8> del menú:

Y por último ejecutamos el comando para compilar, teniendo en cuenta que tenemos dos opciones: o compilar todo el proyecto con:

./build.sh

Esto se llevara un buen rato.. al terminar nos habrá generado una nueva Release completa dentro del directorio SDK/luckfox-pico/IMAGE/SPI_NAND_RV1106G-LUCKFOX-PICO-PRO-MAX.DTS_20240205.1453_RELEASE_TEST con todas las imágenes listas para flasehar en nuestra placa de desarrolo.

La otra opción que tenemos es compilar solo el kernel para ello ejecutamos los siguientes comandos:

./build.sh clean kernel
./build.sh kernel

Esto nos borrara la antigua imagen del kernel y nos creará una nueva en la carpeta SDK/luckfox-pico/output/image que es la que tendremos que flashear en la placa.

Configuración de BuilRoot

Al igual que hemos hecho con la configuración del kernel de Linux podemos utilizar menuconfig para personalizar los paquetes de software y las librerías incluidos en el sistema integrado para cumplir con los requisitos específicos que queremos para nuestra placa.

  1. Agregar paquetes:

Para ejecutar menuconfig ejecutamos los siguientes comandos:

cd <Directorio SDK>/sysdrv/source/buildroot/buildroot-2023.02.6/
make luckfox_pico_defconfig
make menuconfig

Nota: El directorio "buildroot-2023.02.6" no está presente inmediatamente después de descargar el SDK. Es necesario compilar el SDK una vez antes de que este directorio esté disponible.

Vamos a instalar el paquete minicom un cliente de comunicación serie a través de consola. Tenemos el paquete en la ruta: Target packages --> Hardware handling--> minicom lo seleccionamos y escribimos <y> para seleccionarlo. También podemos escribir </> para buscar el paquete luego <1> para ir a el.

Compilación de Imágenes
  1. Instalamos la cadena de herramientas de compilación cruzada:

cd {SDK_PATH}/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/
source env_install_toolchain.sh

2.1 Compilar todas las imágenes:

cd luckfox-pico

# Compile busybox/buildroot
./build.sh lunch
./build.sh

2.2 Compilación parcial:

Compilar U-Boot por separado:
./build.sh clean uboot
./build.sh uboot


Archivos de imagen generado en: output/image/uboot.img


Compile el kernel por separado:
./build.sh clean kernel
./build.sh kernel


Archivo de imagen generado: output/image/boot.img


Compile rootfs por separado:

./build.sh clean rootfs
./build.sh rootfs


Nota: Después de la compilación, utilice el siguiente comando para volver a empaquetar.

./build.sh firmware


Compile el directorio media por separado:

./build.sh clean media
./build.sh media


Los archivos se almacenan en el directorio: output/out/media_out. Después de la compilación, utilice el comando ./build.sh firmware para volver a empaquetar.

Compile las aplicaciones de referencia por separado:


./build.sh clean app
./build.sh app


Nota 1: la aplicación depende de los medios.
Nota 2: Después de la compilación utilice el comando ./build.sh firmware para volver a empaquetar.

Empaquetado de firmware:

./build.sh firmware

Seleccionamos <Save> y en la ventana que nos sale dejamos el nombre que aparece por defecto y le damos a <Ok>

Después salimos de menuconfig y compilamos con:

make savedefconfig
make

  1. Agregar bibliotecas de Python:

    También podemos agregar bibliotecas de Pyhton para ello volvemos abrir menuconfig si no está abierto con:

    cd <Directorio SDK>/sysdrv/source/buildroot/buildroot-2023.02.6/
    make luckfox_pico_defconfig
    make menuconfig

    vamos a instalar como ejemplo la biblioteca terminaltables que nos permite dibujar tablas formateadas en la terminal, se encuentra en la ruta Target packages--> Interpreter languages and scripting--> python3-->External python modules --> python-terminaltables

    La seleccionamos con <y> y aceptamos con <Ok>

En la ventana que nos sale dejamos el nombre de archivo por defecto y le damos a <Ok>

Después salimos de menuconfig y compilamos con:

make savedefconfig
make

Grabar el firmware en la placa de desarrollo. para ello realizamos los siguientes pasos:

  1. volvemos a ir al directorio raiz de nuestro proyecto (~/SDK/luckfox-pico$) y ejecutamos

./build.sh lunch

Seleccionamos la opción [8] que corresponde con nuestra placa y la rama elegida.

  1. Compilamos con:

./build.sh

  1. Volvemos a cargar el firmware en la placa con la herramienta SocToolKit:

Aquí tenéis un vídeo paso a paso de todo el proceso:

Si te ha gustado el tutorial o te interesa algún tema en particular relacionado con el artículo puedes dejar tus comentarios en los vídeos de YouTube que acompañan al tutorial.

Un saludo