Ubuntu kép létrehozása ARM-hoz "from scratch"

Amikor a fejlesztés csak kezdődik, gyakran még nem világos, hogy pontosan mely csomagok fognak a cél rootfs-be kerülni.

Más szavakkal, korai még az LFS, buildroot vagy yocto (vagy valami más) használata, de már el kellene kezdeni. A gazdagok számára (nekem a prototípusaim 4GB eMMC-vel rendelkeznek) van lehetőség disztribúciót biztosítani a fejlesztőknek, amely lehetővé teszi, hogy gyorsan hozzáférjenek valamihez, amire éppen szükség van, majd mindig összeállíthatjuk a csomagok listáját, és létrehozhatunk egy listát a cél rootfs számára.

Ez a cikk nem tartalmaz újdonságokat, és egyszerű copy-paste útmutatót ad.

A cikk célja az Ubuntu rootfs összeszerelése ARM alapú deszkához (az én esetemben Colibri imx7d alapú).

A kép építése

Cél rootfs összeszerelése mintához.

Ubuntu Base kicsomagolása

A kiadást magunk választjuk az igények és a saját preferenciák alapján. Itt 20-at hoztam fel.

$ mkdir ubuntu20
$ cd ubuntu20
$ mkdir rootfs
$ wget http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04-base-armhf.tar.gz
$ tar xf ubuntu-base-20.04-base-armhf.tar.gz -C rootfs

A BINFMT támogatás ellenőrzése a kernelben

Ha elterjedt disztribúciót használ, akkor a BINFMT_MISC támogatva van, és minden be van állítva, ha nem — biztos vagyok benne, hogy tudja, hogyan kell aktiválni a BINFMT támogatását a kernelben.

Győződjön meg róla, hogy a BINFMT_MISC be van kapcsolva a kernelben:

$ zcat /proc/config.gz | grep BINFMT
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_BINFMT_MISC=y

Most ellenőrizni kell a beállításokat:

$ ls /proc/sys/fs/binfmt_misc
qemu-arm register status
$ cat /proc/sys/fs/binfmt_misc/qemu-arm
enabled
interpreter /usr/bin/qemu-arm
flags: OC
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

Kézzel is regisztrálható például ezzel az utasítással ezen az útmutatón.

qemu statikus arm beállítása

Most szükségünk lesz egy statikusan összeszerelt qemu példányra.

!!! FIGYELEM!!!
Ha konténert tervez használni valaminek az összeszereléséhez, nézze meg:
https://sourceware.org/bugzilla/show_bug.cgi?id=23960
https://bugs.launchpad.net/qemu/+bug/1805913
Akkor x86_64 host és arm guest esetén az i386 verziót kell használni:
http://ftp.ru.debian.org/debian/pool/main/q/qemu/qemu-user-static_5.0-13_i386.deb

$ wget http://ftp.debian.org/debian/pool/main/q/qemu/qemu-user-static_5.0-13_amd64.deb
$ alien -t qemu-user-static_5.0-13_amd64.deb
# az útvonal a rootfs-ben és a végrehajtható fájl neve meg kell egyezzen a /proc/sys/fs/binfmt_misc/qemu-arm
$ mkdir qemu
$ tar xf qemu-user-static-5.0.tgz -C qemu
$ file qemu/usr/bin/qemu-arm-static
qemu/usr/bin/qemu-arm-static: ELF 64-bit LSB végrehajtható, x86-64, verzió 1 (GNU/Linux), statikusan linkelve, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, GNU/Linux 3.2.0 számára, csupaszítva
$ cp qemu/usr/bin/qemu-arm-static rootfs/usr/bin/qemu-arm
$ file rootfs/usr/bin/qemu-arm
rootfs/usr/bin/qemu-arm: ELF 64-bit LSB végrehajtható, x86-64, verzió 1 (GNU/Linux), statikusan linkelve, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, GNU/Linux 3.2.0 számára, csupaszítva

Chroot

Egyszerű script:

ch-mount.sh

#!/bin/bash

function mnt() {
    echo "MOUNTING"
    sudo mount -t proc /proc ${2}proc
    sudo mount --rbind /sys ${2}sys
    sudo mount --make-rslave ${2}sys
    sudo mount --rbind /dev ${2}dev
    sudo mount --make-rslave ${2}dev
    sudo mount -o bind /dev/pts ${2}dev/pts
    sudo chroot ${2}
}

function umnt() {
    echo "UNMOUNTING"
    sudo umount ${2}proc
    sudo umount ${2}sys
    sudo umount ${2}dev/pts
    sudo umount ${2}dev

}

if [ "$1" == "-m" ] && [ -n "$2" ] ;
then
    mnt $1 $2
elif [ "$1" == "-u" ] && [ -n "$2" ];
then
    umnt $1 $2
else
    echo ""
    echo "Either 1'st, 2'nd or both parameters were missing"
    echo ""
    echo "1'st parameter can be one of these: -m(mount) OR -u(umount)"
    echo "2'nd parameter is the full path of rootfs directory(with trailing '/')"
    echo ""
    echo "For example: ch-mount -m /media/sdcard/"
    echo ""
    echo 1st parameter : ${1}
    echo 2nd parameter : ${2}
fi

Gyönyörködjünk az elért eredményben:

$ .\/ch-mount.sh -m rootfs\/\n# cat \/etc\/os-release\nNAME="Ubuntu"\nVERSION="20.04 LTS (Focal Fossa)"\nID=ubuntu\nID_LIKE=debian\nPRETTY_NAME="Ubuntu 20.04 LTS"\nVERSION_ID="20.04"\nHOME_URL="https:\/\/www.ubuntu.com\/"\nSUPPORT_URL="https:\/\/help.ubuntu.com\/"\nBUG_REPORT_URL="https:\/\/bugs.launchpad.net\/ubuntu\/"\nPRIVACY_POLICY_URL="https:\/\/www.ubuntu.com\/legal\/terms-and-policies\/privacy-policy"\nVERSION_CODENAME=focal\nUBUNTU_CODENAME=focal\n# uname -a\nLinux NShubin 5.5.9-gentoo-x86_64 #1 SMP PREEMPT Mon Mar 16 14:34:52 MSK 2020 armv7l armv7l armv7l GNU\/Linux

Csak kíváncsiságból mérjük meg a méretet a minimális (számomra) csomagok telepítése előtt és után:

# du -d 0 -h / 2>/dev/null
63M     /

Frissítsük:

# apt update
# apt upgrade --yes

Telepítsük az érdeklődésünkre számot tartó csomagokat:

# SYSTEMD_IGNORE_CHROOT=yes apt install --yes autoconf kmod socat ifupdown ethtool iputils-ping net-tools ssh g++ iproute2 dhcpcd5 incron ser2net udev systemd gcc minicom vim cmake make mtd-utils util-linux git strace gdb libiio-dev iiod

A kernel fejlécfájlok és modulok külön téma. A bootloader, a kernel, a modulok és az eszközfájlok telepítése Ubuntu rendszerre nem lehetséges, ezeket külső forrásból szerezzük be, vagy magunk készítjük el, vagy a gyártó biztosítja — minden esetben ez már túlmutat ezen az útmutatón.

Bizonyos mértékig megengedett a verziók eltérése, de a legjobb, ha a kernel összeállításából származnak.

# apt install --yes linux-headers-generic

Nézzük meg, mi lett az eredmény, és nem épp kevés:

# apt clean
# du -d 0 -h / 2>/dev/null
770M    /

Ne felejtsd el beállítani a jelszót.

Csomagoljuk be a képet

$ sudo tar -C rootfs --transform "s|^.\/||" --numeric-owner --owner=0 --group=0 -c .\/ | tar --delete .\/ | gzip > rootfs.tar.gz

További lehetőségként telepíthetjük az etckeeper-t automatikus push beállítással

Tegyük fel, hogy kiadtuk a saját összeállításunkat, a munka elindult — hogyan gyűjthetjük össze később a rendszer különböző verzióit.

Az etckeeper lehet a segítségünkre.

A biztonság mindenki személyes ügye:

  • védhetsz meg bizonyos ágakat
  • generálhatsz egyedi kulcsot minden eszközhöz
  • megteheted, hogy letiltod a force push-ot
  • és így tovább...
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...

Állítsuk be az autopush-t

Természetesen előre létrehozhatunk ágakat az eszközön (például készíthetünk egy scriptet vagy szolgáltatást, ami az első indításkor fut).

# cat /etc/etckeeper/etckeeper.conf
PUSH_REMOTE="origin"

De tehetjük okosabban is...

A lusta megoldás

Legyen egyedi azonosítónk, mondjuk a processzor sorozatszáma (vagy MAC — a komoly cégek megvásárolják a tartományt):

cat \/proc\/cpuinfo

# cat /proc/cpuinfo
processor       : 0
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 60.36
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

processor       : 1
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 60.36
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : Freescale i.MX7 Dual (Device Tree)
Revision        : 0000
Serial          : 06372509

Akkor felhasználhatjuk ezt az ágnévhez, ahova fogunk push-olni:

# cat /proc/cpuinfo | grep Serial | cut -d':' -f 2 | tr -d [:blank:]
06372509

Hozzunk létre egy egyszerű scriptet:

# cat /etc/etckeeper/commit.d/40myown-push
#!/bin/sh
set -e

if [ "$VCS" = git ] && [ -d .git ]; then
  branch=$(cat /proc/cpuinfo | grep Serial | cut -d':' -f 2 | tr -d [:blank:])
  cd /etc/
  git push origin master:${branch}
fi

És ennyi — egy kis idő elteltével megnézhetjük a változásokat és összeállíthatjuk a célzott firmware-hez szükséges csomagok listáját.

Ajánlott anyagok

BINFMT_MISC
Kernel támogatás különféle bináris formátumokhoz (binfmt_misc)
Fordítás qemu felhasználói chroot segítségével
Ubuntu rootfs építése ARM számára
Hogyan készítsünk egy egyedi Ubuntu live-ot a semmiből
Crossdev qemu-static-user-chroot
etckeeper

getdents64 probléma

readdir() NULL-t ad vissza (errno=EOVERFLOW) 32-bites user-static qemu esetén 64-bites hoszton
Ext4 64 bit hash megszakítja a 32 bites glibc 2.28+ működését
compiler_id_detection nem működik megfelelően armhf esetén, ha QEMU felhasználói üzemmódot használunk
A CMake nem működik megfelelően a qemu-arm alatt

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster