Jak przygotować własny obraz systemu

Forum poświęcone układom SBC (Single Board Komputer) opartych o SoC Amlogic
Regulamin forum
Obrazek

Amlogic Khadas VIM1 BASIC
SoC: Amlogic S905 Quad Core ARM Cortex-A53 Mali-T450MP5 GPU UHD H.265/VP9 60fps HDR10 oraz HLG HDR

Obrazek

Amlogic Khadas VIM2 PRO
SoC: Amlogic S912 Octa Core ARM Cortex-A53 Mali-T820MP3 GPU HW UHD H.265/VP9 60fps HDR10 oraz HLG HDR
ODPOWIEDZ
elvis
Użytkownik
Posty: 57
Rejestracja: 30 lis 2018, 17:50

Jak przygotować własny obraz systemu

Post autor: elvis » 19 cze 2019, 15:09

W internecie znajdziemy całkiem sporo gotowych systemów dla płytek Khadas VIM i VIM2. Można po prostu pobrać taki obraz i nagrać, ale używanie "pełnego" systemu operacyjnego na SBC ma tyle samo wad co zalet. Po pierwsze taki system jest duży i powolny. Typowe dystrybucje jak Ubuntu, czy Debian/Armbian są przeznaczone raczej dla pełnosprawnych komputerów PC, zawierają mnóstwo pakietów, które mocno spowalniają pracę systemu. Dodatkowo są one kompilowane w sposób możliwie ogólny - tak aby działały na różnych konfiguracjach sprzętowych. Kompilując własny obraz, możemy wybrać tylko to co jest nam niezbędne, co więcej wszystkie programy mogą być skompilowane w sposób optymalny dla naszej płytki.
Przy okazji dostajemy również toolchain, czyli kompilator, biblioteki i wszystkie niezbędne narzędzia, za pomocą których możemy pisać programy na PC, a tylko uruchamiać na SBC. To o wiele wydajniejsze rozwiązanie niż uruchamianie gcc na docelowej płytce. Jako przykład może posłużyć kompilacja samego linuxa - na SBC trwa kilkadziesiat minut, czasem i godzinę. Na PC - około minuty.
Przy okazji możemy też poznać lepiej sam sprzęt i dowiedzieć się jak działa.

Co potrzebujemy


Do uruchomienia systemu potrzebujemy:
  • system plików - a na nim programy, które będziemy uruchamiać
Żeby to wszystko skompilować potrzebny jest jeszcze toolchain, czyli kompilator i inne pomocnicze programy jak linker, asembler oraz biblioteki.

Można to wszystko przygotować od zera, ale to dość ciężka praca. Na szczęście są do tego gotowe skrypty:
  • Buildroot - szybki i sympatyczny system budowania obrazów (https://buildroot.org/), niestety nie obsługuje on khadas-a
Skoro buildroot wymaga sztukowania zostało mi użycie Yocto

Yocto

Zanim skompilujemy system musimy pobrać odpowiednie "warstwy". Są to po prostu zestawy pakietów, które można w miarę potrzeby dodawać do naszego obrazu. Co ciekawe takie warstwy są przygotowywane przez różne firmy lub osoby i na ogół ze sobą działają. Czyli możemy mieć warstwę opisującą nasz VIM / VIM2, dodać do niej warstwę ze wsparciem dla Qt5 i już mamy bibliotekę qt dla Khadas-a.
Na początek musimy przygotować sporo miejsca na dysku - kompilacja wymaga 50 do 100 GB. Ja do tego używam zewnętrzenego dysku SSD podłączanego przez USB3.0, polecam działa całkiem sprawnie.
Tworzymy więc katalog np. /mnt/usbssd/khadas/yocto, w nim podkatalog "sources" na kody źródłowe yocto i pobieramy warstwy.
Absolutne minimum to:
  • poky - czyli domyślna dystrybucja yocto
  • meta-openembedded - najbardziej podstawowe programy
  • meta-meson - wsparcie dla płytek Khadas
Do pobrierania warstw dobrze sprawdza się git, więc wykonujemy polecenia:

Kod: Zaznacz cały

git clone -b thud git://git.yoctoproject.org/poky.git
git clone -b thud https://github.com/openembedded/meta-openembedded.git
git clone -b thud https://github.com/superna9999/meta-meson.git
Thud to nazwa "Wersji" naszego yocto - najnowszy jest obecnie Warrior, ale nie działał poprawnie, używałem więc poprzedniej wersji o nazwie "Thud".
Teraz przechodzimy do katalogu /mnt/usbssd/yocto i tworzymy zaczynamy:

Kod: Zaznacz cały

source sources/poky/oe-init-build-env
Po wywołaniu skryptu oe-init-build-env zostanie utworzony podkatalog o domyślnej nazwie "build", w którym będziemy przygotowywać obraz systemu.
Konieczne jest jeszcze skonfigurowanie dwóch plików:
conf/local.conf:

Kod: Zaznacz cały

MACHINE = "khadas-vim"
DISTRO ?= "poky"
PACKAGE_CLASSES ?= "package_ipk"
EXTRA_IMAGE_FEATURES ?= "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS ??= "\
    STOPTASKS,${TMPDIR},1G,100K \
    STOPTASKS,${DL_DIR},1G,100K \
    STOPTASKS,${SSTATE_DIR},1G,100K \
    STOPTASKS,/tmp,100M,100K \
    ABORT,${TMPDIR},100M,1K \
    ABORT,${DL_DIR},100M,1K \
    ABORT,${SSTATE_DIR},100M,1K \
    ABORT,/tmp,10M,1K"
PACKAGECONFIG_append_pn-qemu-system-native = " sdl"
PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
CONF_VERSION = "1"

DL_DIR ?= "${BSPDIR}/downloads"

IMAGE_FSTYPES += "tar.gz"
Pierwsza linijka określa nasz SBC, jeśli chcemy mieć obraz dla VIM2 to zmieniamy na khadas-vim2.
Kolejny plik to conf/bblayers.conf:

Kod: Zaznacz cały

POKY_BBLAYERS_CONF_VERSION = "2"

BBPATH = "${TOPDIR}"
BSPDIR := "${TOPDIR}/.."
BBFILES ?= ""

BBLAYERS ?= " \
  ${BSPDIR}/sources/poky/meta \
  ${BSPDIR}/sources/poky/meta-poky \
  ${BSPDIR}/sources/poky/meta-yocto-bsp \
  \
  ${BSPDIR}/sources/meta-openembedded/meta-oe \
  ${BSPDIR}/sources/meta-openembedded/meta-multimedia \
  \
  ${BSPDIR}/sources/meta-meson \
"
W tym pliku podajemy, które warstwy będą użyte.
Do kompilacji najbardziej podstawowej wersji po prostu piszemy:

Kod: Zaznacz cały

bitbake core-image-minimal
Teraz możemy iść na bezalkoholowe... Kompilacja trwa od 20 min do kilku godzin, w zależności o szybkości komputera i łącza - bo sporo danych będzie pobierane. Wszystkie pakiety są kompilowane ze źródeł - nawet gcc. To trwa i zajmuje miejsce na dysku, ale efekt jest wart poczekania. System jest mały i bardzo szybki.
Później możemy skompilować również nieco bardziej rozbudowane wersje, np. z graficznym interfejsem:

Kod: Zaznacz cały

bitbake core-image-sato
Dodano po 16 minutach 36 sekundach:
Instalacja systemu
Gdy bitbake skończy pracę, obraz systemu znajdziemy w katalogu build/tmp/deploy/images/khadas-vim.
Niestety nie jest to jeden plik, więc musimy się jeszcze trochę pomęczyć.
Na początek warto użyć karty SD, jak coś się nie uda można ją łatwo wymienić i nie trzeba do tego wylutowywać emmc.
To co potrzebujemy to:
  • u-boot.bin.sd.bin - bootloader, czyli uboot
  • Image - jądro linuxa
  • meson-gxl-s905x-khadas-vim.dtb - plik device-tree, czyli konfiguracja naszej płytki
  • extlinux.conf - plik konfiguracyjny z informacją dla uboot-a o wcześniej wspomnianych plikach
  • core-image-minimal-khadas-vim.tar.gz - archiwum ze wszystkimi plikami naszego systemu
Jako ciekawostkę napiszę że core-image-minimal ma raptem 9.8MB... (spakowany) To chyba najlepiej pokazuje jak zoptymalizowany jest nasz system.

Czas przygotować kartę SD
To chyba jeden z najciekawszych i najgorzej opisanych fragmentów. Khadas nie jest zbyt wylewny i niełatwo domyślić się jak taką kartę przygotować.
Na początek najlepiej usunąć jej całą zawartość, następnie musimy nagrać u-boota, co robimy za pomocą odrobiny magii:

Kod: Zaznacz cały

dd if=u-boot.bin.sd.bin of=/dev/sdg conv=fsync bs=1 count=442
dd if=u-boot.bin.sd.bin of=/dev/sdg conv=fsync bs=512 skip=1 seek=1
Zamiast /dev/sdg należy wstawić nazwę odpowiadającą naszej karcie SD oczywiście. Jeśli taką kartę umieścimy w slocie VIM-a, zobaczymy że u-boot już działa:

Kod: Zaznacz cały

GXL:BL1:9ac50e:bb16dc;FEAT:ADFC318C:0;POC:3;RCY:0;EMMC:0;READ:0;CHK:A7;READ:0;CHK:A7;READ:0;CHK:A7;SD:0;READ:0;0.0;CHK:0;
no sdio debug board detected 
TE: 217444

BL2 Built : 14:59:36, Aug  9 2017. 
gxl ge8c6a83 - xiaobo.gu@droid12

set vcck to 1120 mv
set vddee to 1000 mv
Board ID = 6
CPU clk: 1200MHz
DQS-corr enabled
DDR scramble enabled
DDR3 chl: Rank0+1 @ 768MHz - PASS
Rank0: 1024MB(auto)-2T-11
Rank1: 1024MB(auto)-2T-11
DataBus test pass!
AddrBus test pass!
Load fip header from SD, src: 0x0000c200, des: 0x01400000, size: 0x00004000
New fip structure!
Load bl30 from SD, src: 0x00010200, des: 0x01100000, size: 0x0000d600
Load bl31 from SD, src: 0x00020200, des: 0x05100000, size: 0x0002c600
Load bl33 from SD, src: 0x00050200, des: 0x01000000, size: 0x00081000
NOTICE:  BL3-1: v1.0(release):801e730
NOTICE:  BL3-1: Built : 22:09:38, Aug 10 2017
[BL31]: GXL CPU setup!
mpu_config_enable:ok
[Image: gxl_v1.1.3244-a3237e2 2017-08-16 14:01:18 hong.guo@droid04]
OPS=0x84
36 30 c5 dc 60 28 58 6a a5 2a 7 87 [0.588513 Inits done]
secure task start!
high task start!
low task start!
Dalej jest już tylko łatwiej. Potrzebujemy na karcie utworzyć dwie partycje - pierwszą z systemem FAT32 oraz drugą np. ext4 na główny system plików.
Poniżej lista poleceń dla fdisk-a (sudo fdisk /dev/sdg):

Kod: Zaznacz cały

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (1-4, default 1): 
First sector (2048-31116287, default 2048): 32768
Last sector, +sectors or +size{K,M,G,T,P} (32768-31116287, default 31116287): +240M

Created a new partition 1 of type 'Linux' and of size 240 MiB.

Command (m for help): t
Selected partition 1
Partition type (type L to list all types): b
Changed type of partition 'Linux' to 'W95 FAT32'.

Command (m for help): p
Disk /dev/sdg: 14.9 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xffd51936

Device     Boot Start    End Sectors  Size Id Type
/dev/sdg1       32768 524287  491520  240M  b W95 FAT32

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (2-4, default 2): 
First sector (2048-31116287, default 2048): 524288
Last sector, +sectors or +size{K,M,G,T,P} (524288-31116287, default 31116287): 

Created a new partition 2 of type 'Linux' and of size 14.6 GiB.

Command (m for help): p
Disk /dev/sdg: 14.9 GiB, 15931539456 bytes, 31116288 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xffd51936

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sdg1        32768   524287   491520  240M  b W95 FAT32
/dev/sdg2       524288 31116287 30592000 14.6G 83 Linux

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Teraz formatujemy nowo utworzone partycje:

Kod: Zaznacz cały

sudo mkfs.fat -F 32 -n BOOT /dev/sdg1
sudo mkfs.ext4 -L rootfs /dev/sdg2
Na pierwszą wgrywamy pliki: Image oraz meson-gxl-s905x-khadas-vim.dtb. Następnie tworzymy podkatalog extlinux i umieszczamy w nim plik extlinux.conf. Musimy go trochę zmienić:

Kod: Zaznacz cały

# Generic Distro Configuration file generated by OpenEmbedded
LABEL Poky (Yocto Project Reference Distro)
	KERNEL ../Image
	FDT ../meson-gxl-s905x-khadas-vim.dtb
	APPEND root=/dev/mmcblk0p2 rootwait rw console=ttyAML0
Ostatni krok to rozpakowanie systemu plików na drugą partycję, możemy ją nagrać z obrazu albo użyć tar-a:

Kod: Zaznacz cały

sudo tar -axpf core-image-minimal-khadas-vim.tar.gz -C /mnt/ext/
System jest już gotowy, wystarczy umieścić w czytniku i można bawić się własnym systemem na VIM lub VIM2 :)

Inne obrazy systemu
W kolejnych krokach możemy dodawać nowe pakiety, czy własne programy do systemu. Nie będziemy już musieli tyle się męczyć, wystarczy powtarzać ostatni krok, czyli kopiować pliki na partycję /dev/sdg2.
Co więcej zamiast karty SD znacznie przyjemniej będzie używać NFS, czyli umieścić wszystkie pliki na PC i nic już na karcie nie zmieniać.

Dodano po 3 minutach 11 sekundach:
I jeszcze ostatnia uwaga - system plików można przygotować też zupełnie inaczej. Np. używając buildroot-a. Czyli pomieszać własne jądro i uboot-a z innym systemem. Dostępne są gotowce z obrazem Ubuntu, Debiana, a pewnie i innych systemów. W ten sposób możemy zmieniać device-tree i dodawać np. własne urządzenia podłączone do i2c i używać ich z naszym SBC.

Dodano po 1 minucie 49 sekundach:
W taki sam sposób możemy też przygotowywać obrazy dla innych SBC, jak chociażby lubianej przez wszystkich malinki: https://forbot.pl/forum/topic/12078-jak ... e-linux-a/

Awatar użytkownika
l3n1n
Moderator
Posty: 322
Rejestracja: 28 paź 2017, 8:46
Lokalizacja: 3M

Re: Jak przygotować własny obraz systemu

Post autor: l3n1n » 19 cze 2019, 16:22

No i wyszła ci bardzo zgrabna instrukcja step by step. Dzięki za ten wpis. Dobrze że zabrałem dziś z pracy khadasa to się w ten weekend pobawię. O ile starczy mi miejsca na dysku ;)

elvis
Użytkownik
Posty: 57
Rejestracja: 30 lis 2018, 17:50

Re: Jak przygotować własny obraz systemu

Post autor: elvis » 19 cze 2019, 20:16

Właśnie odkryłem, że w sumie niepotrzebnie się tyle namęczyłem wcześniej...
Teoretycznie Yocto powinno generować gotowy obraz systemu, próbowałem taki nagrywać na kartę ale nie działało - dlatego krok-po-kroku odkryłem jak wszystko "ręcznie" skonfigurować.
Jednak pisząc o kompilacji u-boota bez użycia yocto znalazłęm, że taki gotowy obraz powinien jednak działać. Spróbowałem jeszcze raz, czyli:

Kod: Zaznacz cały

sudo dd if=core-image-minimal-khadas-vim.wic of=/dev/sdg bs=4M && sync
I... zadziałało. Więc wszystko co napisałem wcześniej o zakładaniu partycji, nagrywaniu u-boota jest oczywiście prawdą, ale można to samo zrobić o wiele, wiele łatwiej.

Awatar użytkownika
SunRiver
Administrator
Posty: 772
Rejestracja: 08 paź 2017, 11:27
Lokalizacja: Opole
Kontakt:

Re: Jak przygotować własny obraz systemu

Post autor: SunRiver » 19 cze 2019, 20:43

hehe świetny materiał i optymalizacja w locie :)
.... z każdym bitem serca ....
💫SunDUINO
💦GitHUB
💦Google Drive
💦Sotton

ODPOWIEDZ