STM32MP1: U-Boot, Buildroot, Arch Linux y un poco de Debian

Hola Habr!

Hace algún tiempo, STMicroelectronics lanzó interesantes procesadores de la serie STM32MP1. Cuando finalmente puse mis manos en la placa de depuración basada en este procesador, me sorprendió descubrir que carece de compilaciones basadas en distribuciones populares (Debian, Arch Linux, etc.). Todo lo que quedaba era intentar adaptar algún kit de distribución para esta placa. Basado en los resultados de esto, apareció este artículo.



¿Cuáles son las características?


Este artículo no estaría completo sin al menos una breve descripción de las características de los procesadores de la serie STM32MP1. Hay tres familias de procesadores en la serie STM32MP1: STM32MP151, STM32MP153 y STM32MP157. Sus características principales se dan en la tabla.



Como puede ver en la tabla, la diferencia entre las familias es que STM32MP151 tiene un núcleo de Cortex-A7, mientras que STM32MP153 y STM32MP157 tienen dos núcleos, y STM32MP157 también tiene soporte para GPU 3D. Pero, en general, las características de estos procesadores en 2020 no causan ninguna impresión, son más bien modestas. ¿Por qué seguí prestándoles atención?

¿Por qué STM32MP1?


De hecho, puede surgir una pregunta completamente lógica: ¿hay una Raspberry Pi, hay una Banana Pi, hay una Orange Pi y, finalmente, por qué necesitamos alguna otra STM32MP1? Además, todas estas placas suelen tener un rendimiento significativamente mayor que el objeto de nuestro estudio. La respuesta es simple: si está haciendo manualidades para uso doméstico, es necesario tomar la frambuesa y estará bien. Pero si hablamos de productos producidos en masa para aplicaciones industriales, aquí otras cosas comienzan a desempeñar un papel decisivo, gracias al cual el STM32MP1 es el ganador:

  • Rango de temperatura de funcionamiento. Para STM32MP1, comienza a menos 40 grados, mientras que para muchos procesadores de otras computadoras de una sola placa es bueno si es menos 20.
  • . STMicroelectronics , .
  • . DigiKey Mouser STM32MP1, .

Por supuesto, ST32MP1 no es el único procesador en el mercado para aplicaciones industriales. Hay tanto NXP como TI. En cuanto a TI, tenía un proyecto de un módulo bastante complejo basado en él, y había un sedimento de un número notable de características de hardware que no estaban cubiertas en la documentación, pero si no se respetaba, el procesador podría fallar por completo, y no de inmediato, sino con el tiempo y en el momento más inoportuno. Además, era un procesador de un solo núcleo, y con un aumento en el número de tareas que se le asignaron, surgieron problemas cada vez más frecuentes. Al mismo tiempo, estaba lidiando con microcontroladores STMicroelectronics, y demostraron ser bastante buenos, así que decidí tratar de elegir este nuevo pequeño.

Junta de depuración


Para los experimentos, compré una placa de depuración STM32MP157A-DK1. Esta placa es bastante modesta en términos de equipamiento: no tiene una pantalla LCD como el STM32MP157C-DK2 o un periférico tan rico como el STM32MP157A-EV1. Sin embargo, hay una ranura para tarjeta microSD, una consola USB-UART, varios puertos USB y Ethernet. Para el primer comienzo, más que suficiente. Y para diluir la historia seca con una imagen, adjunto una foto de este tablero de depuración.



¿Qué es del software listo para usar?


En STMicroelectronics, todo suele ser bastante bueno en términos de hardware, pero terrible en términos de software. Todas estas modificaciones de Atollic True Studio, CubeMX, CubeIDE, que son cada vez más defectuosas con cada nueva versión, evocan cierta angustia. La situación es un poco mejor con el soporte STM32MP1. STMicroelectronics ofrece solo un cierto conjunto de OpenSTLinux. Este conjunto es una distribución construida utilizando el Proyecto Yocto. Por supuesto, todo esto puede existir de esta forma, pero para mí el principal inconveniente fue la falta de acceso a repositorios de distribuciones conocidas. Esto significa que no podrá poner en su placa ninguna utilidad de los repositorios de distribuciones populares simplemente ejecutando un comando como apt-get install. A menudo esto no es necesario para soluciones integradas, pero las situaciones son posibles,cuando tal oportunidad definitivamente no será superflua.

qué hacemos?


Entonces, la tarea es clara: necesitamos ejecutar una distribución popular en nuestro tablero de depuración. Mi elección recayó en Arch Linux. Esta no es la distribución más fácil, pero está bien adaptada para dispositivos ARM: hay ensamblajes listos para usar y un sitio oficial dedicado a esto.

Lo primero que traté de resolver el problema con un chasquido: acabo de deslizar el núcleo listo para el cargador de arranque de la distribución de Arch Linux, ensamblado bajo armv7. Esto a veces funcionó en otras placas, pero había un fiasco esperándome: a pesar de que el núcleo se ensambló para la arquitectura correcta, no comenzó. Bueno, entonces necesitas ensamblar tu kernel y al mismo tiempo tu cargador. Mi plan de acción fue este:

  1. Construye el gestor de arranque U-Boot.
  2. Construye el kernel de Linux.
  3. Marcamos la tarjeta microSD.
  4. Escribimos el gestor de arranque, el núcleo y el sistema de archivos raíz en la tarjeta microSD.
  5. Lucro

Preparación de la asamblea


Para implementar este plan, necesitamos una computadora con Linux y un lector de tarjetas para grabar en una tarjeta microSD. Utilicé una computadora portátil con Debian 10, pero en general esto no es importante, los nombres de las utilidades pueden diferir ligeramente. Entonces, ponemos las utilidades requeridas. Noto de inmediato que ahora y más todos los comandos deben ejecutarse como root o mediante sudo.

apt-get install git
apt-get install make
apt-get install gcc
apt-get install gcc-arm-linux-gnueabihf
apt-get install bison
apt-get install flex
apt-get install g++
apt-get install rsync
apt-get install libncurses-dev

En preparación para el ensamblaje, creamos tres directorios en el directorio de trabajo: u-boot (para el gestor de arranque), buildroot (para la compilación del sistema) y archlinux (para la distribución):

mkdir u-boot
mkdir buildroot
mkdir archlinux

Necesitaremos más estos directorios. Me referiré a estos nombres más adelante en el texto del artículo.

Ensamblaje de arranque en U


Ya se han escrito muchos artículos sobre U-Boot, y como parte de esto, no profundizaré en las explicaciones de qué es, para qué sirve y cómo funciona. Solo puedo decir que este es un gestor de arranque que proporciona arranque de Linux en dispositivos ARM. El código fuente para el gestor de arranque U-Boot está disponible en GitHub.

Para construir U-Boot, en primer lugar clonamos el repositorio de U-Boot en el directorio u-boot que creamos anteriormente:

git clone https://github.com/u-boot/u-boot

Para construir con éxito U-Boot, necesitamos un archivo de árbol de dispositivo y un archivo de configuración de U-Boot.

El archivo del árbol de dispositivos es un archivo dependiente del dispositivo. Este archivo describe la configuración del procesador para una placa específica. Si crea su hardware en un procesador ARM y planea ejecutar Linux en él, deberá desarrollar el archivo de árbol de su dispositivo (o adaptar uno listo para usar). Sin embargo, muchas placas de depuración ya tienen archivos listos para usar: los desarrolladores U-Boot interesados ​​los incluyen en su repositorio. Entonces, mira el directorio u-boot / arch / arm / dts. Debe contener el archivo stm32mp157a-dk1.dtb : este es el archivo de árbol de dispositivo para nuestra placa de depuración.

En el archivo de configuración de U-Boot, se escriben las configuraciones básicas del cargador de arranque.

Configurar U-Boot desde cero es un proceso bastante largo y laborioso, porque hay muchas configuraciones. Para estos fines, hay configuradores gráficos y de consola. Sin embargo, aquí tuvimos suerte: en el directorio u-boot / configs hay un archivo stm32mp15_basic_defconfig . Este es el archivo de configuración básica de U-Boot para las placas de depuración STM32MP15. Abrimos este archivo y vemos que para comenzar rápidamente es suficiente cambiar solo una línea: en su lugar

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157c-ev1”

escribir

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157a-dk1”

Con esta línea, le decimos al gestor de arranque que necesitamos usar el archivo de árbol del dispositivo para nuestra placa.

Ahora estás listo para construir U-Boot. Usamos nuestra configuración:

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp15_basic_defconfig

Y ejecuta la asamblea:

make CROSS_COMPILE=arm-linux-gnueabihf-

Si todo salió bien, entonces en el directorio u-boot deberíamos tener un montón de archivos. De estos, dos son de interés para nosotros: u-boot-spl.stm32 y u-boot.img .

El primer archivo es el denominado First Stage Boot Loader (FSBL). Está ubicado frente a U-Boot, se inicia primero e inicializa la memoria DDR3, que es necesaria para iniciar U-Boot. En otras placas, FSBL a menudo se combina con U-Boot en una imagen, pero aquí debe escribir cada imagen en una unidad flash USB por separado.

Eso es todo con U-Boot por ahora, guarde los archivos designados y proceda directamente al ensamblaje del kernel de Linux.

Ensamblaje del kernel de Linux


Usaré Buildroot para construir el kernel de Linux. Por supuesto, para estos propósitos, puede usar el Yocto igualmente popular, o incluso tratar de construir el núcleo desde la fuente de kernel.org. Sin embargo, tenía algo de experiencia trabajando con Buildroot, así que decidí hacerlo. Además, Buildroot también construye el sistema de archivos raíz (rootfs) e incluso el cargador U-Boot.

Ahora, por cualquier medio disponible, descargue el archivo de Buildroot desde el sitio web oficial , descomprímalo en el directorio de buildroot y vaya a él.

Como en el caso de U-Boot, lo primero que debe tener en cuenta es el archivo de configuración de nuestro hardware.

Vamos al directorio buildroot / configs y vemos que los desarrolladores ya han agregado un archivo de configuración para nuestra placa: hay un archivostm32mp157a_dk1_defconfig (verdadero para Buildroot-2020.05 build, en versiones anteriores de este archivo todavía no existía).

Traté de construir el kernel 5.4.26 usando este archivo de configuración, y generalmente comenzó con éxito en mi placa. Sin embargo, por alguna razón, el archivo del árbol de dispositivos Linux en este ensamblaje resultó truncado: de forma predeterminada, ni siquiera era compatible con los puertos USB. Esperemos que con el tiempo se solucione este error, pero ¿qué hacer ahora?

Busqué en Google este problema y encontré repositorios de STMicroelectronics, donde encontré fuentes de Linux 4.19 con parches para sus productos. Incluyendo, los archivos DTB correctos también estaban allí. Solo queda decirle a Buildroot que use este repositorio al construir el kernel. Para hacer esto, copie el archivo stm32mp157a_dk1_defconfig y cámbiele el nombre a stm32mp157a_dk1_new_defconfig . Ábralo y realice los siguientes cambios: en su

lugar

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_4=y

Nosotros escribimos

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_19=y

En lugar

BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.4.26"

Nosotros escribimos

BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="$(call github,STMicroelectronics,linux,v4.19-stm32mp-r1.2)/linux-v4.19-stm32mp-r1.2.tar.gz"

Guarde y cierre el archivo. El archivo de configuración está listo, apliquémoslo (debe ejecutarlo desde el directorio buildroot):

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp157a_dk1_new_defconfig

Este comando transferirá información desde nuestro archivo de configuración stm32mp157a_dk1_defconfig al archivo .config, que se encuentra en el directorio buildroot. En el futuro, el ensamblado se construirá sobre la base del archivo .config.

Entonces, ahora todo está casi listo para comenzar el proceso de compilación, pero antes de eso debe configurar nuestro núcleo.

Aquí vale la pena decir que, por defecto, se incluirá una funcionalidad mínima en el núcleo. Si queremos expandirlo, entonces el núcleo deberá configurarse por nosotros mismos. Como mínimo, deberá agregar soporte para el Grupo de control al núcleo: sin esto, nuestro Arch Linux no se iniciará. Además, como ejemplo, demostraré cómo agregar soporte para unidades flash USB al núcleo: como resultado, nuestra placa de depuración podrá trabajar con unidades flash.
Para iniciar el configurador de kernel desde el directorio buildroot, ejecute el comando

make linux-menuconfig

e ir a tomar el té. Este proceso no es rápido y, dependiendo de la potencia de su computadora, puede tomar de quince minutos a varias horas. Importante: durante el trabajo de buildroot necesita una conexión estable a Internet, se descargarán muchos paquetes diferentes.
Si en el proceso aparece un error

configure: error: you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
See `config.log' for more details

necesitará ejecutar el comando

export FORCE_UNSAFE_CONFIGURE=1

y reinicie el configurador del kernel.

Como resultado, debería aparecer la ventana del configurador:



Agregar soporte de Grupo de control: Configuración general -> Soporte de Grupo de control y establecer el asterisco con un espacio:



¿Y cómo agregar soporte para unidades flash?
SCSI . 80- , , , USB FLASH . Device Drivers -> SCSI support :



USB FLASH . Device Drivers -> USB support USB Mass Storage support:



, FLASH : File systems -> Native language support -> Codepage 437 File systems -> Native language support -> NLS ISO 8859-1:





, USB FLASH .

Después de realizar todos los ajustes en el configurador del núcleo, guárdelos con el botón Guardar y salga del configurador con el botón Salir .

Ahora solo queda comenzar el proceso de compilación con el comando:

make CROSS_COMPILE=arm-linux-gnueabihf-

y puedes ir a tomar el té por segunda vez, este proceso también lleva mucho tiempo.

Si todo salió bien, el siguiente conjunto de archivos debería aparecer en el directorio buildroot / output / images:

  • rootfs.ext2 es un sistema de archivos raíz compilado con ext2. No nos interesa;
  • rootfs.ext4 es un sistema de archivos raíz compilado con ext4. Nos será útil un poco más tarde;
  • sdcard.img : una imagen de una tarjeta microSD, que incluye FSBL + U-Boot + zImage + rootfs. Un archivo para los perezosos, le permite no molestarse en marcar una tarjeta microSD e inmediatamente cargar todo el sistema en ella. Por supuesto, este no es nuestro camino :).
  • stm32mp157a-dk1.dtb : archivo del árbol de dispositivos. Asegúrese de ser útil para iniciar el sistema;
  • u-boot.img y u-boot-spl.stm32 : archivo FSBL y U-Boot. Como los recolectamos en el último paso, no los necesitamos;
    ¿Por qué los recolectamos por separado?
    , Buildroot U-Boot. , . U-Boot, – Linux.
  • zImage - el corazón de todo el sistema - un archivo comprimido de kernel de Linux.

Entonces, el proceso de ensamblaje se completa, ahora procedemos a marcar la tarjeta de memoria microSD y crear particiones en ella.

Particionamiento y secciones de una tarjeta microSD


Marcar una tarjeta microSD y crear particiones es una etapa muy importante, fuertemente ligada a una plataforma de hardware específica. Desafortunadamente, la información sobre este problema en un procesador específico no siempre es fácil de encontrar, e incluso si recopila U-Boot totalmente funcional y el kernel de Linux, nada de esto funcionará con el más mínimo error en el diseño de la tarjeta microSD.

Inmediatamente, observo que la tarjeta microSD con la que se inicia el sistema en el STM32MP1 debe tener marcado GPT. La utilidad gdisk nos ayudará con esto , pero más sobre eso más adelante.

Las secciones de la tarjeta microSD deberían tener este aspecto:



Como puede ver en la figura, la tarjeta debe contener al menos 5 particiones: fsbl1, fsbl2, ssbl, kernel, rootfs. Además, también puede crear una o más secciones de datos para almacenar cualquier información sobre ellas.

Las secciones fsbl1 y fsbl2 son completamente idénticas y el cargador de arranque primario está escrito en ellas (como recordarán, este es el archivo u-boot-spl.stm32 que recibimos durante el proceso de ensamblaje de U-Boot). A pesar de que todo debería funcionar y con solo una de esas secciones, la documentación en STM2MP1 recomienda hacer dos de ellas. Otros requisitos se aplican a estas secciones:

  • Cada partición debe tener un tamaño de 256 KB.
  • , fsbl (fsbl1 fsbl2). : , .

La sección ssbl está diseñada para escribir el gestor de arranque U-Boot (el archivo u-boot.img que recibimos durante el proceso de ensamblaje de U-Boot). El tamaño de partición ssbl recomendado es de 2 MB.
La sección del kernel está destinada a escribirle el kernel de Linux (archivo zImage ), el árbol de dispositivos ( archivo stm32mp157a-dk1.dtb ), así como el script para U-Boot, con el que se iniciará el sistema. El tamaño de partición del núcleo recomendado es de 64 MB.

La sección rootfs es para escribir el sistema de archivos raíz. Intentaremos escribirle el sistema de archivos raíz compilado por Buildroot, así como el sistema de archivos raíz de Arch Linux. El tamaño de partición rootfs recomendado es de 1 GB o más.
La sección de datos está destinada a almacenar datos de usuario. Puedes hacer una o varias de estas secciones. Y puedes prescindir de él en absoluto. En este artículo, no crearé esta sección.

Entonces, comenzamos a marcar. Insertamos la tarjeta microSD en el lector de tarjetas de nuestra computadora con Linux a bordo y usando cualquier medio disponible (por ejemplo, usando dmesg) determinamos el nombre del dispositivo que aparece. En mi caso, esto es / dev / sdb. En su caso, puede ser un nombre diferente.

Ejecute la utilidad gdisk y elimine completamente el marcado en la tarjeta microSD:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): x
Expert command (? for help): z
About to wipe out GPT on /dev/sdb. Proceed? (Y/N): y
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.
Blank out MBR? (Y/N): y

Por si acaso, martillamos el comienzo de la tarjeta microSD con ceros.

dd if=/dev/zero of=/dev/sdb bs=1M count=64

Ahora ejecute gdisk nuevamente, agregue el marcado y cree 5 particiones en la tarjeta microSD de acuerdo con la tabla que proporcioné anteriormente:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: not present
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): n
Partition number (1-128, default 1): 1
First sector (34-30873566, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-30873566, default = 30873566) or {+-}size{KMGTP}: +256K
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-30873566, default = 4096) or {+-}size{KMGTP}: 
Last sector (4096-30873566, default = 30873566) or {+-}size{KMGTP}: +256K
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (3-128, default 3): 3
First sector (34-30873566, default = 6144) or {+-}size{KMGTP}: 
Last sector (6144-30873566, default = 30873566) or {+-}size{KMGTP}: +2M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (4-128, default 4): 4
First sector (34-30873566, default = 10240) or {+-}size{KMGTP}: 
Last sector (10240-30873566, default = 30873566) or {+-}size{KMGTP}: +64M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): n
Partition number (5-128, default 5): 5
First sector (34-30873566, default = 141312) or {+-}size{KMGTP}: 
Last sector (141312-30873566, default = 30873566) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Luego, agregue los nombres a las secciones de la tarjeta microSD. Como recordará, esto es especialmente crítico para las primeras secciones donde se escribirá FSBL: si no les asigna los nombres requeridos, el sistema no se iniciará:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): c
Partition number (1-5): 1
Enter name: fsbl1

Command (? for help): c
Partition number (1-5): 2
Enter name: fsbl2

Command (? for help): c
Partition number (1-5): 3
Enter name: ssbl

Command (? for help): c
Partition number (1-5): 4
Enter name: kernel

Command (? for help): c
Partition number (1-5): 5
Enter name: roootfs

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Al final del trabajo con la tarjeta microSD, necesitamos agregar el atributo de arranque BIOS heredado a la sección en la que escribiremos el kernel de Linux. Sin este atributo, el núcleo se negó a comenzar:

root@debian:/home/myuser# gdisk /dev/sdb
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): x

Expert command (? for help): a
Partition number (1-5): 4
Known attributes are:
0: system partition
1: hide from EFI
2: legacy BIOS bootable
60: read-only
62: hidden
63: do not automount

Attribute value is 0000000000000000. Set fields are:
  No fields set

Toggle which attribute field (0-63, 64 or <Enter> to exit): 2
Have enabled the 'legacy BIOS bootable' attribute.
Attribute value is 0000000000000004. Set fields are:
2 (legacy BIOS bootable)

Toggle which attribute field (0-63, 64 or <Enter> to exit): 

Expert command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
The operation has completed successfully.

Eso es todo, el diseño de la tarjeta de memoria está listo. Por si acaso, verifique que todo esté registrado como debería. Para hacer esto, ejecute gdisk nuevamente y ejecute el comando p . El resultado debería aconsejar la imagen:



ahora cree el sistema de archivos ext4 en / dev / sdb4 y / dev / sdb5:

mkfs.ext4 /dev/sdb4
mkfs.ext4 /dev/sdb5

Y prescribimos etiquetas de volumen para que luego sea más fácil acceder a ellas:

e2label /dev/sdb4 kernel
e2label /dev/sdb5 rootfs

Esto completa la creación de secciones de la tarjeta de memoria, puede proceder a escribir archivos en ella.

Grabación de tarjeta microSD


Entonces, en la etapa actual, todo está listo para grabar en una tarjeta microSD. Lo insertamos en el lector de tarjetas de la computadora Linux y escribimos el gestor de arranque primario (FSBL) en la primera y segunda sección de la tarjeta mocroSD:

dd if=u-boot/u-boot-spl.stm32 of=/dev/sdb1
dd if=u-boot/u-boot-spl.stm32 of=/dev/sdb2

Ahora escriba U-Boot en la tercera sección de la tarjeta microSD:

dd if=u-boot/u-boot.img of=/dev/sdb3

A continuación, debe copiar el núcleo, el archivo del árbol de dispositivos y la secuencia de comandos de arranque en la cuarta sección de la tarjeta microSD.

Antes de comenzar a copiar archivos, necesita una pequeña explicación sobre el script de descarga. En este script, de hecho, se indica diversa información para U-Boot, con la ayuda de la cual puede arrancar el sistema y transferir el control al kernel. Hay diferentes formas de escribir estos scripts, pero el más simple (en mi opinión) se describe en la documentación de STM32MP1: debe crear el directorio / extlinux en la raíz de la sección del núcleo y crear un archivo de texto con el nombre extlinux.conf con los siguientes contenidos:

LABEL stm32mp157a-dk1
KERNEL /zImage
FDT /stm32mp157a-dk1.dtb
APPEND root=/dev/mmcblk0p5 rootwait rw console=ttySTM0,115200

Aquí todo es bastante simple: le decimos al cargador dónde obtener el núcleo, el árbol de dispositivos, el sistema de archivos raíz y decimos que tendremos el puerto ttySTM0 como consola de trabajo.

Ahora copie el kernel:

cp -a buildroot/output/images/zImage /media/myuser/kernel/

Nota: en el directorio / media / myuser /, monte una tarjeta microSD cuando esté instalada en el lector de tarjetas. En su caso, puede ser un directorio diferente.

Copie el archivo del árbol del dispositivo:

cp -a buildroot/output/images/stm32mp157a-dk1.dtb /media/myuser/kernel/

Crea un directorio:

mkdir /media/myuser/kernel/extlinux

Crea un archivo:

nano /media/myuser/kernel/extlinux/extlinux.conf

y llénalo con el contenido:

LABEL stm32mp157a-dk1
KERNEL /zImage
FDT /stm32mp157a-dk1.dtb
APPEND root=/dev/mmcblk0p5 rootwait rw console=ttySTM0,115200

Guarde el archivo y cierre el editor.

En esto, la cuarta sección de la tarjeta microSD está lista: el kernel de Linux y todos los archivos auxiliares ya están escritos. Ya en esta etapa, si inserta una tarjeta microSD en la placa de depuración, el kernel de Linux debe cargarse, sin embargo, al final se bloqueará en el kernel panic debido al hecho de que el sistema de archivos raíz no se puede montar. Esto no es sorprendente, porque lo hemos grabado hasta ahora.

Existe la etapa final, en la que escribiremos el sistema de archivos raíz en la tarjeta microSD. Y aquí hay varias opciones posibles:

  1. Escriba el sistema de archivos raíz generado por Buildroot
  2. Reescribe el sistema de archivos raíz Arch Linux

Primero, escriba el sistema de archivos raíz que Buildroot generó para nosotros e intente comenzar con él. Este no era el propósito de este artículo, pero me pareció que, en general, podría ser útil para cualquier aplicación, especialmente porque esta acción no lleva mucho tiempo. El sistema de archivos raíz se escribe en la quinta sección de nuestra tarjeta microSD con un solo comando:

dd if=buildroot/output/images/rootfs.ext4 of=/dev/sdb5

Ahora inserte la tarjeta de memoria en la placa de depuración e inicie el sistema. Observaremos la salida de información de depuración a través de la consola USB-UART: el acceso se proporciona a través de un puerto microUSB en la placa STM32MP157A-DK1. La visualización de la información mostrada es posible en cualquier programa de terminal, por ejemplo, Putty o Minicom. Para los fines de este artículo, utilicé este último abriendo otra ventana de terminal en Debian.

Ahora insertamos la tarjeta microSD en la placa de depuración, suministramos energía a la placa y miramos el terminal. Si todo se hizo correctamente, entonces los registros de FSBL, U-Boot, kernel se deben verter allí y, en última instancia, aparecerá una invitación para ingresar al inicio de sesión. Entramos en la raíz y, voila, llegamos a la consola del sistema que acabamos de recopilar:



Sí, ni siquiera tiene un administrador de paquetes y, en general, la funcionalidad es muy pobre, pero con la ayuda de Buildroot puedes construirlo muy bien y crear un sistema complejo realmente funcional. Mientras tanto, su tamaño es de solo 7 megabytes.



Después de asegurarse de que el sistema de archivos raíz casero se inicia correctamente, es hora de iniciar Arch Linux. Nuevamente, inserte la tarjeta microSD en el lector de tarjetas de nuestra computadora y formatee nuevamente la quinta sección de la tarjeta de memoria:

mkfs.ext4 /dev/sdb5

Descargue el archivo con Arch Linux, ensamblado bajo armv7, desde el sitio oficial. Descomprima el archivo en el directorio archlinux y use el comando:

cp -a archlinux/* /media/myuser/rootfs 

Cópielo en la sección rootfs de la tarjeta microSD.

Limpiamos el directorio / media / myuser / rootfs / boot: no necesitamos los contenidos, porque el núcleo y el árbol de dispositivos están en una sección separada de la tarjeta microSD:

rm –rf /media/myuser/rootfs/boot/*

Más tarde, puede montar la partición / dev / sdb4 en el directorio de arranque, donde tenemos la imagen del kernel.

Después de eso, inserte la tarjeta microSD en la placa de depuración, energícese y disfrute trabajando ArchLinux:



Después de que Arch Linux se inició con éxito, decidí intentar ejecutar Debian también en la placa de depuración. Utilizando manipulaciones absolutamente similares con el sistema de archivos raíz, funcionó con éxito:



Conclusión


En este artículo, jugamos lo suficiente con la placa de depuración STM32MP157A-DK1: colocamos U-Boot, el kernel de Linux, nuestro propio sistema de archivos raíz, y también lanzamos Arch Linux y Debian. Espero que este material sea útil para alguien cuando trabaje con procesadores de la familia STM32MP1 o con cualquier otra placa única en ARM.


All Articles