Skapa en Ubuntu-avbild för ARM "frÄn grunden"

NÀr utvecklingen just har börjat Àr det ofta oklart vilka paket som kommer att ingÄ i den mÄlinriktade rootfs.

Med andra ord Àr det för tidigt att greppa LFS, buildroot eller yocto (eller nÄgot annat), men vi mÄste redan börja. För de som har resurser (jag har 4GB eMMC pÄ mina pilotavbilder) finns det en lösning - att dela ett distributionspaket med utvecklarna, vilket snabbt gör det möjligt att fÄ nÄgot som saknas för tillfÀllet, och sedan kan vi alltid samla paketlistor och skapa en lista för den mÄlinriktade rootfs.

Denna artikel innehÄller ingen nyhet och Àr en enkel copy-paste-instruktion.

Syftet med artikeln Àr att samla Ubuntu rootfs för ARM-kort (i mitt fall baserat pÄ Colibri imx7d).

Samla avbilden

Vi samlar den mÄlinriktade rootfs för distribution.

Vi packar upp Ubuntu Base

Vi vÀljer version sjÀlva baserat pÄ behov och egna preferenser. HÀr har jag listat 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

Kontrollera stöd för BINFMT i kÀrnan

Om du har en vanlig distribution sÄ finns stöd för BINFMT_MISC och allt Àr konfigurerat; om inte - Àr jag sÀker pÄ att du vet hur du aktiverar stöd för BINFMT i kÀrnan.

Kontrollera att BINFMT_MISC Àr aktiverat i kÀrnan:

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

Nu mÄste vi kontrollera instÀllningarna:

$ 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

Vi kan registrera manuellt med hjÀlp av, till exempel, denna instruktion.

Konfigurera qemu static arm

Nu behöver vi en statiskt kompilerad qemu-instans.

!!! VARNA !!!
Om du planerar att anvÀnda en container för att bygga nÄgot, se:
https://sourceware.org/bugzilla/show_bug.cgi?id=23960
https://bugs.launchpad.net/qemu/+bug/1805913
DÄ för x86_64-vÀrd och arm-gÀst mÄste den i386-version av qemu anvÀndas:
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
# sökvÀg i rootfs och namn pÄ körbar fil mÄste överensstÀmma med /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), statiskt lÀnkad, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, för GNU/Linux 3.2.0, avskalad
$ 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), statiskt lÀnkad, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, för GNU/Linux 3.2.0, avskalad

Chroot

En enkel skript:

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

Vi beundrar 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

Av nyfikenhet kommer vi att mÀta storleken före och efter installationen av det minimi (för mig) paketset:

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

LÄt oss uppdatera:

# apt update
# apt upgrade --yes

Vi installerar de paket vi Àr intresserade av:

# 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

Huvudfiler för kÀrnan, moduler Àr ett helt annat kapitel. Vi kan förstÄs inte installera bootloader, kÀrna, moduler, enhetstrÀd via Ubuntu. De kommer till oss utifrÄn, antingen samlar vi dem sjÀlva eller sÄ tillhandahÄlls de av tillverkaren av kortet; i vilket fall som helst ligger det utanför denna instruktion.

En viss grad av versionsavvikelse Àr acceptabelt, men det Àr bÀttre att ta dem frÄn kÀrnbyggnaden.

# apt install --yes linux-headers-generic

LÄt oss se vad vi har fÄtt och det Àr inte lite:

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

Glöm inte att stÀlla in ett lösenord.

Vi packar bilden

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

Dessutom kan vi installera etckeeper med instÀllningen autopush

LÄt oss sÀga att vi har delat vÄr byggnad, arbetet har börjat; hur ska vi sedan sammanstÀlla olika versioner av vÄrt system?

Etckeeper kan komma till vÄr hjÀlp.

SÀkerhet Àr en personlig frÄga:

  • du kan skydda specifika grenar
  • generera en unik nyckel för varje enhet
  • förbjuda force push
  • och sĂ„ vidare ...
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...

Vi konfigurerar autopush

Vi kan förstÄs skapa grenar pÄ enheten i förvÀg (till exempel skapa ett skript eller en tjÀnst som körs vid första start).

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

Men vi kan vara lite smartare 


Den lata vÀgen

LĂ„t oss sĂ€ga att vi har nĂ„gon unik identifierare, som till exempel processorserienummer (eller MAC — seriösa företag köper ett intervall):

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

DÄ kan vi anvÀnda den för namn pÄ den gren vi kommer att pusha till:

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

Skapa ett 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

Och allt — efter en tid kan vi se förĂ€ndringar och skapa en lista med paket för den mĂ„linriktade firmware.

Rekommenderade material

BINFMT_MISC
KÀrnstöd för olika binÀra format (binfmt_misc)
Kompilering med qemu anvÀndarchroot
Bygga Ubuntu rootfs för ARM
Hur man skapar en anpassad Ubuntu-live frÄn grunden
Crossdev qemu-static-user-chroot
etckeeper

problem getdents64

readdir() ÄtervÀnder NULL (errno=EOVERFLOW) för 32-bitars anvÀndar-statiska qemu pÄ en 64-bitars vÀrd
Ext4 64-bits hash bryter 32-bitar glibc 2.28+
compiler_id_detection misslyckas för armhf nÀr QEMU anvÀndarlÀgesimulering anvÀnds
CMake fungerar inte ordentligt under qemu-arm

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster