ARM үчүн Ubuntu сүрөтүн түзүү "нөлдөн"

Өнүктүрүү жаңыдан башталганда, кайсы пакеттер максаттуу rootf'терге бараары белгисиз.

Башкача айтканда, LFS, buildroot же yocto (же башка бир нерсе) алуу үчүн али эрте, бирок сиз буга чейин башташыңыз керек. Байлар үчүн (менде пилоттук үлгүлөр боюнча 4 ГБ eMMC бар) иштеп чыгуучуларга бөлүштүрүүнү таратуунун жолу бар, бул аларга учурда жетишпеген нерсени тез жеткирүүгө мүмкүндүк берет, андан кийин биз ар дайым пакеттердин тизмесин чогултуп, тизме түзө алабыз. максаттуу тамырлар.

Бул макала жаңы эмес жана жөнөкөй көчүрүп чаптоо көрсөтмөсү.

Макаланын максаты - ARM такталары үчүн Ubuntu rootfs түзүү (менин учурда, Colibri imx7d негизинде).

Имидж түзүү

Биз репликация үчүн максаттуу rootfs чогултабыз.

Ubuntu базасын ачуу

Биз релизди муктаждыктарга жана өзүбүздүн каалоолорубузга жараша өзүбүз тандайбыз. Мына мен 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

Ядродогу BINFMT колдоосу текшерилүүдө

Эгерде сизде жалпы бөлүштүрүү бар болсо, анда BINFMT_MISC колдоо бар жана баары конфигурацияланган, эгерде андай эмес болсо, анда ядродо BINFMT колдоосун кантип иштетүүнү билесиз деп ишенем.

Ядродо BINFMT_MISC иштетилгенин текшериңиз:

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

Эми сиз орнотууларды текшерүү керек:

$ 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

Кол менен каттасаңыз болот, мисалы, бул жерде бул көрсөтмөлөр.

Qemu статикалык колун орнотуу

Эми бизге статикалык чогултулган qemu инстанциясы керек.

!!! КӨҢҮЛ!!!
Эгер сиз бир нерсе куруу үчүн контейнерди колдонууну пландап жатсаңыз, текшерип көрүңүз:
https://sourceware.org/bugzilla/show_bug.cgi?id=23960
https://bugs.launchpad.net/qemu/+bug/1805913
Андан кийин x86_64 хосту жана курал коногу үчүн qemu'нун i386 версиясын колдонушуңуз керек:
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

Жөнөкөй скрипт:

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

Биз натыйжага суктанабыз:

$ ./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

Жөн гана көңүл ачуу үчүн, пакеттердин минималдуу (мен үчүн) топтомун орнотконго чейин жана андан кийин өлчөмдү өлчөп көрөлү:

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

Жаңырталы:

# apt update
# apt upgrade --yes

Бизди кызыктырган пакеттерди орнотобуз:

# 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

Ядронун баш файлдары жана модулдары өзүнчө маселе. Албетте, биз Ubuntu аркылуу жүктөгүчтү, ядрону, модулдарды, түзмөк дарагын орнотпойбуз. Алар бизге сырттан келишет же биз аларды өзүбүз чогултабыз же тактайды өндүрүүчү бизге берет, кандай болгон күндө да бул бул нускаманын алкагына кирбейт.

Кандайдыр бир деңгээлде версиянын дивергенциясы алгылыктуу, бирок аларды ядро ​​түзүмүнөн алган жакшы.

# apt install --yes linux-headers-generic

Келгиле, эмне болгонун карап көрөлү жана ал көп болду:

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

Сырсөз коюуну унутпаңыз.

Сүрөттү таңгактоо

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

Кошумчалай кетсек, биз autopush жөндөөлөрү менен etckeeper орното алабыз

Макул, биз жыйыныбызды тараттык дейли, системабыздын кийинчерээк ар кандай версияларын кантип мыкты чогултуу боюнча иш башталды.

etckeeper бизге жардамга келе алат.

Коопсуздук - бул жеке маселе:

  • кээ бир бутактарды коргой аласыз
  • ар бир аппарат үчүн уникалдуу ачкычты түзүү
  • күч менен түртүүнү өчүрүү
  • жана башкалар. ...
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...

Келиңиз, автопушту орнотобуз

Биз, албетте, алдын ала түзмөктө бутактарды түзө алабыз (келгиле, биз скрипт же кызматты биринчи жолу ишке киргизебиз дейли).

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

Же биз акылдуураак нерсе кыла алабыз ...

Жалкоо жол

Келгиле, кандайдыр бир уникалдуу идентификаторду алалы, айталы, процессордун сериялык номери (же MAC - олуттуу компаниялар диапазонду сатып алышат):

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

Андан кийин биз аны түрткөн филиалдын аталышы үчүн колдоно алабыз:

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

Келгиле, жөнөкөй скрипт түзөлү:

# 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

Мунун баары - бир аздан кийин биз өзгөрүүлөрдү карап, максаттуу микропрограмма үчүн пакеттердин тизмесин түзө алабыз.

Сунушталган материалдар

BINFMT_MISC
Ар кандай бинардык форматтар үчүн ядро ​​колдоо (binfmt_misc)
Qemu колдонуучу chroot менен компиляция
ARM үчүн Ubuntu rootfs түзүү
Ыңгайлаштырылган Ubuntu түзүүнү нөлдөн баштап кантип түзүүгө болот
Crossdev qemu-static-user-chroot
жана башкалар

getdents64 көйгөйү

readdir() 32 биттик хосттогу 64 биттик колдонуучу статикалык QEMU үчүн NULL (errno=EOVERFLOW) кайтарат
Ext4 64 бит хэш 32 бит glibc 2.28+ сындырат
QEMU колдонуучу режиминин эмуляциясын колдонууда compiler_id_detection armhf үчүн иштебей калат
CMake qemu-arm астында туура иштебейт

Source: www.habr.com