58

I'm trying to chroot into a Arch Linux ARM filesystem from x86_64.

I've seen that it's possible to do using static qemu by copying the binary into the chroot system:

$ cp /usr/bin/qemu-arm archarm-chroot/usr/bin    

But despite this I always get the following error:

chroot: failed to run command ‘/bin/bash’: Exec format error

I know this means that the architectures differ. Am I doing something wrong?

jasonwryan
  • 73,126
Jivings
  • 955
  • 2
    You have to configure binfmt first, have a look at http://wiki.debian.org/QemuUserEmulation for a quiet short introduction. An example for configuring binfmt_misc can be found at http://svn.kju-app.org/trunk/qemu/qemu/qemu-binfmt-conf.sh – Ulrich Dangel Jun 28 '12 at 23:00
  • Qemu static packages don't appear to be in the Arch repositories. – Jivings Jun 28 '12 at 23:04
  • 2
    Sorry i don't use arch, but you should probably be able to build a static qemu package by adding -static to the linker options – Ulrich Dangel Jun 28 '12 at 23:07
  • If you're using something like CentOS then the static version of qemu isn't available, you have to build it yourself :( – G Huxley Sep 12 '21 at 22:11

9 Answers9

56

I use an ARM chroot from time to time: my phone runs Linux Deploy and the image dies now and then. I then copy it to my computer and examine the situation with chroot like this:

# This provides the qemu-arm-static binary
apt-get install qemu-user-static

# Mount my target filesystem on /mnt
mount -o loop fs.img /mnt

# Copy the static ARM binary that provides emulation
cp $(which qemu-arm-static) /mnt/usr/bin
# Or, more simply: cp /usr/bin/qemu-arm-static /mnt/usr/bin

# Finally chroot into /mnt, then run 'qemu-arm-static bash'
# This chroots; runs the emulator; and the emulator runs bash
chroot /mnt qemu-arm-static /bin/bash
Luc
  • 3,610
  • This one works , but after chroot all command gives no such file or directory. I'm using Fedora 24 , selinux problem? Need help please – Superbiji Sep 05 '16 at 10:33
  • @Superbiji Does running /bin/ls work? In that case, your $PATH variable is unset or garbled. Try export PATH=/sbin:/usr/sbin:/usr/bin:/bin. There might be other paths that you should add, but this is probably a good start. If that doesn't work, you probably forgot to copy binaries to the chroot environment. You can use bash to browse around the filesystem too, like echo /* is roughly equivalent to ls /*. I don't know if SELinux might get in the way, no experience there. – Luc Sep 05 '16 at 12:05
  • 2
    Even ls gives /bin/ls: no such file or directory. export shows good path. But echo /* is working, echo /usr/bin/qemu-arm* list the file. I have also mount sys, proc, dev – Superbiji Sep 05 '16 at 16:01
  • @Superbiji Where is your shell installed? That place should usually also contain other basics like ls. Check that, and if it doesn't have it, put them there. That's all I can say without knowing details, and as this is a Q&A and not tech support, you should create a new question if you want to go into details (perhaps also link to this comment thread). – Luc Sep 06 '16 at 18:43
  • 2
    Thanks for helping.. found the problem the cause is interpreter in binfmt point to invalid path – Superbiji Sep 08 '16 at 15:51
  • @Superbiji Great! Also thanks for reporting back, perhaps it will help someone in the future :) – Luc Sep 08 '16 at 20:05
  • This is excellent! Thanks. Should be the chosen answer. – CharlesS Mar 28 '17 at 07:56
  • Hi, I have the same problem as @Superbiji - all command gives no such file or directory, how do I know the path the interpreter points to , and how do I fix that ? , I run sudo chroot bla /bin/qemu-arm-static /bin/bash x where bla is the mounted directory , and x is a two lines script with #!/bin/bash that runs ls – dafnahaktana Nov 11 '17 at 18:43
  • 1
    ok, somehow it was solved by copying qemu-arm-static to bla/usr/bin instead of bla/bin. When I run which qemu-arm-static it gives me /bin/usr so I guess it should be consistent ? – dafnahaktana Nov 11 '17 at 18:52
  • Where the hell can i find qemu-arm-static? – vesperto Aug 12 '21 at 08:40
  • @vesperto Not sure you'll find it in hell, you might have to check heaven. Here on earth it can be found in the package that you installed in the first command of the code block. For the location on your filesystem, use which or perhaps locate or find. By default it's at the path that is also in the code block. – Luc Aug 12 '21 at 10:38
  • @Luc no qemu-user-static Xenial and I'm having trouble finding it in other distros. It may be qemu-system-arm but chroot is having trouble finding it (yes I copied it). Thanks for the Lapalissade, very helpful. – vesperto Aug 12 '21 at 10:57
  • Found it in bionic, seems to work. – vesperto Aug 12 '21 at 11:41
  • If you're using something like CentOS then qemu is in the Epel repo, but for the static version you have to build it yourself :( – G Huxley Sep 12 '21 at 22:13
  • 1
    qemu-aarch64-static for arm64 – akostadinov Mar 08 '24 at 15:24
15

IMPORTANT: Please look at the other answers. This is old and inaccurate answer.

You cannot chroot into different architecture. By chrooting, you are executing the binaries (from the chroot) on your architecture. Executing ARM binaries on x86 (and x86_64 in that matter) would lead to "Exec format error".

If you want to run binaries from different architecture you will need an Emulator. Qemu is a good candidate for this, but you will need to learn how to use it. This would involve creating RootFS and compiling a kernel for ARM. You will need a toolchain for compiling ARM binaries (and kernel) perhaps. One thing is for sure: Forget the chroot method, you cannot run binaries compiled for ARM on x86 (x86_64).

Edit: After the small talk with @UrichDangel, I realized, it should be possible to enter the chroot environment with qemu-user programs (qemu-arm in this case). Chroot should be executing qemu-arm compiled for your host architecture, then the qemu-arm can execute your /bin/sh (compiled for arm).

0xAF
  • 1,219
  • 7
    You should be able to use binfmt and qemu in combination to run non native targets - http://wiki.debian.org/QemuUserEmulation – Ulrich Dangel Jun 28 '12 at 22:59
  • 2
    I know how to use Qemu for emulation. Apparently you can use it with chroot, although clearly I cannot work out how. – Jivings Jun 28 '12 at 23:01
  • @UlrichDangel, Yes, this is a good information. But I think the OP were not looking for this king of solution. binfmt would be possible once he has properly installed qemu with qemu-arm emulation, but I believe he is wanting to enter his ARM emulation environment (e.g. Raspberry Pi) where he would need qemu-system-arm. – 0xAF Jun 28 '12 at 23:07
  • @0xAF but the binfmt/qemu-user solution is exactly what OP described, being able to chroot into into an arm chroot and run the commands without the need to build a dedicated rootfs etc. – Ulrich Dangel Jun 28 '12 at 23:09
  • @Jivings, If you are looking to start just one binary compiled for ARM, you should be able to do this with qemu-arm program, then you will find the binfmt (@Ulrich Daniel suggestion) very handy. – 0xAF Jun 28 '12 at 23:10
  • @UlrichDangel, perhaps I misunderstood the OPs intention. Sorry for that. Edit: I got mislead by his profile with good reputation from Raspberry Pi site, I though he needs to enter RPi environment. – 0xAF Jun 28 '12 at 23:11
  • @0xAF i also wanted to show that it is possible to chroot into different architectures with the binfmt_misc method. Of course it still will be emulated but it feels like it is native, e.g. you can run ./program. I am also not 100% sure what OP needs and creating a cross compile environment is probably the best way anyway and just run it nativ. – Ulrich Dangel Jun 28 '12 at 23:15
  • 1
    @UlrichDangel, now on a second though, I believe you're right. It is possible to enter emulated chroot with the qemu-arm (or should be). I'll Edit my comment on that. – 0xAF Jun 28 '12 at 23:16
  • please delete answers that are outdated rather than add content to explain that it is outdated. – Eric Apr 03 '23 at 08:56
14

On Arch, Install qemu-user-static and binfmt-qemu-static from the AUR .

Then make sure to copy the qemu-*-static to the usr/bin/ directory in the thing you want to chroot to and then the chroot should work with something like chroot /mnt qemu-arm-static /bin/bash

Slim
  • 125
Mariano Alvira
  • 241
  • 2
  • 2
12

I think the problem is that you should not copy qemu-arm but qemu-arm-static. This is a static compiled executable able to run from inside the chroot without any libraries.

You can also look in /proc/sys/fs/binfmt_misc if there exists a file qemu-arm. If not restart the service binfmt_support.

  • I had to manually run: update-binfmts --importdir /var/lib/binfmts/ --import then everything showed up in /proc/sys/fs/binfmt_misc and the chroot works. – Mariano Alvira Jan 02 '15 at 22:58
8

You can most definitely 'chroot' into a (mounted) filesystem meant for a different architecture and do some meaningful work, you just need the right tools.

Have a look at PRoot, which is a user-space implementation of chroot, mount --bind, and binfmt_misc: https://proot-me.github.io/

Together with QEMU's user mode emulators, you're all set.

Although you usually cannot perform a 'full' boot (i.e. starting init and services), it is good enough to run some binaries from their 'natural' place, with access to all their configuration files, including some that are bind-mounted from the 'host' system, etc.

Warbo
  • 281
ack
  • 1,039
7

I believe, for this OP, all he needed to do was configure binfmts, simply by running:

update-binfmts --enable qemu-arm

After running this, chroot into the arm filesystem would have been possible.

techraf
  • 5,941
1

Adding to Luc's answer: you need to make sure the location of the interpreter is the same in the chroot as it is in the main file system. This is because the kernel detects the architecture of an executable and then uses the location of the interpreter as shown by update-binfmts --display to start it up. So the line

cp $(which qemu-arm-static) /mnt/usr/bin

should actually be

cp $(which qemu-arm-static) /mnt/$(which qemu-arm-static)

Otherwise, you may get "Not found"-errors inside your chroot as your kernel can't find the required interpreter, if the location of qemu-arm-static is not inside /usr/bin on your system.

1
sudo apt-get update
sudo apt-get install debootstrap qemu qemu-user-static
sudo qemu-debootstrap --arch armhf bionic armhf-chroot
sudo chroot armhf-chroot

uname -m 
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
0

I just ran into the same issue on Ubuntu. I did have binfmt configured and qemu-arm-static copied to the same chroot-ed path as on host system.

After an hour, I did set|grep bash on a host machine. I found that I had /bin/bash in two env variables: SHELL and SUDO_COMMAND. After replacing the variables, my chroot to ARM worked:

SHELL=/bin/sh SUDO_COMMAND=/bin/sh chroot hd