Estou tentando configurar um rootfs multiarch para um sistema que pode executar ambos os endianess do mesmo kernel. É claro que não consigo misturar bibliotecas de diferente endianness dentro do mesmo programa. Além disso, o big endian rootfs está ligado para usar µClibc com seu carregador dinâmico, enquanto a versão little endian está vinculada à glibc.
Eu não tenho idéia de como a divisão conhecida de sistemas que executam o i686 e o amd64 (mesmo eles raramente usam ordem de byte diferente) .
Mas minha situação parece semelhante em alguns aspectos ... significa que:
- Eu posso mudar para um sistema diferente usando o chroot: (
chroot /tmp/rootfs
)
- binários estaticamente compilados podem ser executados em qualquer lugar;
²
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
Então eu adicionei os seguintes caminhos para /etc/ld.so.conf:
/tmp/rootfs/lib
/tmp/rootfs/usr/lib
e eu copiei o carregador dinâmico dos outros rootfs: (µClibc use ld-uClibc.so)
localhost# ln /tmp/rootfs/lib/ld-linux.so.2 /lib/
localhost# ln /tmp/rootfs/bin/zsh5 /bin/
O ld-linux.so.2 é um binário estático, portanto, posso executar qualquer biblioteca vinculada dinamicamente com ele.
localhost# /lib/ld-linux.so.2 /bin/zsh5
localhost# exit
localhost#
Parece legal, mas os scripts do portage não poderão funcionar dessa maneira. Eu não posso usar o binfmt, pois ele criaria um loop porque o /lib/ld-linux.so.2 tem a mesma arquitetura que o destino.
Então eu pensei que o kernel encontraria e usaria o interpretador ELF correto automaticamente, mas isso não acontece:
localhost# zsh5
/bin/zsh5: No such file or directory
Ainda sou capaz de executar executáveis µ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
Então, eu não entendo como os sistemas multiarch usam a biblioteca de intérpretes certa para a arquitetura certa, uma vez que isso não funciona, e meu entendimento está preso nesse ponto.