Când dezvoltarea abia a început, adesea nu este clar ce pachete vor fi incluse în rootfs-ul țintă.
Cu alte cuvinte, este prea devreme să ne apucăm de LFS, buildroot sau yocto (sau altceva), dar trebuie să începem deja. Pentru cei cu resurse (la mostrele mele am 4GB eMMC), există o soluție: să oferim dezvoltatorilor o distribuție care să permită livrarea rapidă a ce lipsește în acel moment, iar apoi putem întotdeauna să compilăm liste de pachete pentru a forma lista pentru rootfs-ul țintă.
Acest articol nu aduce nimic nou și reprezintă un simplu ghid de tip copy-paste.
Scopul articolului este construirea rootfs-ului Ubuntu pentru plăci ARM (în cazul meu, bazat pe Colibri imx7d).
Crearea imaginii
Construim rootfs-ul țintă pentru reproducere.
Dezarchivează Ubuntu Base
Alegem noi versiunea, în funcție de necesitate și preferințele personale. Aici am enumerat 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 rootfsVerificarea suportului BINFMT în nucleu
Dacă aveți o distribuție comună, suportul pentru BINFMT_MISC este inclus și totul este configurat. Dacă nu, sunt sigur că știți cum să activați suportul BINFMT în nucleu.
Asigurați-vă că BINFMT_MISC este activat în nucleu:
$ zcat /proc/config.gz | grep BINFMT
CONFIG_BINFMT_ELF=y
CONFIG_COMPAT_BINFMT_ELF=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_BINFMT_MISC=yAcum trebuie să verificăm setările:
$ 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 ffffffffffffff00fffffffffffffffffeffffffSe poate înregistra manual, de exemplu, .
Configurarea qemu static arm
Acum avem nevoie de o instanță qemu compilată static.
!!! ATENȚIE!!!
Dacă doriți să folosiți un container pentru a construi un anumit lucru, consultați:
Atunci pentru gazdă x86_64 și invitat arm trebuie să utilizați versiunea i386 a qemu:
$ 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
# calea în rootfs și numele fișierului executabil trebuie să corespundă cu /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), linked statically, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, pentru 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), linked statically, BuildID[sha1]=be45f9a321cccc5c139cc1991a4042907f9673b6, pentru GNU/Linux 3.2.0, strippedChroot
Script simplu:
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}
fiNe admirăm rezultatul obținut:
$ .\/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\/LinuxDe curiozitate, să măsurăm dimensiunea înainte și după instalarea setului minim de pachete (pentru mine):
# du -d 0 -h / 2>/dev/null
63M /Să actualizăm:
# apt update
# apt upgrade --yesSă instalăm pachetele care ne interesează:
# 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 iiodFișierele de antet ale nucleului, modulele, sunt o discuție separată. Bootloaderul, nucleul, modulele, arborele de dispozitive nu le putem instala prin Ubuntu. Ele vor veni din exterior sau le vom compila noi înșine sau ne le va furniza producătorul plăcii, oricum, aceasta este dincolo de această instrucțiune.
Până la un punct, abaterile de versiuni sunt acceptabile, dar cel mai bine este să le luăm de la compilarea nucleului.
# apt install --yes linux-headers-genericSă vedem ce a ieșit și a ieșit mult:
# apt clean
# du -d 0 -h / 2>/dev/null
770M /Nu uitați să setați parola.
Pachetăm imaginea
$ sudo tar -C rootfs --transform "s|^.\/||" --numeric-owner --owner=0 --group=0 -c .\/ | tar --delete .\/ | gzip > rootfs.tar.gzÎn plus, putem instala etckeeper cu setarea autopush
Bine, să spunem că am distribuit construcția noastră, a început activitatea, cum ar fi cel mai bine să construim ulterior diferitele versiuni ale sistemului nostru.
Etckeeper ne-ar putea veni în ajutor.
Securitatea este o chestiune personală:
- puteți proteja anumite ramuri
- generați o cheie unică pentru fiecare dispozitiv
- interziceți force push
- și așa mai departe …
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...Să configurăm autopush
Putem, desigur, să creăm ramuri pe dispozitiv din timp (de exemplu, să facem un script sau un serviciu care să se execute la prima pornire).
# cat /etc/etckeeper/etckeeper.conf
PUSH_REMOTE="origin"Sau putem acționa mai ingenios…
Calea leneșului
Să avem un identificator unic, să spunem, seria procesorului (sau MAC — companiile serioase cumpără un domeniu):
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 : 06372509Atunci putem folosi acest lucru ca nume pentru ramura în care vom face push:
# cat /proc/cpuinfo | grep Serial | cut -d':' -f 2 | tr -d [:blank:]
06372509Să creăm un script simplu:
# 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Și totul — după un timp putem verifica modificările și să formăm o listă de pachete pentru firmware-ul țintă.
Materiale recomandate
problema getdents64
Sursa: habr.com
