Como o uso do qemu por chroot para ambientes cross compile funciona?

3

Para poder fazer compilação cruzada, há um truque em que você copia um binário qemu estático para o seu <different-arch-root-to-be>/usr/bin e quando você faz o chroot nesse sistema de arquivos, que tem binários não nativos, magicamente os binários são executáveis pelo cpu do host, e uname -a e semelhante afirmam que você está na arquitetura de destino. O resultado final é que você pode obter uma compilação cruzada simples.

Posso imaginar como isso pode funcionar, mas seria necessário que chroot fosse qemu aware.

É este o caso? Não consigo encontrar nenhuma documentação sobre como isso funciona.

    
por Catskul 19.08.2014 / 22:49

1 resposta

3

O Linux possui um mecanismo que permite que plug-ins sejam registrados para que o kernel chame um programa de intérprete quando instruído a executar um arquivo: binfmt_misc . Simplificando um pouco, quando um arquivo executável é executado, o kernel lê os primeiros bytes e é assim:

  • Ele começa com os quatro bytes \x7fELF seguidos por um cabeçalho ELF válido? Em caso afirmativo, use o carregador ELF dentro do kernel para carregar o programa e executá-lo.
  • Começa com os dois bytes #! ( shebang )? Se assim for, leia a primeira linha, analise o que está após o #! e execute isso, passando o caminho para o executável como um argumento.
  • Começa com um dos valores mágicos registrados através do mecanismo binfmt_misc? Em caso afirmativo, execute o intérprete registrado.

Para executar binários de arquitetura externa via Qemu, os valores mágicos correspondentes a um cabeçalho ELF com cada arquitetura suportada são registrados através do mecanismo binfmt_misc. Você pode ver o que é suportado listando o diretório /proc/sys/fs/binfmt_misc/ (que é um sistema de arquivos especial que representa o conjunto atual de interpretadores binfmt_misc registrados no kernel). Por exemplo:

cat /proc/sys/fs/binfmt_misc/qemu-arm
enabled
interpreter /usr/bin/qemu-arm-static
flags: 
offset 0
magic 7f454c4601010100000000000000000002002800
mask ffffffffffffff00fffffffffffffffffeffffff

Portanto, se um executável /somewhere/foo iniciar com os bytes mágicos especificados, se você executar /somewhere/foo arg1 arg2 , o kernel chamará /usr/bin/qemu-arm-static /somewhere/foo arg1 arg2 .

Não é necessário usar um chroot para que esse mecanismo funcione, o executável pode estar em qualquer lugar. Um chroot é conveniente para que os executáveis dinâmicos funcionem: os executáveis dinâmicos contêm um caminho absoluto para seu carregador, portanto, se você executar, e. um ARM exequível, ele espera um carregador localizado em /lib . Se o carregador estiver localizado em /different-arch-root-to-be , um chroot para esse diretório será necessário para o executável encontrar o carregador.

    
por 20.08.2014 / 02:24