STM32MP1: U-Boot, Buildroot, Arch Linux und ein bisschen Debian

Hallo Habr!

Vor einiger Zeit hat STMicroelectronics interessante Prozessoren der STM32MP1-Serie auf den Markt gebracht. Als ich endlich das Debug-Board auf der Basis dieses Prozessors in die Hände bekam, stellte ich überrascht fest, dass es keine Builds gibt, die auf gängigen Distributionen (Debian, Arch Linux usw.) basieren. Alles, was blieb, war zu versuchen, ein Distributionskit für dieses Board selbst anzupassen. Basierend auf den Ergebnissen dieses Artikels erschien dieser Artikel.



Was sind die Eigenschaften?


Dieser Artikel wäre ohne einen kurzen Überblick über die Eigenschaften der Prozessoren der STM32MP1-Serie nicht vollständig. Die STM32MP1-Serie umfasst drei Prozessorfamilien: STM32MP151, STM32MP153 und STM32MP157. Ihre Hauptmerkmale sind in der Tabelle angegeben.



Wie Sie der Tabelle entnehmen können, besteht der Unterschied zwischen den Familien darin, dass STM32MP151 einen Kern von Cortex-A7 hat, während STM32MP153 und STM32MP157 zwei solche Kerne haben und STM32MP157 auch 3D-GPU-Unterstützung bietet. Im Allgemeinen machen die Eigenschaften dieser Prozessoren im Jahr 2020 jedoch keinen Eindruck, sie sind eher bescheiden. Warum habe ich immer noch auf sie geachtet?

Warum STM32MP1?


In der Tat kann sich eine völlig logische Frage stellen: Gibt es einen Himbeer-Pi, einen Bananen-Pi, einen Orange-Pi und schließlich - warum brauchen wir einen anderen STM32MP1? Darüber hinaus weisen alle diese Boards in der Regel eine deutlich höhere Leistung auf als das Objekt unserer Studie. Die Antwort ist einfach: Während Sie für den Heimgebrauch basteln, müssen Sie die Himbeere nehmen, und es wird richtig sein. Wenn es sich jedoch um Massenprodukte für industrielle Anwendungen handelt, spielen hier andere Dinge eine entscheidende Rolle, dank derer der STM32MP1 der Gewinner ist:

  • Betriebstemperaturbereich. Für STM32MP1 beginnt es bei minus 40 Grad, während es für viele Prozessoren anderer Single-Board-Computer gut ist, wenn es minus 20 ist.
  • . STMicroelectronics , .
  • . DigiKey Mouser STM32MP1, .

Natürlich ist ST32MP1 nicht der einzige Prozessor auf dem Markt für industrielle Anwendungen. Es gibt sowohl NXP als auch TI. Was TI betrifft, hatte ich ein Projekt eines ziemlich komplexen Moduls, das darauf basierte, und es gab ein Sediment aus einer bemerkenswerten Anzahl von Hardwarefunktionen, die nicht in der Dokumentation behandelt wurden, aber wenn es nicht beachtet wurde, konnte der Prozessor vollständig ausfallen, und zwar nicht sofort, sondern im Laufe der Zeit und im ungünstigsten Moment. Darüber hinaus handelte es sich um einen Single-Core-Prozessor, und mit zunehmender Anzahl der ihm zugewiesenen Aufgaben traten immer häufiger Leistungsprobleme auf. Zur gleichen Zeit beschäftigte ich mich mit STMicroelectronics-Mikrocontrollern, und sie erwiesen sich als ziemlich gut, also entschied ich mich, diesen neuen Kleinen auszuwählen.

Debug Board


Für Experimente habe ich ein STM32MP157A-DK1-Debugboard gekauft. Diese Karte ist in Bezug auf die Ausstattung eher bescheiden: Sie verfügt nicht über ein LCD-Display wie das STM32MP157C-DK2 oder ein so reichhaltiges Peripheriegerät wie das STM32MP157A-EV1. Es gibt jedoch einen microSD-Kartensteckplatz, eine USB-UART-Konsole, mehrere USB-Anschlüsse und Ethernet. Für den ersten Start mehr als genug. Und um die trockene Geschichte mit einem Bild zu verwässern, füge ich ein Foto dieses Debug-Boards bei.



Was ist von vorgefertigter Software?


Bei STMicroelectronics ist normalerweise alles in Bezug auf Hardware recht gut, aber in Bezug auf Software schrecklich. All diese Modifikationen von Atollic True Studio, CubeMX, CubeIDE, die mit jeder neuen Version mehr und mehr fehlerhaft sind, rufen einige Qualen hervor. Mit der Unterstützung von STM32MP1 ist die Situation etwas besser. STMicroelectronics bietet nur eine bestimmte Baugruppe von OpenSTLinux an. Diese Assembly ist eine Distribution, die mit dem Yocto-Projekt erstellt wurde. Natürlich kann all dies in dieser Form existieren, aber für mich war der Hauptnachteil der fehlende Zugang zu Repositories bekannter Distributionen. Dies bedeutet, dass Sie kein Dienstprogramm aus den Repositorys beliebter Distributionen auf Ihr Board setzen können, indem Sie einfach einen Befehl wie apt-get install ausführen. Oft ist dies für eingebettete Lösungen nicht erforderlich, aber Situationen sind möglich,wenn eine solche Gelegenheit definitiv nicht überflüssig sein wird.

Was werden wir machen?


Die Aufgabe ist also klar: Wir müssen eine beliebte Distribution auf unserem Debugboard ausführen. Meine Wahl fiel auf Arch Linux. Dies ist nicht die einfachste Distribution, aber sie ist gut für ARM-Geräte geeignet: Es gibt fertige Baugruppen und eine offizielle Website, die sich diesem Thema widmet.

Das erste, was ich versuchte, das Problem mit einem Snap zu lösen - ich habe gerade den Bootloader-fähigen Kern aus der Distribution von Arch Linux entfernt, die unter armv7 zusammengestellt wurde. Dies funktionierte manchmal auf anderen Boards, aber es wartete ein Fiasko auf mich: Trotz der Tatsache, dass der Kernel für die richtige Architektur zusammengestellt wurde, startete er nicht. Nun, dann müssen Sie Ihren Kernel und gleichzeitig Ihren Loader zusammenbauen. Mein Aktionsplan war folgender:

  1. Erstellen Sie den U-Boot-Bootloader.
  2. Erstellen Sie den Linux-Kernel.
  3. Wir markieren die microSD-Karte.
  4. Wir schreiben den Bootloader, den Kernel und das Root-Dateisystem auf die microSD-Karte.
  5. Profitieren

Montagevorbereitung


Um diesen Plan umzusetzen, benötigen wir einen Computer mit Linux und einen Kartenleser für die Aufzeichnung auf einer microSD-Karte. Ich habe einen Laptop mit Debian 10 verwendet, aber im Allgemeinen ist dies nicht wichtig, die Namen der Dienstprogramme können sich nur geringfügig unterscheiden. Also setzen wir die erforderlichen Dienstprogramme. Ich stelle sofort fest, dass ab und zu alle Befehle als root oder über sudo ausgeführt werden müssen.

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

Zur Vorbereitung der Assembly erstellen wir drei Verzeichnisse im Arbeitsverzeichnis: u-boot (für den Bootloader), buildroot (für den Systembuild) und archlinux (für die Distribution):

mkdir u-boot
mkdir buildroot
mkdir archlinux

Wir werden diese Verzeichnisse weiter brauchen. Ich werde später im Text des Artikels auf diese Namen verweisen.

U-Boot-Baugruppe


Es wurden bereits viele Artikel über U-Boot geschrieben, und als Teil davon werde ich nicht näher darauf eingehen, was es ist, wofür es ist und wie es funktioniert. Ich kann nur sagen, dass dies ein Bootloader ist, der den Linux-Start auf ARM-Geräten ermöglicht. Der Quellcode für den U-Boot-Bootloader ist auf GitHub verfügbar.

Um U-Boot zu erstellen, klonen wir zunächst das U-Boot-Repository in das zuvor erstellte U-Boot-Verzeichnis:

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

Um U-Boot erfolgreich zu erstellen, benötigen wir eine Gerätebaumdatei und eine U-Boot-Konfigurationsdatei.

Die Gerätebaumdatei ist eine geräteabhängige Datei. Diese Datei beschreibt die Konfiguration des Prozessors für eine bestimmte Karte. Wenn Sie Ihre Hardware auf einem ARM-Prozessor basieren und Linux darauf ausführen möchten, müssen Sie Ihre Gerätebaumdatei dafür entwickeln (oder eine vorgefertigte anpassen). Viele Debug-Boards haben jedoch bereits vorgefertigte Dateien: Fürsorgliche U-Boot-Entwickler nehmen sie in ihr Repository auf. Schauen Sie sich also das Verzeichnis u-boot / arch / arm / dts an. Es sollte die Datei stm32mp157a-dk1.dtb enthalten - dies ist die Gerätebaumdatei für unser Debugboard.

In der U-Boot-Konfigurationsdatei werden die grundlegenden Bootloader-Einstellungen geschrieben.

Das Konfigurieren von U-Boot von Grund auf ist ein ziemlich langer und mühsamer Prozess, da es so viele Einstellungen gibt. Für diese Zwecke gibt es sowohl Konsolen- als auch Grafikkonfiguratoren. Hier hatten wir jedoch Glück: Im Verzeichnis u-boot / configs befindet sich eine Datei stm32mp15_basic_defconfig . Dies ist die U-Boot-Grundkonfigurationsdatei für die STM32MP15-Debugboards. Wir öffnen diese Datei und sehen, dass es für einen schnellen Start ausreicht, nur eine Zeile zu ändern: stattdessen

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157c-ev1”

schreiben

CONFIG_DEFAULT_DEVICE_TREE=”stm32mp157a-dk1”

Mit dieser Zeile teilen wir dem Bootloader mit, dass wir die Gerätebaumdatei für unser Board verwenden müssen.

Jetzt können Sie U-Boot erstellen. Wir verwenden unsere Konfiguration:

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp15_basic_defconfig

Führen Sie die Assembly aus:

make CROSS_COMPILE=arm-linux-gnueabihf-

Wenn alles reibungslos lief, sollten wir im U-Boot-Verzeichnis eine Reihe von Dateien haben. Von diesen sind zwei für uns von Interesse: u-boot-spl.stm32 und u-boot.img .

Die erste Datei ist der sogenannte First Stage Boot Loader (FSBL). Es befindet sich vor dem U-Boot, startet zuerst und initialisiert den DDR3-Speicher, der zum Starten von U-Boot erforderlich ist. In anderen Boards wird FSBL häufig mit U-Boot zu einem Image kombiniert. Hier müssen Sie jedoch jedes Image separat auf ein USB-Flash-Laufwerk schreiben.

Das ist alles mit U-Boot, speichern Sie die angegebenen Dateien und fahren Sie direkt mit der Linux-Kernel-Assembly fort.

Linux-Kernel-Assembly


Ich werde Buildroot verwenden, um den Linux-Kernel zu erstellen. Für diese Zwecke können Sie natürlich das ebenso beliebte Yocto verwenden oder sogar versuchen, den Kernel aus der Quelle von kernel.org zu erstellen. Ich hatte jedoch einige Erfahrungen mit Buildroot und habe mich daher dafür entschieden. Darüber hinaus erstellt Buildroot auch das Root-Dateisystem (rootfs) und sogar den U-Boot-Loader.

Laden Sie nun mit allen verfügbaren Mitteln das Archiv von Buildroot von der offiziellen Website herunter , entpacken Sie es in das Buildroot-Verzeichnis und rufen Sie es auf.

Wie bei U-Boot müssen Sie sich zunächst um die Konfigurationsdatei für unsere Hardware kümmern.

Wir gehen zum Verzeichnis buildroot / configs und sehen, dass die Entwickler bereits eine Konfigurationsdatei für unser Board hinzugefügt haben: Es gibt eine Dateistm32mp157a_dk1_defconfig (true für Build Build Build-2020.05, in früheren Versionen dieser Datei war dies noch nicht der Fall).

Ich habe versucht, den 5.4.26-Kernel mit dieser Konfigurationsdatei zu erstellen, und er wurde im Allgemeinen erfolgreich auf meinem Board gestartet. Aus irgendeinem Grund wurde die Linux-Gerätebaumdatei in dieser Assembly jedoch abgeschnitten: Standardmäßig wurden USB-Anschlüsse nicht einmal unterstützt. Hoffen wir, dass dieser Fehler im Laufe der Zeit behoben wird, aber was tun jetzt?

Ich habe dieses Problem googelt und bin auf STMicroelectronics-Repositorys gestoßen, in denen ich Linux 4.19-Quellen mit Patches für ihre Produkte gefunden habe. Einschließlich der richtigen DTB-Dateien waren auch da. Es bleibt nur Buildroot anzuweisen, dieses Repository beim Erstellen des Kernels zu verwenden. Kopieren Sie dazu die Datei stm32mp157a_dk1_defconfig und benennen Sie sie in stm32mp157a_dk1_new_defconfig um . Öffnen Sie es und nehmen Sie die folgenden Änderungen vor:

Stattdessen

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_4=y

Wir schreiben

BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_19=y

Stattdessen

BR2_LINUX_KERNEL_CUSTOM_VERSION=y
BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.4.26"

Wir schreiben

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"

Speichern und schließen Sie die Datei. Die Konfigurationsdatei ist fertig. Wenden wir sie an (Sie müssen sie aus dem Buildroot-Verzeichnis ausführen):

make CROSS_COMPILE=arm-linux-gnueabihf- stm32mp157a_dk1_new_defconfig

Dieser Befehl überträgt Informationen aus unserer Konfigurationsdatei stm32mp157a_dk1_defconfig in die .config-Datei, die sich im Buildroot-Verzeichnis befindet. In Zukunft wird die Assembly auf der Basis der .config-Datei erstellt.

Jetzt ist fast alles bereit, um den Build-Prozess zu starten, aber vorher müssen Sie unseren Kernel konfigurieren.

Hier ist anzumerken, dass standardmäßig minimale Funktionen im Kernel enthalten sind. Wenn wir es erweitern möchten, muss der Kernel für uns selbst konfiguriert werden. Zumindest müssen Sie dem Kernel Unterstützung für die Kontrollgruppe hinzufügen: Ohne dies wird unser Arch Linux nicht gestartet. Darüber hinaus werde ich als Beispiel zeigen, wie dem Kernel Unterstützung für USB-Flash-Laufwerke hinzugefügt wird: Dadurch kann unser Debug-Board mit Flash-Laufwerken arbeiten.
Führen Sie den Befehl aus, um den Kernel-Konfigurator über das Buildroot-Verzeichnis zu starten

make linux-menuconfig

und Tee trinken gehen. Dieser Vorgang ist nicht schnell und kann je nach Leistung Ihres Computers zwischen fünfzehn Minuten und mehreren Stunden dauern. Wichtig: Während der Arbeit von buildroot benötigen Sie eine stabile Verbindung zum Internet. Viele verschiedene Pakete werden heruntergeladen.
Wenn dabei ein Fehler auftritt

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

muss den Befehl ausführen

export FORCE_UNSAFE_CONFIGURE=1

und starten Sie den Kernel-Konfigurator neu.

Infolgedessen sollte das Konfiguratorfenster angezeigt werden:



Unterstützung für Kontrollgruppen hinzufügen: Allgemeine Einrichtung -> Unterstützung für Kontrollgruppen und das Sternchen mit einem Leerzeichen versehen:



Und wie füge ich Unterstützung für Flash-Laufwerke hinzu?
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 .

Nachdem alle Einstellungen im Kernel-Konfigurator vorgenommen wurden, speichern Sie sie mit der Schaltfläche Speichern und beenden Sie den Konfigurator mit der Schaltfläche Beenden .

Jetzt muss der Erstellungsprozess nur noch mit dem folgenden Befehl gestartet werden:

make CROSS_COMPILE=arm-linux-gnueabihf-

und Sie können ein zweites Mal Tee trinken gehen, dieser Vorgang nimmt auch viel Zeit in Anspruch.

Wenn alles reibungslos verlief, sollten die folgenden Dateien im Verzeichnis buildroot / output / images angezeigt werden:

  • rootfs.ext2 ist ein kompiliertes Root-Dateisystem mit ext2. Es interessiert uns nicht;
  • rootfs.ext4 ist ein kompiliertes Root-Dateisystem mit ext4. Es wird uns etwas später nützlich sein;
  • sdcard.img - Ein Image einer microSD-Karte, einschließlich FSBL + U-Boot + zImage + rootfs. Als Datei für Faulenzer können Sie sich nicht die Mühe machen, eine microSD-Karte zu markieren und das gesamte System sofort darauf hochzuladen. Das ist natürlich nicht unser Weg :).
  • stm32mp157a-dk1.dtb - Gerätebaumdatei. Stellen Sie sicher, dass Sie sich beim Starten des Systems als nützlich erweisen.
  • u-boot.img und u-boot-spl.stm32 - Datei FSBL und U-Boot. Da wir sie im letzten Schritt gesammelt haben, brauchen wir sie nicht.
    Warum haben wir sie separat gesammelt?
    , Buildroot U-Boot. , . U-Boot, – Linux.
  • zImage - das Herzstück des gesamten Systems - eine komprimierte Linux- Kerneldatei .

Damit ist der Montageprozess abgeschlossen. Nun markieren wir die microSD-Speicherkarte und erstellen Partitionen darauf.

Partitionierung und Abschnitte einer microSD-Karte


Das Markieren einer microSD-Karte und das Erstellen von Partitionen ist eine sehr wichtige Phase, die stark an eine bestimmte Hardwareplattform gebunden ist. Leider sind Informationen zu diesem Problem auf einem bestimmten Prozessor nicht immer leicht zu finden, und selbst wenn Sie voll funktionsfähigen U-Boot und den Linux-Kernel sammeln, funktioniert nichts davon mit dem geringsten Fehler im Layout der microSD-Karte.

Ich stelle sofort fest, dass die microSD-Karte, mit der das System auf dem STM32MP1 gestartet wird, über ein GPT-Markup verfügen muss. Das Dienstprogramm gdisk hilft uns dabei , aber dazu später mehr.

Die microSD-Kartenabschnitte sollten folgendermaßen aussehen:



Wie Sie der Abbildung entnehmen können, muss die Karte mindestens 5 Partitionen enthalten: fsbl1, fsbl2, ssbl, kernel, rootfs. Darüber hinaus können Sie auch einen oder mehrere Datenabschnitte erstellen, um Informationen darüber zu speichern.

Die Abschnitte fsbl1 und fsbl2 sind vollständig identisch und der primäre Bootloader wird in sie geschrieben (wie Sie sich erinnern, ist dies die Datei u-boot-spl.stm32 , die wir während des U-Boot-Montageprozesses erhalten haben). Trotz der Tatsache, dass alles funktionieren sollte und nur ein solcher Abschnitt vorhanden ist, wird in der Dokumentation zu STM2MP1 empfohlen, zwei davon auszuführen. Für diese Abschnitte gelten andere Anforderungen:

  • Jede Partition muss 256 KB groß sein.
  • , fsbl (fsbl1 fsbl2). : , .

Der Abschnitt ssbl dient zum Schreiben des U-Boot-Bootloaders (der Datei u-boot.img , die wir während des U-Boot-Montageprozesses erhalten haben). Die empfohlene ssbl-Partitionsgröße beträgt 2 MB.
Der Kernel- Abschnitt dient zum Schreiben des Linux-Kernels ( zImage- Datei ), des Gerätebaums ( stm32mp157a-dk1.dtb-Datei ) sowie des Skripts für U-Boot, mit dem das System gestartet wird. Die empfohlene Kernel-Partitionsgröße beträgt 64 MB.

Der Abschnitt rootfs dient zum Schreiben des Root-Dateisystems. Wir werden versuchen, das von Buildroot kompilierte Root-Dateisystem sowie das Root-Dateisystem von Arch Linux darauf zu schreiben. Die empfohlene Rootfs-Partitionsgröße beträgt 1 GB oder mehr.
Der Datenbereich dient zum Speichern von Benutzerdaten. Sie können einen solchen oder mehrere Abschnitte erstellen. Und darauf können Sie überhaupt verzichten. In diesem Artikel werde ich diesen Abschnitt nicht erstellen.

Also fangen wir an zu markieren. Wir stecken die microSD-Karte mit Linux an Bord in den Kartenleser unseres Computers und bestimmen mit allen verfügbaren Mitteln (z. B. mit dmesg) den Namen des angezeigten Geräts. In meinem Fall ist dies / dev / sdb. In Ihrem Fall kann es sich um einen anderen Namen handeln.

Führen Sie das Dienstprogramm gdisk aus und löschen Sie das Markup auf der microSD-Karte vollständig:

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

Für alle Fälle hämmern wir den Anfang der microSD-Karte mit Nullen.

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

Führen Sie nun gdisk erneut aus, fügen Sie das Markup hinzu und erstellen Sie 5 Partitionen auf der microSD-Karte gemäß der oben angegebenen Tabelle:

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.

Fügen Sie als Nächstes die Namen zu den Abschnitten auf der microSD-Karte hinzu. Wie Sie sich erinnern, ist dies besonders wichtig für die ersten Abschnitte, in denen FSBL geschrieben wird: Wenn Sie ihnen nicht die erforderlichen Namen zuweisen, startet das System nicht:

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.

Am Ende der Arbeit mit der microSD-Karte müssen wir dem Abschnitt, in den wir den Linux-Kernel schreiben, das alte bootfähige BIOS-Attribut hinzufügen . Ohne dieses Attribut weigerte sich der Kernel zu starten:

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.

Das ist alles, das Layout der Speicherkarte ist fertig. Überprüfen Sie für alle Fälle, ob alles so aufgezeichnet ist, wie es sollte. Führen Sie dazu gdisk erneut aus und führen Sie den Befehl p aus . Das Ergebnis sollte das Bild



anzeigen: Erstellen Sie nun das ext4-Dateisystem unter / dev / sdb4 und / dev / sdb5:

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

Und wir schreiben Volumenbezeichnungen vor, damit später leichter darauf zugegriffen werden kann:

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

Damit ist die Erstellung von Abschnitten der Speicherkarte abgeschlossen. Sie können fortfahren, Dateien darauf zu schreiben.

MicroSD-Kartenaufzeichnung


Zum gegenwärtigen Zeitpunkt ist also alles für die Aufnahme auf einer microSD-Karte bereit. Wir legen es in den Kartenleser des Linux-Computers ein und schreiben den primären Bootloader (FSBL) in den ersten und zweiten Abschnitt der mocroSD-Karte:

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

Schreiben Sie nun U-Boot in den dritten Abschnitt der microSD-Karte:

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

Als nächstes müssen Sie den Kernel, die Gerätebaumdatei und das Boot-Skript in den vierten Abschnitt der microSD-Karte kopieren.

Bevor Sie mit dem Kopieren von Dateien beginnen, benötigen Sie eine kurze Erläuterung des Download-Skripts. In diesem Skript werden tatsächlich verschiedene Informationen für U-Boot angegeben, mit deren Hilfe das System gestartet und die Steuerung an den Kernel übertragen werden kann. Es gibt verschiedene Möglichkeiten, diese Skripte zu schreiben, aber die einfachste (meiner Meinung nach) ist in der Dokumentation zu STM32MP1 beschrieben: Sie müssen das Verzeichnis / extlinux im Stammverzeichnis des Kernelabschnitts erstellen und eine Textdatei mit dem Namen extlinux.conf mit den folgenden Inhalten erstellen :

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

Hier ist alles ganz einfach: Wir teilen dem Loader mit, wo er den Kernel, den Gerätebaum und das Root-Dateisystem erhalten soll, und sagen, dass wir den ttySTM0-Port als Arbeitskonsole haben werden.

Kopieren Sie nun den Kernel:

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

Hinweis: Im Verzeichnis / media / myuser / mounte ich eine microSD-Karte, wenn sie im Kartenleser installiert ist. In Ihrem Fall kann es sich um ein anderes Verzeichnis handeln.

Kopieren Sie die Gerätebaumdatei:

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

Erstellen Sie ein Verzeichnis:

mkdir /media/myuser/kernel/extlinux

Erstellen Sie eine Datei:

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

und fülle es mit dem Inhalt:

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

Speichern Sie die Datei und schließen Sie den Editor.

Hierzu ist der vierte Abschnitt der microSD-Karte fertig: Der Linux-Kernel und alle dazugehörigen Hilfsdateien sind bereits geschrieben. Wenn Sie bereits zu diesem Zeitpunkt eine microSD-Karte in das Debugboard einlegen, sollte der Linux-Kernel geladen werden. Am Ende stürzt er jedoch in Kernel-Panik ab, da das Root-Dateisystem nicht gemountet werden kann. Dies ist nicht überraschend, da wir es bisher aufgenommen haben.

Es gibt die letzte Phase, in der wir das Root-Dateisystem auf die microSD-Karte schreiben. Und hier sind verschiedene Möglichkeiten möglich:

  1. Schreiben Sie das von Buildroot generierte Root-Dateisystem
  2. Schreiben Sie das Arch Linux-Root-Dateisystem neu

Schreiben Sie zunächst das Root-Dateisystem auf, das Buildroot für uns generiert hat, und versuchen Sie, damit zu beginnen. Dies war nicht der Zweck dieses Artikels, aber es schien mir, dass es im Allgemeinen für alle Anwendungen nützlich sein könnte, zumal diese Aktion nicht viel Zeit in Anspruch nimmt. Das Root-Dateisystem wird mit nur einem Befehl in den fünften Abschnitt unserer microSD-Karte geschrieben:

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

Setzen Sie nun die Speicherkarte in die Debug-Karte ein und starten Sie das System. Wir werden die Ausgabe von Debugging-Informationen über die USB-UART-Konsole beobachten: Der Zugriff darauf erfolgt über einen Micro-USB-Anschluss auf der STM32MP157A-DK1-Karte. Das Anzeigen der angezeigten Informationen ist in jedem Terminalprogramm möglich, z. B. Putty oder Minicom. Für die Zwecke dieses Artikels habe ich letzteres verwendet, indem ich ein anderes Terminalfenster in Debian geöffnet habe.

Jetzt setzen wir die microSD-Karte in die Debug-Karte ein, versorgen die Karte mit Strom und sehen uns das Terminal an. Wenn alles richtig gemacht wurde, sollten die FSBL-, U-Boot- und Kernel-Protokolle dort eingefügt werden und schließlich wird eine Einladung zur Eingabe des Logins angezeigt. Wir geben root ein und - voila - gelangen zur Konsole des Systems, das wir gerade gesammelt haben:



Ja, es gibt nicht einmal einen Paketmanager, und im Allgemeinen ist die Funktionalität sehr schlecht, aber mit Hilfe von Buildroot können Sie es sehr cool erstellen und ein wirklich funktionierendes komplexes System erstellen. In der Zwischenzeit beträgt seine Größe nur 7 Megabyte!



Nachdem Sie sichergestellt haben, dass das hausgemachte Root-Dateisystem erfolgreich gestartet wurde, ist es Zeit, Arch Linux zu starten. Setzen Sie die microSD-Karte erneut in den Kartenleser unseres Computers ein und formatieren Sie den fünften Abschnitt der Speicherkarte erneut:

mkfs.ext4 /dev/sdb5

Laden Sie das unter armv7 zusammengestellte Archiv mit Arch Linux von der offiziellen Website herunter. Entpacken Sie das Archiv in das archlinux-Verzeichnis und verwenden Sie den folgenden Befehl:

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

Kopieren Sie es in den rootfs-Bereich der microSD-Karte.

Wir bereinigen das Verzeichnis / media / myuser / rootfs / boot: Wir benötigen den Inhalt nicht, da sich der Kernel und der Gerätebaum in einem separaten Abschnitt der microSD-Karte befinden:

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

Später können Sie die Partition / dev / sdb4 im Boot-Verzeichnis bereitstellen, in dem sich das Kernel-Image befindet.

Setzen Sie danach die microSD-Karte in das Debug-Board ein, aktivieren Sie die Arbeit und genießen Sie die Arbeit mit ArchLinux:



Nachdem Arch Linux erfolgreich gestartet wurde, habe ich beschlossen, Debian auch auf dem Debug-Board auszuführen. Mit absolut ähnlichen Manipulationen mit dem Root-Dateisystem hat es erfolgreich funktioniert:



Fazit


In diesem Artikel haben wir genug mit dem Debug-Board STM32MP157A-DK1 gespielt: Legen Sie U-Boot, den Linux-Kernel und unser eigenes Root-Dateisystem darunter und starten Sie Arch Linux und Debian. Ich hoffe, dass dieses Material für jemanden nützlich ist, sowohl bei der Arbeit mit Prozessoren der STM32MP1-Familie als auch mit anderen Single-Boards auf ARM.


All Articles