Mencipta imej Ubuntu untuk ARM "dari awal"

Apabila pembangunan baru bermula, selalunya tidak jelas pakej mana yang akan pergi ke rootfs sasaran.

Dalam erti kata lain, terlalu awal untuk mengambil LFS, buildroot atau yocto (atau sesuatu yang lain), tetapi anda sudah perlu bermula. Bagi orang kaya (saya mempunyai 4GB eMMC pada sampel perintis) terdapat jalan keluar untuk mengedarkan kepada pembangun pengedaran yang akan membolehkan mereka menghantar sesuatu yang tiada pada masa ini dengan cepat, dan kemudian kami sentiasa boleh mengumpul senarai pakej dan membuat senarai untuk rootfs sasaran.

Artikel ini bukan baru dan merupakan arahan salin-tampal yang mudah.

Tujuan artikel adalah untuk membina rootfs Ubuntu untuk papan ARM (dalam kes saya, berdasarkan Colibri imx7d).

Membina imej

Kami mengumpulkan rootfs sasaran untuk replikasi.

Membongkar Pangkalan Ubuntu

Kami memilih keluaran sendiri berdasarkan keperluan dan keutamaan kami sendiri. Di sini saya telah memberikan 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

Menyemak sokongan BINFMT dalam kernel

Jika anda mempunyai pengedaran biasa, maka terdapat sokongan untuk BINFMT_MISC dan semuanya dikonfigurasikan, jika tidak, maka saya pasti anda tahu bagaimana untuk membolehkan sokongan BINFMT dalam kernel.

Pastikan BINFMT_MISC didayakan dalam kernel:

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

Sekarang anda perlu menyemak tetapan:

$ 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

Anda boleh mendaftar secara manual menggunakan, contohnya, inilah arahan ini.

Menyediakan lengan statik qemu

Sekarang kita memerlukan contoh qemu yang dipasang secara statik.

!!! PERHATIAN!!!
Jika anda bercadang untuk menggunakan bekas untuk membina sesuatu, lihat:
https://sourceware.org/bugzilla/show_bug.cgi?id=23960
https://bugs.launchpad.net/qemu/+bug/1805913
Kemudian untuk hos x86_64 dan tetamu lengan anda perlu menggunakan versi i386 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

Kekacauan

Skrip mudah:

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

Kami mengagumi hasilnya:

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

Hanya untuk keseronokan, mari kita ukur saiz sebelum dan selepas memasang set pakej minimum (bagi saya):

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

Mari kemas kini:

# apt update
# apt upgrade --yes

Mari pasang pakej yang kami minati:

# 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

Fail dan modul pengepala kernel adalah perkara yang berasingan. Sudah tentu, kami tidak akan memasang pemuat but, kernel, modul, pokok peranti melalui Ubuntu. Mereka akan datang kepada kami dari luar atau kami akan memasangnya sendiri atau mereka akan diberikan kepada kami oleh pengeluar papan, dalam apa jua keadaan ini di luar skop arahan ini.

Pada tahap tertentu, perbezaan versi boleh diterima, tetapi lebih baik untuk mengambilnya dari binaan kernel.

# apt install --yes linux-headers-generic

Mari lihat apa yang berlaku dan ia ternyata banyak:

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

Jangan lupa tetapkan kata laluan.

Mengemas imej

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

Selain itu, kita boleh memasang etckeeper dengan tetapan autopush

Baiklah, katakan kami mengedarkan pemasangan kami, kerja bermula tentang cara terbaik untuk memasang versi sistem kami yang berbeza kemudian.

dllkeeper boleh datang untuk membantu kami.

Keselamatan adalah perkara peribadi:

  • anda boleh melindungi cawangan tertentu
  • menjana kunci unik untuk setiap peranti
  • lumpuhkan tolakan paksa
  • dan lain-lain. ...
# ssh-keygen
# apt install etckeeper
# etckeeper init
# cd /etc
# git remote add origin ...

Mari sediakan autopush

Kita boleh, sudah tentu, membuat cawangan pada peranti terlebih dahulu (katakan kita membuat skrip atau perkhidmatan yang akan dijalankan pada kali pertama ia dilancarkan).

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

Atau kita boleh melakukan sesuatu yang lebih bijak...

Cara malas

Biarkan kami mempunyai beberapa jenis pengecam unik, katakan nombor siri pemproses (atau MAC - syarikat yang serius membeli julat):

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

Kemudian kita boleh menggunakannya untuk nama cawangan yang akan kita tolak:

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

Mari buat skrip mudah:

# 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

Dan itu sahaja - selepas beberapa ketika kita boleh melihat perubahan dan membuat senarai pakej untuk perisian tegar sasaran.

Bahan yang disyorkan

BINFMT_MISC
Sokongan Kernel untuk pelbagai Format Perduaan (binfmt_misc)
Menyusun dengan pengguna qemu chroot
Membina rootfs Ubuntu untuk ARM
Bagaimana untuk mencipta Ubuntu tersuai secara langsung dari awal
Crossdev qemu-static-user-chroot
etckeeper

masalah getdents64

readdir() mengembalikan NULL (errno=EOVERFLOW) untuk qemu statik pengguna 32-bit pada hos 64-bit
Ext4 64 bit cincang memecahkan 32 bit glibc 2.28+
compiler_id_detection gagal untuk armhf apabila menggunakan emulasi mod pengguna QEMU
CMake tidak berfungsi dengan betul di bawah lengan qemu

Sumber: www.habr.com