Opprette et Ubuntu-bilde for ARM "fra bunnen av"

Når utviklingen nettopp begynner, er det ofte ikke klart hvilke pakker som vil gå til målrotfsene.

Med andre ord, det er for tidlig å ta tak i LFS, buildroot eller yocto (eller noe annet), men du må allerede begynne. For de rike (jeg har 4GB eMMC på pilotprøver) er det en utvei for å distribuere til utviklere en distribusjon som gjør at de raskt kan levere noe som mangler, og da kan vi alltid samle lister over pakker og lage en liste for målrotene.

Denne artikkelen er ikke ny og er en enkel copy-paste-instruksjon.

Formålet med artikkelen er å bygge Ubuntu rootfs for ARM-kort (i mitt tilfelle, basert på Colibri imx7d).

Bygg bildet

Vi setter sammen målrootfs for replikering.

Pakker ut Ubuntu Base

Vi velger utgivelsen selv ut fra behov og egne preferanser. Her har jeg gitt 20.

$ 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

Sjekker BINFMT-støtte i kjernen

Hvis du har en felles distribusjon, så er det støtte for BINFMT_MISC og alt er konfigurert, hvis ikke, så er jeg sikker på at du vet hvordan du aktiverer BINFMT-støtte i kjernen.

Sørg for at BINFMT_MISC er aktivert i kjernen:

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

Nå må du sjekke innstillingene:

$ 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

Du kan registrere deg manuelt ved å bruke f.eks. her er disse instruksjonene.

Sette opp qemu statisk arm

Nå trenger vi en statisk sammensatt qemu-forekomst.

!!! MERK FØLGENDE!!!
Hvis du planlegger å bruke en container til å bygge noe, sjekk ut:
https://sourceware.org/bugzilla/show_bug.cgi?id=23960
https://bugs.launchpad.net/qemu/+bug/1805913
Så for x86_64 vert og arm gjest må du bruke i386-versjonen av qemu:
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
$ alient -t qemu-user-static_5.0-13_amd64.deb
# путь в rootfs и имя исполняемого файла должно совпадать с /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 executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, for GNU/Linux 3.2.0, stripped
$ 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 executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, for GNU/Linux 3.2.0, stripped

chroot

Enkelt skript:

ch-mount.sh

#!/bin/bash

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

function umnt() {
    echo "UNMOUNTING"
    sudo umount proc
    sudo umount sys
    sudo umount dev/pts
    sudo umount 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 : 
    echo 2nd parameter : 
fi

Vi beundrer resultatet:

$ ./ch-mount.sh -m rootfs/
# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
# uname -a
Linux NShubin 5.5.9-gentoo-x86_64 #1 SMP PREEMPT Mon Mar 16 14:34:52 MSK 2020 armv7l armv7l armv7l GNU/Linux

Bare for moro skyld, la oss måle størrelsen før og etter installasjon av minimum (for meg) sett med pakker:

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

La oss oppdatere:

# apt update
# apt upgrade --yes

La oss installere pakkene vi er interessert i:

# 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

Kjernehodefiler og moduler er en egen sak. Selvfølgelig vil vi ikke installere bootloader, kjerne, moduler, enhetstreet via Ubuntu. De vil komme til oss utenfra, eller vi vil montere dem selv eller de vil bli gitt til oss av brettprodusenten, i alle fall er dette utenfor rammen av denne instruksjonen.

Til en viss grad er versjonsdivergens akseptabelt, men det er bedre å ta dem fra kjernebygget.

# apt install --yes linux-headers-generic

La oss se hva som skjedde og det viste seg mye:

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

Ikke glem å angi et passord.

Pakker bildet

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

I tillegg kan vi installere etckeeper med autopush-innstillingen

Vel, la oss si at vi distribuerte sammenstillingen vår, arbeidet begynte med hvordan vi best kunne sette sammen senere forskjellige versjoner av systemet vårt.

etckeeper kan hjelpe oss.

Sikkerhet er en personlig sak:

  • du kan beskytte visse grener
  • generere en unik nøkkel for hver enhet
  • deaktiver krafttrykk
  • etc. ...
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...

La oss sette opp autopush

Vi kan selvfølgelig lage grener på enheten på forhånd (la oss si at vi lager et skript eller en tjeneste som kjører første gang den lanseres).

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

Eller vi kan gjøre noe smartere...

lat måte

La oss ha en slags unik identifikator, si serienummeret til prosessoren (eller MAC - seriøse selskaper kjøper serien):

katt / 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

Så kan vi bruke det for navnet på grenen som vi vil skyve til:

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

La oss lage et enkelt skript:

# 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

Og det er alt - etter en stund kan vi se på endringene og lage en liste over pakker for målfastvaren.

Anbefalte materialer

BINFMT_MISC
Kjernestøtte for diverse binære formater (binfmt_misc)
Kompilere med qemu bruker chroot
Bygge Ubuntu rootfs for ARM
Hvordan lage en tilpasset Ubuntu live fra bunnen av
Crossdev qemu-static-user-chroot
etckeeper

getdents64-problem

readdir() returnerer NULL (errno=EOVERFLOW) for 32-bits brukerstatisk qemu på 64-bits vert
Ext4 64 bit hash bryter 32 bit glibc 2.28+
compiler_id_detection mislykkes for armhf ved bruk av QEMU brukermodusemulering
CMake fungerer ikke ordentlig under qemu-arm

Kilde: www.habr.com