Como posso executar o chroot em um sistema de arquivos com uma arquitetura diferente?

38

Estou tentando chrootentrar em um ARMsistema de arquivos Arch Linux a partir de x86_64.

Vi que é possível usar a estática qemucopiando o binário no sistema chroot:

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

Mas, apesar disso, sempre recebo o seguinte erro:

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

Eu sei que isso significa que as arquiteturas diferem. Estou fazendo algo errado?

Jivings
fonte
2
Você precisa configurar binfmtprimeiro, dê uma olhada no wiki.debian.org/QemuUserEmulation para obter uma breve introdução. Um exemplo para configurar o binfmt_misc pode ser encontrado em svn.kju-app.org/trunk/qemu/qemu/qemu-binfmt-conf.sh
Ulrich Dangel
Pacotes estáticos do Qemu não parecem estar nos repositórios do Arch.
Jivings
2
Desculpe eu não uso arco, mas provavelmente você deve ser capaz de construir um pacote qemu estática adicionando -staticàs opções de vinculador
Ulrich Dangel

Respostas:

15

Você não pode criar uma arquitetura diferente. Fazendo chroot, você está executando os binários (a partir do chroot) em sua arquitetura. A execução de binários ARM no x86 (e x86_64 nesse assunto) levaria ao "erro de formato Exec".

Se você deseja executar binários de arquitetura diferente, precisará de um emulador. O Qemu é um bom candidato para isso, mas você precisará aprender como usá-lo. Isso envolveria a criação do RootFS e a compilação de um kernel para o ARM. Você precisará de uma cadeia de ferramentas para compilar binários ARM (e kernel) talvez. Uma coisa é certa: esqueça o método chroot, você não pode executar binários compilados para ARM no x86 (x86_64).

Edit: Após a pequena conversa com @UrichDangel, eu percebi, deveria ser possível entrar no ambiente chroot com programas qemu-user (qemu-arm neste caso). O Chroot deve estar executando o qemu-arm compilado para sua arquitetura host, então o qemu-arm pode executar seu / bin / sh (compilado para arm).

0xAF
fonte
6
Você deve ser capaz de usar binfmte qemu em combinação para executar as metas não nativas - wiki.debian.org/QemuUserEmulation
Ulrich Dangel
2
Eu sei como usar o Qemu para emulação. Aparentemente, você pode usá-lo com chroot, embora claramente eu não saiba como.
Jivings
@UlrichDangel, Sim, esta é uma boa informação. Mas acho que o OP não estava procurando por esse rei da solução. O binfmt seria possível depois que ele instalasse o qemu corretamente com a emulação do qemu-arm, mas acredito que ele queira entrar no seu ambiente de emulação do ARM (por exemplo, Raspberry Pi) onde ele precisaria do qemu-system-arm.
0xAF
@ 0xAF mas a binfmt/ qemu-usersolução é exatamente o OP descrito, sendo capaz de chroot em em um chroot braço e executar os comandos sem a necessidade de construir um rootfs dedicados etc.
Ulrich Dangel
1
@UlrichDangel, agora em um segundo, acredito que você esteja certo. É possível inserir chroot emulado com o braço qemu (ou deveria ser). Vou editar meu comentário sobre isso.
0xAF
33

De vez em quando, uso um chroot do ARM: meu telefone executa o Linux Deploy e a imagem morre de vez em quando. Depois, copio-o para o meu computador e examino a situação com o chroot assim:

# 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
fonte
Este funciona, mas depois de chroot all, o comando não fornece esse arquivo ou diretório. Estou usando o Fedora 24, problema com selinux? Necessita de ajuda, por favor
Superbiji
@Superbiji A corrida /bin/lsfunciona? Nesse caso, sua $PATHvariável está desconfigurada ou ilegível. Tente export PATH=/sbin:/usr/sbin:/usr/bin:/bin. Pode haver outros caminhos que você deve adicionar, mas este provavelmente é um bom começo. Se isso não funcionar, você provavelmente esqueceu de copiar binários no ambiente chroot. Você pode usar o bash para navegar pelo sistema de arquivos também, como echo /*é aproximadamente equivalente a ls /*. Não sei se o SELinux pode atrapalhar, não há experiência lá.
Luc
1
Até ls dá /bin/ls: no such file or directory. a exportação mostra um bom caminho. Mas echo / * está funcionando, echo / usr / bin / qemu-arm * lista o arquivo. Eu também montar sys, proc, Dev
Superbiji
1
Obrigado por ajudar .. encontrado o problema a causa é intérprete no ponto binfmt a caminho inválido
Superbiji
1
ok, de alguma forma foi resolvido copiando qemu-arm-static para em bla/usr/binvez de bla/bin. Quando corro, which qemu-arm-staticisso me dá, /bin/usrentão acho que deve ser consistente?
dafnahaktana
11

Eu acho que o problema é que você não deve copiar, qemu-armmas qemu-arm-static. Este é um executável compilado estático, capaz de executar de dentro do chroot sem nenhuma biblioteca.

Você também pode procurar /proc/sys/fs/binfmt_miscse existe um arquivo qemu-arm. Caso contrário, reinicie o serviço binfmt_support.

Christian Wolf
fonte
Eu tive que executar manualmente: update-binfmts --importdir / var / lib / binfmts / --import, então tudo apareceu em / proc / sys / fs / binfmt_misc e o chroot funciona.
Mariano Alvira
7

Para chegar a este trabalho que eu instalado qemu-static-arme binfmt-supportde AUR.

Leia os comentários para qemu-user-static. Eu tive que atualizar o PKGBUILDURL de download e os hashes mais recentes para o makepkg terminar.

(Para instalar a partir AUR, baixe o tarball, untar, cd, run makepkg -i)

A resposta de Christian Wolf é importante. update-binfmtsnão é executado corretamente para ativar esses formatos. Para fazer isso, eu corri:

update-binfmts --importdir /var/lib/binfmts/ --import

conforme descrito na página de manual para update-binfmts. Depois disso, cat /proc/sys/fs/binfmt_miscmostrará os vários binfmts.

Em seguida, certifique-se de copiar o arquivo qemu-*-staticpara o usr/bin/diretório em que você deseja fazer o chroot e, em seguida, chrootdeve funcionar.

Mariano Alvira
fonte
6

Você pode definitivamente 'chroot' em um sistema de arquivos (montado) destinado a uma arquitetura diferente e fazer algum trabalho significativo, você só precisa das ferramentas certas.

Dê uma olhada no PRoot, que é uma implementação no espaço do usuário de chroot, mount --bind e binfmt_misc: https://proot-me.github.io/

Juntamente com os emuladores de modo de usuário do QEMU, você está pronto.

Embora você normalmente não possa executar uma inicialização 'completa' (ou seja, iniciando init e serviços), é bom executar alguns binários a partir do local 'natural', com acesso a todos os seus arquivos de configuração, incluindo alguns que são montados em bind sistema 'host' etc.

ack
fonte
2
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 
Maxim Akristiniy
fonte
1

Adicionando a resposta de Luc: você precisa garantir que a localização do intérprete seja a mesma no chroot e no sistema de arquivos principal. Isso ocorre porque o kernel detecta a arquitetura de um executável e, em seguida, usa o local do intérprete como mostrado update-binfmts --displaypara iniciá-lo. Então a linha

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

realmente deveria ser

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

Caso contrário, você poderá obter os espelhos "Não encontrado" dentro do seu chroot, pois o kernel não consegue encontrar o intérprete necessário, se o local qemu-arm-staticnão estiver dentro /usr/bindo seu sistema.

Marten Jacobs
fonte
0

Acabei de encontrar o mesmo problema no Ubuntu. Eu binfmtconfigurei e qemu-arm-staticcopiei para o mesmo caminho chroot-ed que no sistema host.

Depois de uma hora, eu fiz set|grep bashem uma máquina host. Eu descobri que tinha /bin/bashduas variáveis ​​env: SHELLe SUDO_COMMAND. Depois de substituir as variáveis, meu chroot para o ARM funcionou:

SHELL=/bin/sh SUDO_COMMAND=/bin/sh chroot hd
Victor Sergienko
fonte
0

Acredito que, para este OP, tudo o que ele precisava fazer era configurar o binfmts, simplesmente executando:

update-binfmts --enable qemu-arm

Depois de executar isso, o chroot no sistema de arquivos arm seria possível.

user175914
fonte