Post em Destaque

Feliz Natal e fechando com dica do fsck automático

Gostaria de desejar, em nome de todos da BSDInfo, um feliz Natal para todos os leitores do nosso blog. Que a paz e muita saúde estejam com vocês e esperamos fazer mais em 2013. Aproveitando deixo aqui uma pequena dica para quem tem servidores à distância. Pode ocorrer em algum momento a necessidade...

Leia mais...

FreeBSD – compatibilidade binária com Linux

Postado por gondim | Categoria FreeBSD, Software Livre, Tecnologia | Dia 07-06-2012

Tags:,

2

FreeBSD possui o que chamamos de compatibilidade binária com Linux. Veja bem não é emulação! Não estamos falando de um Wine da vida. Tanto FreeBSD quanto Linux executam binários em formato ELF  (Executable and Linking Format) e a diferença entre um e outro é mínima. Com algumas configurações veremos que binários Linux podem rodar em FreeBSD e a maior parte deles roda com uma performance melhor no FreeBSD que no próprio Linux. Existem algumas exceções mas são poucas onde não se conseguiria rodar um binário ELF Linux. Usaremos para os nossos testes um FreeBSD 9 32 bits rodando um programa chamado Midnight Commander (mc) que peguei de um Ubuntu Lucid 32 bits. Eu sei, eu sei que existe no ports o Midnight Commander mas o objetivo aqui é ver um binário linux rodando no FreeBSD.  🙂

Vamos começar nossos testes carregando o módulo de compatibilidade binária:

# kldload linux
# kldstat
Id Refs Address            Size     Name
1    6 0xffffffff80200000 11cd9b0  kernel
2    1 0xffffffff81412000 1e17c    linux.ko

Acima carregamos o módulo e podemos observar o linux.ko carregado. Para que isso fique sendo carregado sempre após o boot, adicione a linha abaixo em seu /etc/rc.conf:

linux_enable=”YES”

Também vamos precisar de umas bibliotecas e outros programas utilizados em sistemas GNU/Linux para compor um ambiente necessário de funcionamento e por isso vamos instalar um port específico para isso:

# cd /usr/ports/emulators/linux_base-f10
# make install distclean

Reparem que o port está em “emulators” mas não se trata de emulação. Contudo vamos precisar informar ao FreeBSD que aquele binário é um ELF do tipo Linux para que ele possa lê-lo adequadamente. A maneira de se fazer isso é através de uma marcação no binário. Veja bem a marcação é feita apenas no binário e não nas bibliotecas que este utiliza.

Após a instalação do port acima teremos essa estrutura criada:

# ls -l /compat/linux/
total 48
drwxr-xr-x   2 root  wheel  1024 Jun  5 10:47 bin
drwxr-xr-x  17 root  wheel  1024 Jun  5 10:48 etc
drwxr-xr-x   6 root  wheel  2560 Jun  5 10:47 lib
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 mnt
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 opt
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 proc
drwxr-xr-x   2 root  wheel  1024 Jun  5 10:47 sbin
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 selinux
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 srv
drwxr-xr-x   2 root  wheel   512 Jun  5 10:47 sys
drwxr-xr-x  13 root  wheel   512 Jun  5 10:48 usr
drwxr-xr-x  14 root  wheel   512 Jun  5 10:48 var

Precisamos adicionar algumas configurações para evitarmos problemas com programas linux que usem shared memory e proc. Façamos o seguinte:

1º Adicione a linha abaixo em /etc/devfs.conf:

link /tmp shm

2º Adicione a linha abaixo em /etc/fstab:

none /compat/linux/proc linprocfs rw 0 0

Reboot o sistema e começaremos com o Midnight Commander.

No Ubuntu fiz o seguinte comando para vermos todas as libs necessárias para a execução do nosso programa:

# ldd /usr/bin/mc
linux-gate.so.1 =>  (0x0018e000)
libgpm.so.2 => /usr/lib/libgpm.so.2 (0x0045b000)
libslang.so.2 => /lib/libslang.so.2 (0x0018f000)
libglib-2.0.so.0 => /lib/libglib-2.0.so.0 (0x0073d000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00289000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0x00508000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00110000)
libpcre.so.3 => /lib/libpcre.so.3 (0x00c1d000)
/lib/ld-linux.so.2 (0x005f9000)

Nem só de libs viverá um programa mas sim de todos os arquivos necessários para a sua perfeita execução. 🙂 Então vamos copiar o nosso /usr/bin/mc para o nosso FreeBSD e colocá-lo em /compat/linux/usr/bin/.

Reparem que toda a estrutura que o programa usará ficará embaixo de /compat/linux como se ele fosse a raiz para os binários que executaremos.

Antes de mais nada vamos precisar dizer ao FreeBSD que esse binário se trata de um binário ELF Linux e para isso vamos fazer apenas o seguinte:

# brandelf -t Linux /compat/linux/usr/bin/mc

Vou tentar rodar /compat/linux/mc e ver que erros pegarei:

# /compat/linux/usr/bin/mc
/compat/linux/usr/bin/mc: error while loading shared libraries: libgpm.so.2: cannot open shared object file: No such file or directory

Opa! Ele reclamou da libgpm.so.2 que na verdade é um link simbólico para libgpm.so.2.0.0. Vamos então copiar do Ubuntu a lib /usr/lib/libgpm.so.2.0.0 para o FreeBSD em /compat/linux/usr/lib e executar:

# cd /compat/linux/usr/lib
# ln -sf libgpm.so.2.0.0 libgpm.so.2

Depois disso vamos rodá-lo novamente e veremos algo assim:

Tem algo errado ainda porque a tela deveria estar com fundo azul e os gráficos certos. Bem, vamos sair com F10 e ver se aparece algum erro:

# /compat/linux/usr/bin/mc
Warning: file /etc/mc/extfs/extfs.ini not found
Warning: file /etc/mc/extfs/sfs.ini not found
Warning: file /etc/mc/mc.charsets not found
Warning: file /usr/share/mc/mc.charsets not found

 

Ummm podemos deduzir então que faltam algumas coisas como o /etc/mc e o /usr/share/mc que estão lá no Ubuntu. Para resolver isso pegaremos o conteúdo de cada diretório e colocaremos eles em /compat/linux/etc/mc e /compat/linux/usr/share/mc.

Feito isso agora sim rodaremos o nosso /compat/linux/usr/bin/mc e veremos a tela certa e sem erros:

Bem é isso pessoal, para mais informações vocês podem consultar o Handbook aqui.

Para fazer o mesmo em um FreeBSD 64 bits existem algumas coisas que precisam ser feitas. Aqui está uma página, embora antiga, boa para consultar sobre rodando binários 32 bits do Linux em FreeBSD 64 bits.

Be happy!!

 

Share Button

Comments (2)

Oi Gondim! Para fazer cross compiling de um programa feito no Free para Linux, o modo de compatibilidade teria que estar habilitado ou só se eu for rodar o binário dele? Valeu!

No caso você está querendo fazer o inverso? Rodar um binário ELF do FreeBSD no Linux?
Se for isso acredito que não. Pelo menos não vi até hoje alguém rodando assim. Porque veja, no FreeBSD foi feito um trabalho em cima do binário de identificar ele e criar um ambiente onde ele pudesse rodar. Mesmo assim nem todo binário Linux rodaria devido à algumas diferenças estruturais. Por exemplo eu tentei rodar o iptraf, mas não consegui que ele ouvisse na em0 do FreeBSD. Deu erro de raw socket. O programa abriu mas não identificou a em0.

Write a comment

*