Buildroot i STM32MP257F-DK
Jak zbudować i wgrać obraz na płytkę STM32MP257F-DK przy użyciu Buildroot oraz analiza struktury wygenerowanego obrazu
Płytka STM32MP257F-DK jest dostarczana z preinstalowanym systemem OpenSTLinux opartym na Yocto. Ale co, jeśli chcemy zbudować własny, lżejszy obraz? Odpowiedź: Buildroot — narzędzie do budowania kompletnych systemów Linux dla urządzeń wbudowanych.
W tym artykule pokażę, jak zbudować i wgrać obraz na płytkę STM32MP257F-DK, używając Buildroota z zewnętrznym drzewem od Bootlina.
Czym jest Buildroot?
Buildroot to zestaw skryptów Makefile i Kconfig, który automatyzuje proces budowania kompletnego systemu Linux. W porównaniu do Yocto jest prostszy w użyciu i szybszy w kompilacji, choć oferuje mniej możliwości konfiguracji.
Firma Bootlin udostępnia zewnętrzne drzewo (buildroot-external-st) z gotowymi konfiguracjami dla płytek STMicroelectronics, w tym dla serii STM32MP2.
Przygotowanie środowiska
Do kompilacji możemy wykorzystać kontener Docker, co pozwoli uniknąć ręcznej konfiguracji zależności na hoście. Poniższe repozytorium zawiera gotowe pliki Dockera, dzięki którym można szybko rozpocząć pracę:
Klonowanie repozytoriów
Zaczynamy od pobrania Buildroota i zewnętrznego drzewa od Bootlina:
git clone -b st/2025.02.5 https://github.com/bootlin/buildroot.git
git clone -b st/2025.02.5 https://github.com/bootlin/buildroot-external-st.git
W chwili pisania tego artykułu najnowsza dostępna gałąź to st/2025.02.5.
Konfiguracja i budowanie
Wchodzimy do katalogu Buildroot i wybieramy konfigurację dla naszej płytki:
cd buildroot
make BR2_EXTERNAL=../buildroot-external-st st_stm32mp257f_dk_defconfig
Następnie uruchamiamy kompilację:
make -j $(nproc)
Proces może zająć od kilkunastu minut do godziny, w zależności od wydajności komputera i połączenia internetowego (pobierane są źródła).
Wynik kompilacji
Po zakończeniu budowania gotowy obraz znajdziemy pod ścieżką output/images/sdcard.img.gz. Jest to skompresowany obraz karty SD zawierający wszystkie niezbędne komponenty do uruchomienia systemu.
Wgrywanie obrazu na kartę SD
Podłączamy kartę microSD do komputera i sprawdzamy nazwę urządzenia:
sudo lsblk
Zakładając, że karta jest widoczna jako /dev/sdx, wgrywamy obraz:
cd output/images
gzip -dc sdcard.img.gz | sudo dd of=/dev/sdx bs=1M status=progress
sync
Uwaga: Upewnij się, że wskazujesz właściwe urządzenie! Komenda dd nadpisze wszystkie dane.
Uruchomienie płytki
- Włóż kartę SD do gniazda na płytce
- Ustaw przełączniki rozruchowe na tryb SD:
1-0-0-0 - Podłącz kabel USB-C do portu PWR
- Połącz się przez port szeregowy:
picocom -b 115200 /dev/ttyACMx
-> Dokładny opis, jak uruchomić płytkę, znajdziemy tutaj
Po uruchomieniu zaloguj się jako root (bez hasła).
Co dalej?
Moim kolejnym celem będzie uruchomienie systemu na płytce bez użycia systemów budowania takich jak Yocto czy Buildroot. System OpenSTLinux budowany za pomocą Yocto jest bardzo rozbudowany, co widać choćby po liczbie potrzebnych partycji na karcie SD (Flashlayout). Obraz zbudowany za pomocą Buildroota jest natomiast minimalny, co znacznie ułatwi analizę wsteczną (reverse engineering) procesu uruchamiania. Skoro zweryfikowaliśmy już prawidłowe działanie obrazu, możemy przyjrzeć się jego strukturze.
Analiza struktury obrazu
Włóżmy kartę SD z powrotem do komputera i zobaczmy, jaką strukturę ma wygenerowany obraz. Na początek sprawdźmy rozpoznane partycje za pomocą blkid:
sudo blkid /dev/sdb*
/dev/sdb: PTUUID="42104540-b803-4e34-aad8-e499bc40110f" PTTYPE="gpt"
/dev/sdb1: PARTLABEL="fsbla" PARTUUID="b49f6b5a-f5d8-4d6d-aa50-11611113578d"
/dev/sdb2: PARTLABEL="fip" PARTUUID="6c692391-fb50-4c2e-b757-e07287342d44"
/dev/sdb3: PARTLABEL="u-boot-env" PARTUUID="61d25e7c-4ba2-40c3-8301-3a0f90d2604a"
/dev/sdb4: LABEL="rootfs" UUID="2f3910e7-d70f-4ada-9742-f35e3e006568" BLOCK_SIZE="1024" TYPE="ext4" PARTLABEL="rootfs" PARTUUID="b26967be-18fb-40fe-9d9b-ae035fc4a1c5"
Mamy zaledwie cztery partycje — znacznie mniej niż w przypadku obrazu Yocto. Karta korzysta z tablicy partycji GPT i zawiera:
fsbla— pierwszy etap bootloadera (TF-A BL2)fip— pakiet firmware’u (FIP) z kolejnymi etapami uruchamianiau-boot-env— zmienne środowiskowe U-Bootarootfs— główny system plików (ext4)
Za pomocą sgdisk możemy wyświetlić szczegółowe cechy zawartych partycji.
sudo sgdisk -p /dev/sdb
Disk /dev/sdb: 31116288 sectors, 14.8 GiB
Model: MassStorageClass
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 42104540-B803-4E34-AAD8-E499BC40110F
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 213574
Partitions will be aligned on 2-sector boundaries
Total free space is 5 sectors (2.5 KiB)
Number Start (sector) End (sector) Size Code Name
1 34 545 256.0 KiB 8300 fsbla
2 546 8737 4.0 MiB 8300 fip
3 8738 8769 16.0 KiB 8300 u-boot-env
4 8770 213569 100.0 MiB 8300 rootfs
Przyjrzyjmy się teraz zawartości poszczególnych partycji, zaczynając od fsbla:
Partycja fsbla — pierwszy etap bootloadera
sudo hexdump -C /dev/sdb1 | head -20
00000000 53 54 4d 32 00 00 00 00 00 00 00 00 00 00 00 00 |STM2............|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Pierwsze cztery bajty to tzw. magic number: 0x324D5453 (ASCII: „STM2”). Jest to sygnatura nagłówka STM32, po której kod ROM rozpoznaje prawidłowy obraz FSBLA (First Stage Boot Loader Authenticate), czyli w przypadku STM32MP2 — TF-A BL2.
Kod ROM umieszczony w procesorze oczekuje tablicy GPT, w której pierwsza partycja nosi nazwę fsbla (Boot from SD card).
Partycja fip — pakiet firmware’u
sudo hexdump -C /dev/sdb2 | head -20
00000000 01 00 64 aa 78 56 34 12 00 00 00 00 00 00 00 00 |..d.xV4.........|
00000010 47 d4 08 6d 4c fe 98 46 9b 95 29 50 cb bd 5a 00 |G..mL..F..)P..Z.|
Pierwsze cztery bajty to magic number formatu FIP (Firmware Image Package): 0xAA640001. FIP to kontener zdefiniowany przez projekt TF-A (Trusted Firmware-A), który pakuje w jeden plik wiele komponentów firmware’u — m.in. BL31, BL32 (OP-TEE), BL33 (U-Boot) oraz pliki Device Tree.
Partycja u-boot-env — zmienne środowiskowe
Trzecia partycja przechowuje zmienne środowiskowe U-Boota. Zrzućmy jej zawartość do pliku, aby móc ją zbadać:
sudo dd if=/dev/sdb3 of=uboot-env.bin bs=16K count=1
1+0 records in
1+0 records out
16384 bytes (16 kB, 16 KiB) copied, 0.00305791 s, 5.4 MB/s
hexdump -C uboot-env.bin | head -20
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002000 55 6d 6e c1 01 61 70 69 5f 61 64 64 72 65 73 73 |Umn..api_address|
00002010 3d 66 38 30 37 36 34 33 30 00 61 72 63 68 3d 61 |=f8076430.arch=a|
00002020 72 6d 00 61 75 74 6f 6c 6f 61 64 3d 30 00 62 61 |rm.autoload=0.ba|
00002030 75 64 72 61 74 65 3d 31 31 35 32 30 30 00 62 6f |udrate=115200.bo|
00002040 61 72 64 3d 73 74 6d 33 32 6d 70 32 00 62 6f 61 |ard=stm32mp2.boa|
Partycja u-boot-env ma prostą strukturę: pierwsze 4 bajty to suma kontrolna CRC32 danych, a po nich następują zmienne środowiskowe zapisane jako ciągi klucz=wartość, oddzielone bajtem zerowym (\0). Poniższa komenda pomija nagłówek CRC i wyodrębnia zmienne w czytelnej formie:
dd if=uboot-env.bin bs=1 skip=4 2>/dev/null | tr '\0' '\n' | grep -v '^$'
arch=arm
autoload=0
baudrate=115200
board=stm32mp2
board_name=stm32mp257f-dk
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_device=mmc
...
To już nauczyliśmy się sporo o płytce i będziemy w stanie dalej kombinować :).
Podsumowanie
Buildroot oferuje szybszy i prostszy sposób na zbudowanie własnego obrazu Linux dla STM32MP257F-DK w porównaniu do Yocto. Jest idealny do prototypowania i sytuacji, gdy potrzebujemy lekkiego, zoptymalizowanego systemu. Jak pokazała analiza, wygenerowany obraz ma przejrzystą strukturę — zaledwie cztery partycje, z których każda pełni ściśle określoną rolę w procesie uruchamiania.
Powiązane wpisy
STM32MP257F-DK: Unboxing
Płyta deweloperska STM32MP257F-DK firmy ST - hit czy hit ;)
Embedded Linux od podstaw — szybko i łatwo z QEMU
Skompiluj system Linux i jego narzędzia budowania od zera
TFTP i NFS w rozwoju Embedded Linux
Wykorzystaj TFTP i NFS, by przyspieszyć uruchamianie Embedded Linux
Komentarze