Tutorial paso a paso para compilar una imagen de Linux para plataformas ARM
Tabla de Contenidos
1. Introducción
Este tutorial explica paso a paso cómo compilar una imagen de Linux para ARM. Se indica todo lo necesario para configurar correctamente el entorno del sistema operativo para poder customizar el Kernel de Linux y crear una imagen propia para un procesador ARM.
Placa embebida de pruebas
Los pasos que se muestran en esta Guía están orientados a crear una imagen de Linux para la placa VAB-630, del fabricante VIA Technologies. Este fabricante proporciona el hardware, el software y los componentes básicos de la nube para crear sistemas y dispositivos integrados innovadores que liberan el impresionante potencial de la conectividad y el Internet de las cosas (IoT).
Placa VIA VAB-630 3.5″ SBC
Impulsado por un SoC VIA Cortex-A9 de doble núcleo de 1.0GHz, la VIA VAB-630 presenta un rendimiento multimedia avanzado, una gran cantidad de E/S y compatibilidad con conectividad inalámbrica, y herramientas avanzadas de desarrollo de software para una gran cantidad de aplicaciones, señalización e Interfaz Humano-Máquina (Human-Machine Interface, HMI). También está disponible un panel táctil opcional de 10.1 pulgadas para acelerar los tiempos de desarrollo del sistema.
En la siguiente imagen se muestran las distintas partes de la placa, así como los conectores disponibles para todo tipo de interfaces de conexión. Además, se incluye una tabla con todas las especificaciones técnicas de la VAB-630.
MODEL NAME | VAB-630 |
Processor | 1.0GHz VIA Cortex-A9 dual-core SoC |
System Memory | 1GB DDR3 SDRAM onboard |
Storage | 4GB eMMC flash memory |
Boot Loader | 512KB SPI Flash ROM |
Graphics | Mali-400 SP GPU 2 integrated, independent 3D/2D graphics processing units Graphics engine supporting OpenGL® ES 2.0 hardware acceleration Supports MPEG-2 and H.264 video decoding up to 1080p |
LAN | ASIC AX88772CLF |
Audio | VIA VT1603A I2S Audio Codec |
HDMI | Integrated HDMI 1.4 Transmitter |
USB | ASIC USB2514B-AEZC USB 2.0 hi speed 4-port hub controller |
Expansion I/O | 1 miniPCIe slot |
Onboard I/O | 1 Single-channel LVDS connector 1 miscellaneous pin header for I2C touch screen interface 1 USB connector 1 UART (console port connector) 1 RTC battery connector 1 Battery charger connector 1 Reset connector 1 SIM card slot (supports 3G module without built-in SIM card slot) 1 miniPCIe slot |
Front Panel I/O | 1 Micro USB 2.0 OTG port 1 DIO port supporting 10 GPIO with 3.3V power 1 Micro SD card slot 2 Audio jacks : Line-out and Mic-in 1 Power LED 1 Power Button |
Back Panel I/O | 1 HDMI port 2 USB 2.0 ports 1 COM port for RS-232 (TX/RX) 1 10/100Mbps Ethernet port 1 DC-in jack |
Power Supply | 12V DC-in (5V DC-in optional) |
Operating System | Android 5.0, Linux kernel 3.4.5 |
VIA Smart ETK | Watchdog timer, GPIO, UART |
Operating Temperature | 0°C ~ 60°C |
Operating Humidity | 0 ~ 90% @ 40°C (non-condensing) |
Form Factor | 14.6cm x 10.2cm (5.75″ x 4.02″) |
Compliance | CE / FCC |
Como se puede observar, la placa admite como Sistemas Operativos tanto Android 5.0 como Linux kernel 3.4.5. En el presente documento se muestran los pasos para crear la imagen para este último SO.
Para poder sacarle el máximo partido a los componentes hardware que componen las innumerables placas y módulos que existen en el mercado, los fabricantes proporcionan los archivos necesarios para poder crear nuestra propia distribución de Linux en la que estarán implementadas todas las funcionalidades necesarias para hacer uso de todo el hardware incorporado. De esta manera, se tendrá una distribución diseñada para el hardware específico que tenga la placa, maximizando el rendimiento de la misma.
En los siguientes capítulos se explicará en detalle los pasos necesarios para llegar a tener nuestra placa VAB-630 funcionando correctamente con la distribución de Linux que hayamos creado.
2. Preparación del entorno
A través de esta sección se irán explicando los pasos a seguir para la correcta configuración del entorno de desarrollo desde el que se realizará la compilación. Todas las instrucciones que se muestran están basadas en Ubuntu14.04 LTS x64. Para poder trabajar en un entorno perfectamente configurado, se recomienda el uso de Máquinas Virtuales, mediante las cuales podremos instalar la distribución de Linux necesaria para poder realizar la compilación.
Una vez tengamos la máquina Host configurada, debemos acceder a la página web del fabricante de la placa de desarrollo, con el fin de poder descargarnos todo lo necesario para compilar la imagen de Linux para ARM que posteriormente volcaremos en la placa VAB-630. En nuestro caso, accederemos a la web de VIA, a la página correspondiente a la VAB-630, donde además de poder ver las distintas características de la placa, podremos descargarnos los manuales de la misma, así como de todos los archivos necesarios. Para la placa VAB-630, podremos descargar lo necesario para instalar una distribución de Linux en ella, como también lo necesario para instalar Android 5.0. En nuestro caso nos descargaremos el “Linux Board Support Package (BSP)”.
¿Qué es el BSP?
En los sistemas embebidos, un “Board Support Package” ( BSP ) es la capa de software que contiene controladores específicos de hardware y otras rutinas que permiten que un sistema operativo en particular (tradicionalmente un sistema operativo en tiempo real, o RTOS) funcione en un entorno de hardware en particular, como puede ser la placa VAB-630, integrado con el propio RTOS. Los desarrolladores de hardware de terceros que deseen admitir un RTOS en particular deben crear un BSP que permita que el RTOS se ejecute en su plataforma. En la mayoría de los casos, la imagen del RTOS, el BSP que la contiene y el hardware están agrupados por el proveedor de hardware, como sería el fabricante VIA en el caso de la VAB-630.
Los BSP suelen ser personalizables, lo que permite al usuario especificar qué controladores y rutinas deben incluirse en la compilación en función de su selección de opciones de hardware y software. Por ejemplo, para que en una placa como la VAB-630 se pueda hacer uso de la interfaz I2C de la misma, el BSP incluiría un controlador específico para dicha interfaz.
Además de los BSP, los fabricantes también proporcionan el toolchain, que contienen las herramientas de desarrollo de software necesarias, de manera que forman un sistema integrado que es usado para programar tanto aplicaciones como sistemas operativos.
Contenido del BSP
A continuación se explica el contenido y algunos términos que intervienen a la hora de crear distintas imágenes de sistemas operativos:
-
- Kernel: El kernel de Linux es el elemento principal de los sistemas operativos (SO) Linux, y es la interfaz fundamental entre el hardware de un equipo y sus procesos. Los comunica entre sí y gestiona los recursos de la manera más eficiente posible. Se llama kernel porque se encuentra dentro del sistema operativo y controla todas las funciones principales del hardware, ya sea un teléfono, un ordenador portátil, un servidor o cualquier otro tipo de equipo.
El kernel cumple cuatro tareas:
-
- Gestión de la memoria: supervisa cuánta memoria se utiliza para almacenar qué tipo de elementos, así como el lugar en que los guarda.
- Gestión de los procesos: determina qué procesos pueden usar la unidad central de procesamiento (CPU), cuándo y durante cuánto tiempo.
- Controladores de dispositivos: actúa como mediador o intérprete entre el hardware y los procesos.
- Seguridad y llamadas al sistema: recibe solicitudes de servicio por parte de los procesos.
- U-Boot: (Universal Bootloader) Es un bootloader para varios tipos de arquitecturas de computadores, incluyendo PPC, ARM, AVR32, MIPS, x86, 68k, Nios, y MicroBlaze. El bootloader es un programa ejecutado por la BIOS cuando se enciende el equipo informático y que se encarga de la inicialización del sistema operativo y de los dispositivos.
- GNU Toolchain y GCC: El GNU Toolchain agrupa a una serie de proyectos que contienen las herramientas de desarrollo de software producidas por el proyecto GNU. Estos proyectos forman un sistema integrado que es usado para programar tanto aplicaciones como sistemas operativos. El GNU toolchain es un componente vital en el desarrollo del núcleo Linux, el desarrollo de BSD y de software para sistemas embebidos. Dentro del GNU Toolchain se incluye la GNU Compiler Collection (GCC), que agrupa distintos compiladores para varios lenguajes. Estos compiladores se consideran estándar para los sistemas operativos derivados de UNIX, de código abierto y también de propietarios. GCC requiere el conjunto de aplicaciones conocido como binutils para realizar tareas como identificar archivos objeto u obtener su tamaño para copiarlos, traducirlos o crear listas, enlazarlos, o quitarles símbolos innecesarios.
- GNU Arm Embedded Toolchain: Este Toolchain contiene un conjunto de herramientas de código abierto para utilizar en C, C++ y ensamblador. Está dirigido a las familias de procesadores Arm Cortex-A, Arm Cortex-M y Arm Cortex-R de 32 bits. GNU Arm Embedded Toolchain incluye el compilador GNU (GCC) y está disponible gratuitamente por Arm para el desarrollo de software integrado en los sistemas operativos Windows, Linux y Mac OS X.
- Compilación Cruzada: A la hora de compilar una aplicación o un sistema operativo personalizado, debemos tener en cuenta la arquitectura del procesador sobre la cual va a ejecutarse dicha aplicación o SO. En nuestro caso, vamos a compilar desde un equipo con arquitectura x86 un SO basado en Linux para un equipo con arquitectura ARM. Al ser dos arquitecturas distintas, será necesario compilar un SO para una arquitectura distinta a la del equipo Host, usando las herramientas necesarias para llevar a cabo esta compilación entre arquitecturas. De ahí el término de “Compilación Cruzada”.
Con todos los archivos necesarios descargados, lo primero que habrá que hacer es preparar el entorno de compilación.
Instalación del Toolchain
Extraer el archivo arm_201103_gcc4.5.2.tgz dentro de la carpeta /usr/local/arm/ (En caso de que no exista la carpeta, la crearemos primero manualmente).
$ sudo tar –xzvf arm_201103_gcc4.5.2.tar.gz -C /usr/local/arm/
El cross compiler estará localizado en el directorio /usr/local/arm/arm_201103_gcc4.5.2/
A continuación habrá que añadir esta ruta al PATH. El PATH (el camino, la ruta) es una variable de entorno. Las variables de entorno contienen información a la que se accede a través del nombre de la variable (al igual que ocurre en los lenguajes de programación). Esta variable informa al shell (en la mayoría de los casos BASH) dónde se encuentran los programas binarios que se pueden ejecutar en el sistema, por lo que podremos llamarlos sin tener que especificar su ruta absoluta. Añadiremos la ruta al PATH:
$ export PATH=/usr/local/arm/arm_201103_gcc4.5.2/mybin/:$PATH
Nos aseguramos que la ruta se haya añadido correctamente al PATH.
Una vez tengamos el cross compiler instalado, será necesario descargar una serie de paquetes que serán necesarios para poder ejecutar la compilación cruzada. Para ello habrá que estar conectado a internet, con el fin de poder actualizar la lista de paquetes disponibles y sus versiones.
$ sudo apt-get update
Con la lista de paquetes actualizada, se ejecuta la siguiente instrucción para descargar todos las aplicaciones necesarias para la compilación:
$ sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev lib32ncurses5-dev lib32z1 lib32ncurses5 x11proto-core-dev libx11-dev libgl1-mesa-dev g++-multilib mingw-w64 tofrodos python-markdown libxml2-utils u-boot-tools
De las aplicaciones instaladas con el comando anterior, podemos destacar las siguientes:
- build-essential: A la hora de crear paquetes para distribuciones GNU Linux, como Debian, una herramienta clave es build-essentials. Se trata de un paquete que contiene una lista informativa de los paquetes que se consideran esenciales para la creación de paquetes Debian. Para la instalación de muchos módulos o drivers, es necesario tener instalado este paquete.
- flex y bison: Flex y Bison son dos herramientas útiles para crear programas que reaccionen a una entrada de datos con una estructura y un lenguaje predeterminado. Como ejemplo se pueden crear compiladores intérprete y analizadores de línea de comando.
- libc6-dev: Contiene los enlaces simbólicos, cabeceras y archivos objeto necesarios para compilar y enlazar los programas que usan la biblioteca estándar de C.
- g++-multilib: Este es el compilador GNU C++, un compilador de optimización portátil para C++.
- u-boot-tools: Boot loader para varios tipos de arquitecturas de computadores, incluyendo PPC, ARM, AVR32, MIPS, x86, 68k, Nios, y MicroBlaze.
En este punto ya se tendría la máquina Host correctamente configurada para poder llevar a cabo el proceso de compilación del Bootloader y del Kernel.
3. Proceso de compilación:
A la hora de querer compilar un Bootloader y un Kernel propio para la placa VAB-630, tendremos que hacer uso del paquete BSP que nos proporciona el fabricante VIA. Para ello deberemos acceder a la carpeta “Source Code Folder”, en la que se encuentran los archivos necesarios para la compilación.
Usaremos el siguiente comando para descomprimir el contenido del BSP:
$ unzip VAB-630_Linux_source_code.zip
Una vez descomprimido, dentro de la carpeta tendremos el contenido para crear la imagen del Bootloader y del Kernel de Linux.
Compilación del Bootloader
En esta sección se muestran los pasos necesarios para compilar la imagen de U-Boot a partir del código fuente. Lo primero que debemos hacer es descomprimir el archivo u-boot-1.1.4.tar.gz
$ tar -xzvf u-boot-1.1.4.tar.gz
A continuación crearemos la imagen del U-Boot, y lo haremos haciendo uso de la herramienta make.
Make es una herramienta de gestión de dependencias, típicamente, las que existen entre los archivos que componen el código fuente de un programa, para dirigir su recompilación o «generación» automáticamente.Make es muy usada en los sistemas operativos tipo Unix/Linux. Por defecto lee las instrucciones para generar el programa u otra acción del fichero makefile. Las instrucciones escritas en este fichero se llaman dependencias.
La herramienta make se usa para las labores de creación de fichero ejecutable o programa, para su instalación, la limpieza de los archivos temporales en la creación del fichero, todo ello especificando unos parámetros iniciales (que deben estar en el makefile) al ejecutarlo. Dentro de este archivo makefile estará declarado el siguiente contenido:
- Comentarios
- Variables
- Reglas explícitas
- Reglas implícitas
Las Reglas explícitas le indican a make qué archivos dependen de otros archivos, así como los comandos requeridos para compilar un archivo en particular. Las Reglas implícitas son reglas que make interpreta para actualizar destinos sin tener que escribirlas dentro del fichero makefile.
Para realizar el proceso de compilación, accedemos a la carpeta que se ha generado
$ cd /u-boot-1.1.4
Y una vez dentro ejecutaremos la siguiente instrucción con el fin de cargar la configuración por defecto
$ make wmt_config
Con la configuración ya cargada, solo falta compilar la imagen del U-Boot haciendo uso del compilador cruzado para ARM. Para ello ejecutaremos la siguiente instrucción make, pasándole el parámetro zuboot, que está recogido en el archivo Makefile, en el que se indica las reglas necesarias para generar la imagen del U-Boot.
$ make zuboot
Cuando el proceso haya completado, se habrá generado en el directorio el archivo zuboot.bin.
Compilación del Kernel
En esta sección se explica cómo compilar el Kernel de Linux a partir del código fuente.
Al igual que lo realizado con el Bootloader, comenzaremos extrayendo el código fuente del Kernel.
$ tar -xzvf Kernel_3.4.5.tar.gz
Para usar la configuración por defecto, usaremos las siguientes instrucciones:
$ cd /Kernel_3.4.5
$ make vab630_linux_defconfig
$ make clean
Por último, solo queda compilar el Kernel
$ make ubin
Una vez completado el proceso de compilación, se habrá creado el archivo uzImage.bin en el directorio.
Preparación de archivos para la instalación de Linux en la placa VAB-630
Después de haber completado los procesos de compilación del Bootloader y del Kernel, es hora de preparar los archivos necesarios para poder cargarlos en la placa VAB-630. Los directorios /u-boot-1.1.4/ y /Kernel_3.4.5/ contendrán los archivos binarios, como muestra la siguiente tabla:
Archivos Binarios | Descripción |
zuboot.bin | U-Boot boot loader |
uzImage.bin | Kernel para la VAB-630 |
Estos archivos deberán copiarse dentro de la carpeta con el firmware original de la VAB-630. Para ello habrá que descomprimir el archivo de la carpeta Firmware folder, el cual nos dará como resultado lo siguiente:
Dentro de la carpeta bspinst estarán los archivos necesarios para realizar el proceso de instalación en la placa VAB-630, y el archivo scriptcmd contendrá las instrucciones para flashear la memoria e iniciar el proceso de instalación.
Para preparar los archivos, primero renombramos el archivo zuboot.bin como u-boot.bin.
$ cd /u-boot-1.1.4
$ mv zuboot.bin u-boot.bin
A continuación, deberemos copiar las imágenes que hemos creado del Bootloader y del Kernel en la carpeta bspinst.
$ cd /u-boot-1.1.4
$ cp –f u-boot.bin VAB-630_Linux_EVK_v1.0.1/bspinst/u-boot.bin
$ cd /Kernel_3.4.5
$ cp –f uzImage.bin VAB-630_Linux_EVK_v1.0.1/bspinst/uzImage.bin
Una vez copiados los archivos necesarios, se tendrá todo listo para poder instalar la imagen de Linux en la VAB-630. De esta manera, habrá finalizado el proceso de compilación del Bootloader y del Kernel de Linux y creación de la imagen de Linux. Únicamente quedará iniciar el proceso de instalación de la imagen en la placa VAB-630, que se encuentra detallado en el siguiente capítulo de esta guía.
4. Instalación de la Imagen Linux
La placa VAB-630 únicamente soporta el arranque desde la ROM SPI con la memoria eMMC. Para iniciar el proceso de instalación de una nueva imagen de Linux, habrá que realizarlo desde una tarjeta Micro SD.
Con todos los archivos preparados, únicamente queda copiar la carpeta bspinst y el archivo scriptcmd en una tarjeta Micro SD, formateada en formato FAT.
Para llevar a cabo el proceso de instalación, introduciremos la tarjeta Micro SD en su ranura correspondiente y nos conectaremos a la placa VAB-630 a través del conector de Debug UART y usando el adaptador ENT-610T facilitado por VIA para poder conectarnos a través del puerto serie. Este mismo adaptador se utiliza para flashear el Bootloader en caso de que se haya dañado en el proceso de instalación. Conectados a la placa a través del puerto serie podremos seguir el proceso de instalación desde nuestro equipo, sin recurrir a pantallas ni periféricos externos.
Para seguir el proceso de instalación de la imagen de Linux en la VAB-630, haremos uso de una aplicación cliente para conexiones serie, como puede ser la aplicación de software libre, Putty.
Iniciaremos una conexión en el puerto serie correspondiente (COM6 en este caso) y fijamos la velocidad del puerto serie al valor 115200 bit/s (valor por defecto de la placa VAB-630).
Con la conexión serie abierta y la tarjeta Micro SD en la placa VAB-630, únicamente queda conectar el cable de alimentación a la placa para que arranque e inicie el proceso de instalación de la imagen de Linux de forma automática.
Una vez haya completado el proceso de instalación de la imagen de Linux, aparecerá el mensaje de que quitemos el medio de instalación. Para ello únicamente habrá que retirar la tarjeta Micro SD y la VAB-630 se reiniciará, y ahora así, cargará la versión de Linux que tendrá instalada.
Una vez completado el arranque, únicamente quedará hacer login, usando debian tanto como nombre de usuario como de contraseña.
Con los pasos mostrados en esta guía se ha llevado a cabo el proceso de configuración del entorno de desarrollo, la compilación del Bootloader y del Kernel, y la instalación de la imagen de Linux resultante en la placa VAB-630.
Configuración de parámetros del Bootloader
A la hora de iniciar el arranque a través del Bootloader, existe la opción de entrar en la consola de configuración del Bootloader con el que poder configurar una serie de parámetros. Una vez se conecte la placa VAB-630 a la corriente, debemos pulsar una tecla antes de que se inicie el autoarranque, con lo que entraremos en la consola.
Desde esta consola de configuración se puede acceder a una gran cantidad de instrucciones para configurar distintos tipos de parámetros:
Por ejemplo, en la sección siguiente se indica como proceder para cambiar la configuración de vídeo y utilizar una pantalla externa conectada a través del conector LVDS.
Configuración de salida de la imagen
La versión Linux BSP v1.0.1 de la VAB-630 permite dos modos de salida de vídeo:
- ONation 10.1” LVDS Panel VIA1001 OT101RBWDLT-00 (1280×800)
- HDMI monitor (por defecto)
Para cambiar la salida de vídeo hacia una pantalla externa conectada a través del conector LVDS, debemos ejecutar las siguientes instrucciones en la consola de configuración del U-Boot:
WMT # setenv wmt.display.fb0 0:[6:0:18:1280:800:60]
WMT # saveenv
WMT # reset