Uruchamiamy GNU/Linux na płycie ARM od podstaw (na przykładzie Kali i iMX.6)

tl;dr: tworzę obraz Kali Linux dla komputera ARM w programie debootstrap, linux i u-boot.

Uruchamiamy GNU/Linux na płycie ARM od podstaw (na przykładzie Kali i iMX.6)

Jeśli kupiłeś jakiś mniej popularny komputer jednopłytkowy, mogłeś napotkać na brak obrazu ulubionego dystrybucji. Podobna sytuacja miała miejsce z planowanym Flipper One. Kali Linux dla IMX6 po prostu nie ma (przygotowuję), więc muszę go zbudować samodzielnie.

Proces uruchamiania jest dość prosty:

  1. Inicjalizuje się sprzęt.
  2. Z pewnego obszaru pamięci urządzenia (karta SD/eMMC/etc) odczytywany i wykonywany jest bootloader.
  3. Bootloader znajduje jądro systemu operacyjnego i ładuje je do pewnego obszaru pamięci i wykonuje.
  4. Jądro ładuje resztę systemu operacyjnego.

Do moich celów wystarczy taki poziom szczegółowości, więcej możesz przeczytać w innym artykule. Wspomniane wcześniej „pewne” obszary różnią się między płytami, co stwarza pewne trudności przy instalacji. Ładowanie serwerowych platform ARM próbuje się standaryzować dzięki UEFI, ale na razie nie jest to dostępne dla wszystkich, więc będziesz musiał zbierać wszystko osobno.

Budowanie systemu plików root

Na początku należy przygotować partycje. U-Boot obsługuje różne systemy plików, wybrałem FAT32 dla /boot i ext3 dla korzenia, to standardowy podział obrazów dla Kali pod ARM. Skorzystam z GNU Parted, ale można to zrobić w bardziej znany sposób za pomocą fdisk. Potrzebne będą również dosfstools i e2fsprogs do tworzenia systemów plików: apt install parted dosfstools e2fsprogs.

Partycjonujemy kartę SD:

  1. Oznaczamy kartę SD jako używającą partycjonowania MBR: parted -s /dev/mmcblk0 mklabel msdos
  2. Tworzymy partycję pod /boot o rozmiarze 128 megabajtów: parted -s /dev/mmcblk0 mkpart primary fat32 1MiB 128MiB. Pierwszy pominięty megabajt musi być zostawiony na samą strukturę podziału i bootloader.
  3. Tworzymy system plików root na pozostałą pojemność: parted -s /dev/mmcblk0 mkpart primary ext4 128MiB 100%
  4. Jeśli przypadkiem nie utworzyły się lub nie zmieniły pliki partycji, należy wykonać `partprobe`, wtedy tabela partycji będzie przeczytana na nowo.
  5. Tworzymy system plików partycji rozruchowej z etykietą BOOT: mkfs.vfat -n BOOT -F 32 -v /dev/mmcblk0p1
  6. Tworzymy system plików root z etykietą ROOTFS: mkfs.ext3 -L ROOTFS /dev/mmcblk0p2

Świetnie, teraz można go wypełniać. Dodatkowo będzie potrzebna debootstrap, narzędzie do tworzenia systemów plików dla systemów operacyjnych opartych na Debianie: apt install debootstrap.

Tworzymy system plików:

  1. Montujemy partycję w /mnt/ (użyj wygodniejszego dla siebie punktu montowania): mount /dev/mmcblk0p2 /mnt
  2. Wypełniamy system plików: debootstrap --foreign --include=qemu-user-static --arch armhf kali-rolling /mnt/ http://http.kali.org/kali. Parametr --include określa dodatkowe pakiety do zainstalowania, wskazałem statycznie skompilowany emulator QEMU. Umożliwia on wykonywanie chroot w środowisku ARM. Znaczenie pozostałych opcji można zobaczyć w man debootstrap. Nie zapomnij, że nie każda płyta ARM obsługuje architekturę armhf.
  3. Z powodu różnic w architekturze debootstrap wykonywane jest w dwóch etapach, drugi wykonuje się tak: chroot /mnt/ /debootstrap/debootstrap --second-stage
  4. Teraz musimy przejść do chroot: chroot /mnt /bin/bash
  5. Wypełniamy /etc/hosts i /etc/hostname docelowy FS. Wypełnij analogicznie do zawartości na swoim lokalnym komputerze, nie zapomnij tylko zmienić nazwę hosta.
  6. Można skonfigurować resztę. Szczególnie instaluję locales (klucze repozytoriów), przestawiam lokalizacje i strefę czasową (dpkg-reconfigure locales tzdata). Nie zapomnij ustawić hasła komendą passwd.
  7. Ustawiamy hasło dla root poleceniem passwd.
  8. Przygotowanie obrazu kończy się na wypełnieniu /etc/fstab wciąż /mnt/.

Będę ładować zgodnie z wcześniej utworzonymi etykietami, dlatego zawartość będzie następująca:

LABEL=ROOTFS / auto errors=remount-ro 0 1
LABEL=BOOT /boot auto defaults 0 0

Na koniec, można zamontować partycję rozruchową, będzie nam potrzebna dla jądra: `mount /dev/mmcblk0p1 /mnt/boot/`

Budowanie Linuxa

Aby zbudować jądro (a potem boot loader) na Debian Testing, należy zainstalować standardowy zestaw GCC, GNU Make oraz nagłówki GNU C Library dla docelowej architektury (u mnie armhf), a także nagłówki OpenSSL, kalkulator konsolowy bc, bison i flex: apt install crossbuild-essential-armhf bison flex libssl-dev bc. Ponieważ boot loader domyślnie szuka pliku zImage na systemie plików partycji rozruchowej, czas podzielić pendrive'a.

  1. Klonowanie jądra zajmuje za długo, dlatego po prostu je pobiorę: wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.9.1.tar.xz. Rozpakujemy i przejdźmy do katalogu ze źródłami: tar -xf linux-5.9.1.tar.xz && cd linux-5.9.1
  2. Konfigurujemy przed kompilacją: make ARCH=arm KBUILD_DEFCONFIG=imx_v6_v7_defconfig defconfig. Konfiguracja znajduje się w katalogu arch/arm/configs/. Jeśli go nie ma, można spróbować znaleźć i pobrać gotowy i podać nazwę pliku w tym katalogu jako parametr KBUILD_DEFCONFIG. W ostateczności od razu przejdź do następnego punktu.
  3. Opcjonalnie można dopracować ustawienia: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
  4. I cross-kompilujemy obraz: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
  5. Teraz można skopiować plik z jądrem: cp arch/arm/boot/zImage /mnt/boot/
  6. I pliki z DeviceTree (opis dostępnego sprzętu na płycie): cp arch/arm/boot/dts/*.dtb /mnt/boot/
  7. I zainstalować zbudowane moduły jako osobne pliki: make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- INSTALL_MOD_PATH=/mnt/ modules_install

Jądro jest gotowe. Można wszystko odmontować: umount /mnt/boot/ /mnt/

Das U-Boot

Ponieważ bootloader jest interaktywny, do sprawdzenia jego działania wystarczy sama płyta, urządzenie pamięci i opcjonalnie urządzenie USB-to-UART. Można pozostawić jądro i OS na później.

Absolutna większość producentów oferuje użycie Das U-Boot do początkowego uruchamiania. Pełne wsparcie zazwyczaj zapewniane jest w własnym forku, ale nie zapominają też o kontribucjach do upstream. W moim przypadku płyta jest wspierana w mainstreamie, więc forka zignorowałem.

Budujemy sam bootloader:

  1. Klonujemy stabilną gałąź repozytorium: git clone https://gitlab.denx.de/u-boot/u-boot.git -b v2020.10
  2. Przechodzimy do samego katalogu: cd u-boot
  3. Przygotowujemy konfigurację budowy: make mx6ull_14x14_evk_defconfig. Działa to tylko, jeśli konfiguracja istnieje w samym Das U-Boot, w przeciwnym razie musisz znaleźć konfigurację producenta i umieścić ją w głównym katalogu repozytorium w pliku .config, lub zbudować w inny sposób zalecany przez producenta.
  4. Budujemy sam obraz bootloadera za pomocą cross-kompilatora armhf: make CROSS_COMPILE=arm-linux-gnueabihf- u-boot.imx

W rezultacie otrzymujemy plik u-boot.imx, to gotowy obraz, który można zapisać na pendrive. Zapisujemy na karcie SD, pomijając pierwsze 1024 bajty. Dlaczego wybrałem target u-boot.imx? Почему пропустил именно 1024 байта? Так предлагают сделать в dokumentacji. Dla innych płyt proces budowy obrazu i zapisu może nieco się różnić.

Gotowe, można uruchomić. Bootloader powinien zgłosić swoją wersję, pewne informacje o płycie i spróbować znaleźć obraz jądra na partycji. W przypadku niepowodzenia spróbuje uruchomić się przez sieć. Ogólnie wyjście jest dość szczegółowe, można znaleźć błąd w przypadku problemu.

Zamiast zakończenia

A wiedziałeś, że czoło delfina nie jest kostne? To dosłownie trzecie oko, tłuszczowa soczewka do echolokacji!

Uruchamiamy GNU/Linux na płycie ARM od podstaw (na przykładzie Kali i iMX.6)

Uruchamiamy GNU/Linux na płycie ARM od podstaw (na przykładzie Kali i iMX.6)

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster