termux / proot

An chroot-like implementation using ptrace.
https://wiki.termux.com/wiki/PRoot
Other
745 stars 161 forks source link

How do I add magics/masks to binfmt_misc? #192

Closed WheezyE closed 2 years ago

WheezyE commented 2 years ago

Problem description

Box86 is an x86->ARM emulator. I've had success running it on proot in the past, but I would like to use box86 and the newer box64 side-by-side. To do that, I believe the only way may be to use binfmt_misc. Proot's readme says that it implements binfmt_misc(?)

The trouble is, I can't seem to register box86 in binfmt_misc so that i386 files will be automatically passed to it. Binfmt_misc is the default mechanism for how box86 catches and emulates i386 files on arm processors. Having this feature is the only way I know of to make box86 and box64 play nicely with eachother.

Steps to reproduce

I'm using this script to set up proot-distro, a user account with sudo, box64, box86 with multi-arch, and wine inside the user account (note that I'm still working on this script and that it's still highly experimental).

When box86 or box64 are first installed, they automatically put a binmft_misc config file into /etc/binfmt.d/. The user is then supposed to run sudo systemctl restart systemd-binfmt as part of initial setup to load the binfmt config file into binfmt_misc. When I try installing systemctl, logging out/in, and then running systemctl though, I get

user@localhost:~$ sudo apt-get install -y systemctl systemd -y
# ...
user@localhost:~$ systemctl
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

Note: This is the default box86 binfmt.d config file for arm platforms (stored in /etc/binfmt.d/):

# /etc/binfmt.d/box86.conf
:x86:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/box86:

And if I try to manually set up binfmt_misc, I also get errors: This input:

sudo apt install binfmt-support -y

# Magic & mask vars
#magic='\x7f\x45\x4c\x46\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00' #qemu-static-i386 x86 file magic
magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00' #box86 x86 file magic
#mask='\xff\xff\xff\xff\xff\xfe\xfe\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' #qemu-static-i386 x86 file mask
mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' #box86 x86 file mask

# Binfmt box86 registration (caches a temp binfmt file in /proc/sys/fs/binfmt_misc/ )
sudo /usr/sbin/./update-binfmts --install box86f /usr/local/bin/box86 --magic "$magic" --mask "$mask" --offset 0 --credential no --fix-binary no

results in:

mount: /proc/sys/fs/binfmt_misc: mount(2) system call failed: Function not implemented.
update-binfmts: warning: Couldn't mount the binfmt_misc filesystem on /proc/sys/fs/binfmt_misc.

Expected behavior

I'm kind of new to binfmt_misc (and linux in general), but these steps seem to work ok on Raspberry Pi 4B and other linux arm distros. In distros where it works, a user can simply invoke a program name (like wine or wine64) and the appropriate box86 or box64 emulator will be run to handle the appropriate file architecture.

Additional information

I'm using a freshly-installed Termux downloaded from F-Droid:

~ $ termux-info
Application version:
0.117
Packages CPU architecture:
aarch64
Subscribed repositories:
# sources.list
deb https://packages.termux.org/apt/termux-main/ stable main
# science-repo (sources.list.d/science.list)
deb https://termux.mentality.rip/termux-science science stable
# game-repo (sources.list.d/game.list)
deb https://termux.mentality.rip/termux-games games stable
Updatable packages:
All packages up to date
Android version:
9
Kernel build information:
Linux localhost 4.4.146+ #1 SMP PREEMPT Sat Apr 24 02:53:11 UTC 2021 aarch64 Android
Device manufacturer:
Amazon
Device model:
KFTRWI
ghost commented 2 years ago

PRoot doesn't emulate real binfmt_misc as on LInux and it doesn't give you write access to /proc either (not saying that kernel used by Android doesn't have binfmt_support compiled in). Instead it allows to supply path to emulator binary, e.g. proot -q $PREFIX/bin/qemu-386 -r /rootfs /bin/bash. So at max you can have only one emulator at a time.

WheezyE commented 2 years ago

Thank you for the info, that's good to know!