1

Я пытаюсь настроить multiarch rootfs для системы, которая может запускать оба порядка байтов из одного и того же ядра. Конечно, я не могу смешивать библиотеки с разными порядками байтов в одной программе. Кроме того, root-файлы с прямым порядком байтов связаны с использованием µClibc с его динамическим загрузчиком, тогда как версия с прямым порядком байтов связана с glibc.

Я понятия не имею, как хорошо известное отделение от систем, которые работают как на i686, так и на amd64 (даже если они редко используют разный порядок байтов).

Но моя ситуация выглядит несколько похожей ... это означает, что:

  • Я могу переключиться на другую систему, используя chroot: (chroot /tmp/rootfs)
  • статически скомпилированные двоичные файлы можно запускать везде;

²

example.c:
int main() {return 200;}

²

localhost# gcc -static -Ofast $HOME/example.c -o $HOME/example
localhost# $HOME/example
localhost# echo $?
200
localhost# mv $HOME/example /tmp/rootfs
localhost# chroot /tmp/rootfs /example
localhost# echo $?
200

Поэтому я добавил следующие пути в /etc/ld.so.conf:

/tmp/rootfs/lib
/tmp/rootfs/usr/lib

и я скопировал динамический загрузчик из других rootfs: (µClibc использует ld-uClibc.so)

localhost# ln /tmp/rootfs/lib/ld-linux.so.2 /lib/
localhost# ln /tmp/rootfs/bin/zsh5 /bin/

ld-linux.so.2 - это статический двоичный файл, поэтому я могу запускать с ним любую динамически связанную библиотеку.

localhost# /lib/ld-linux.so.2 /bin/zsh5
localhost# exit
localhost# 

Это выглядит красиво, но сценарии portage не смогут работать таким образом. Я не могу использовать binfmt, так как это создаст цикл, потому что /lib/ld-linux.so.2 имеет ту же архитектуру, что и цель.
Поэтому я подумал, что ядро автоматически найдет и использует правильный ELF-интерпретатор, но это не так:

localhost# zsh5
/bin/zsh5: No such file or directory

Я все еще могу запустить исполняемые файлы µClibc:

localhost# busybox
BusyBox v1.22.1 (2014-06-11 08:01:31 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
   or: busybox --install [-s] [DIR]
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        [, [[, acpid, addgroup, adduser, adjtimex, ar, arp, arping, ash, awk, base64, basename, bb, bbconfig, bbsh, blkid, blockdev, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst,
    chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio, crond, cryptpw, cttyhack, cut, date, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsdomainname, dos2unix, du, dumpkmap,
    dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, false, fbset, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flash_eraseall, flash_lock, flash_unlock, flashcp, flock, free,
    freeramdisk, fsck, fstrim, fsync, ftpd, fuser, getopt, getty, ginit, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostname, httpd, hwclock, id, ifconfig, ifdown, ifenslave, ifplugd, ifup, init, insmod, install,
    ionice, iostat, ip, ipaddr, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, last, less, linux32, linux64, linuxrc, ln, loadfont, loadkmap, login, losetup, lpq, lpr, ls, lsattr, lsmod, lsof,
    lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.reiser, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount,
    mountpoint, mpstat, mt, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, ntpd, openvt, passwd, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir,
    poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, readahead, readlink, realpath, reboot, renice, reset, resize, rev, rm, rmdir, rmmod, route, rtcwake, runlevel, rx, script, scriptreplay,
    sed, sendmail, seq, setarch, setconsole, setfont, setkeycodes, setlogcons, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, sleep, softlimit, sort, split, start-stop-daemon, stat, strings, stty,
    su, sum, swapoff, swapon, switch_root, sync, sysctl, tac, tail, tar, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl, tune2fs, ubiattach, ubidetach,
    ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpc6, udhcpd, umount, uname, uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users, usleep, vconfig, vi, vlock, volname, wall, watch, watchdog,
    wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes, zcat, zcip

Итак, я не понимаю, как многоархатные системы используют правильную библиотеку интерпретаторов для правильной архитектуры, поскольку она не работает, и мое понимание застряло на этом этапе.

2 ответа2

0

Хорошо, оказалось, что это была простая жестко заданная проблема пути.

localhost# readelf -l /bin/zsh5

Elf file type is EXEC (Executable file)
Entry point 0x40f015
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000001f8 0x00000000000001f8  R E    8
  INTERP         0x0000000000000238 0x0000000000400238 0x0000000000400238
                 0x000000000000001c 0x000000000000001c  R      1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

добавление этой библиотеки по этому пути и ld-2.19.so в LD_LIBRARY_PATH решило мою проблему.

Так что это, вероятно, первая система, которая может запускать amd64 и работает так же, как i686 :).

0

В Linux вы можете запустить только двоичный файл с тем же порядком байтов, что и в ядре, на котором он работает. Если вы хотите запустить двоичный файл armeb (big-endian ARM), вам нужно иметь ядро armeb, а если вы хотите запустить двоичный файл armel, вам нужно иметь ядро armel. Это верно для всех архитектур ЦП, которые поддерживают режимы с прямым и прямым порядком байтов в Linux (ARM, ARM64, ARC, C6x, PowerPC, MIPS, m32r, microblaze, SH4, xtensa).

Есть два способа обойти это, но оба имеют и существенные недостатки:

  1. Вы можете запустить любой двоичный файл, используя эмуляцию qemu-user. Типичным примером этого является запуск двоичного файла ARM на платформе x86, но вы также можете запустить двоичный файл PowerPC с прямым порядком байтов на ядре ARM с прямым порядком байтов или любой другой комбинации, если хост и цель поддерживаются qemu. Некоторые вещи (например, редкие драйверы устройств) могут не работать из-за отсутствия кода эмуляции в qemu, и в целом все будет работать медленно, обычно в 10 раз медленнее, чем выполнение собственных инструкций.

  2. Вы можете запустить гостевую KVM с другим порядком байтов от хоста, если у вас есть аппаратная поддержка. Это работает на некоторых ARM32 (Cortex-A7, A12, A15, A17, но не Cortex-A9 или старше), а также PowerPC и ARM64. Процессы гостя не видны хосту или наоборот, и вы должны настроить внутреннюю сеть и хранилище, чтобы гость делал что-нибудь полезное.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .