# kldload linux
Capítulo 10. Compatibilidade binária com o Linux®
Esta tradução pode estar desatualizada. Para ajudar com as traduções, acesse a ferramenta de traduções do FreeBSD.
Índice
10.1. Sinopse
O FreeBSD fornece compatibilidade binária com o Linux™, permitindo que os usuários instalem e executem a maioria dos binários do Linux™ em um sistema FreeBSD sem ter que primeiro modificar o binário. Foi até relatado que, em algumas situações, os binários Linux™ têm melhor desempenho no FreeBSD do que no Linux™.
No entanto, alguns recursos do sistema operacional específicos do Linux™ não são suportados no FreeBSD. Por exemplo, os binários Linux™ não funcionarão no FreeBSD se usarem chamadas específicas i386™, mesmo ativando o modo 8086 virtual.
O suporte para compatibilidade binária de 64 bits com o Linux™ foi adicionado no FreeBSD 10.3. |
Depois de ler este capítulo, você saberá:
Como habilitar a compatibilidade binária com o Linux™ em um sistema FreeBSD.
Como instalar bibliotecas compartilhadas adicionais do Linux™.
Como instalar aplicativos Linux™ em um sistema FreeBSD.
Os detalhes de implementação da compatibilidade com o Linux™ no FreeBSD.
Antes de ler este capítulo, você deve:
Saiber como instalar software adicional de terceiros.
10.2. Configurando a compatibilidade binária com o Linux™
Por padrão, as bibliotecas do Linux™ não estão instaladas e a compatibilidade binária com o Linux™ não está ativada. As bibliotecas Linux™ podem ser instaladas manualmente ou a partir da coleção de Ports do FreeBSD.
Antes de tentar compilar o port, carregue o módulo de kernel Linux™, caso contrário a compilação irá falhar:
Para compatibilidade com 64 bits:
# kldload linux64
Para verificar se o módulo está carregado:
% kldstat
Id Refs Address Size Name
1 2 0xc0100000 16bdb8 kernel
7 1 0xc24db000 d000 linux.ko
O pacote ou port emulators/linux_base-c7 é a maneira mais fácil de instalar um conjunto básico de bibliotecas e binários do Linux™ em um sistema FreeBSD. Para instalar o port:
# pkg install emulators/linux_base-c7
Para que a compatibilidade com o Linux™ seja ativada durante a inicialização, adicione esta linha ao /etc/rc.conf:
linux_enable="YES"
Em máquinas de 64 bits, o /etc/rc.d/abi carregará automaticamente o módulo para emulação de 64 bits.
Como a camada de compatibilidade binária do Linux™ ganhou suporte para a execução de binários Linux™ de 32 e 64 bits (em hosts x86 de 64 bits), não é mais possível vincular estaticamente a funcionalidade de emulação a um kernel personalizado.
10.2.1. Instalando Bibliotecas Adicionais Manualmente
Se um aplicativo Linux™ reclamar sobre a falta de bibliotecas compartilhadas após configurar a compatibilidade binária do Linux™, determine quais bibliotecas compartilhadas o Linux™ precisa e instale-as manualmente.
A partir de um sistema Linux™, o ldd
pode ser usado para determinar quais bibliotecas compartilhadas o aplicativo precisa. Por exemplo, para verificar quais bibliotecas compartilhadas o linuxdoom
precisa, execute este comando a partir de um sistema Linux™ que tenha o Doom instalado:
% ldd linuxdoom
libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0
libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0
libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
Então, copie todos os arquivos listados na última coluna da saída do comando no sistema Linux™ para o diretório /compat/linux no sistema FreeBSD. Depois de copiados, crie links simbólicos para os nomes na primeira coluna. Este exemplo irá resultar nos seguintes arquivos no sistema FreeBSD:
/compat/linux/usr/X11/lib/libXt.so.3.1.0
/compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0
/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
Se uma biblioteca compartilhada Linux™ já existir com um número de revisão principal correspondente à primeira coluna da saída do comando ldd
, ela não precisará ser copiada para a arquivo nomeado na última coluna, pois a biblioteca existente deve funcionar. No entanto é aconselhável copiar a biblioteca compartilhada se for uma versão mais nova. O arquivo antigo pode ser removido, desde que o link simbólico aponte para o novo.
Por exemplo, essas bibliotecas já existem no sistema FreeBSD:
/compat/linux/lib/libc.so.4.6.27
/compat/linux/lib/libc.so.4 -> libc.so.4.6.27
e o ldd
indica que um binário requer uma versão posterior:
libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29
Como a biblioteca existente tem apenas uma ou duas versões desatualizadas no último dígito, o programa ainda deve funcionar com a versão um pouco mais antiga. No entanto, é seguro substituir o libc.so existente pela versão mais nova:
/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
Geralmente, será necessário procurar as bibliotecas compartilhadas que os binários do Linux™ dependem apenas das primeiras vezes que um programa Linux™ é instalado no FreeBSD. Depois de um tempo, haverá um conjunto suficiente de bibliotecas Linux™ compartilhadas no sistema para poder executar binários Linux™ atualizados sem qualquer trabalho extra.
10.2.2. Instalando os binários Linux™ELF
Os binários ELF requerem por vezes um passo extra. Quando um binário ELF sem marca for executado, ele gerará uma mensagem de erro:
% ./my-linux-elf-binary
ELF binary type not known
Abort
Para ajudar o kernel do FreeBSD a distinguir entre um binário do FreeBSD ELF e um binário Linux™, use brandelf(1):
% brandelf -t Linux my-linux-elf-binary
Como o conjunto de ferramentas GNU coloca as informações de branding apropriadas em binários ELF automaticamente, essa etapa geralmente não é necessária.
10.2.3. Instalando um aplicativo baseado em Linux™RPM
Para instalar um aplicativo baseado em Linux™RPM, primeiro instale o pacote ou o port archivers/rpm4. Uma vez instalado, o usuário root
pode usar este comando para instalar um .rpm:
# cd /compat/linux
# rpm2cpio < /path/to/linux.archive.rpm | cpio -id
Se necessário, use o brandelf
nos binários ELF instalados . Observe que isso impedirá uma desinstalação limpa.
10.2.4. Configurando o Resolver do Hostname
Se o DNS não funcionar ou este erro aparecer:
resolv+: "bind" is an invalid keyword resolv+:
"hosts" is an invalid keyword
configure o /compat/linux/etc/host.conf como segue:
order hosts, bind multi on
Isso especifica que o /etc/hosts deve ser pesquisado primeiro e o DNS deve ser pesquisado em segundo lugar. Quando o /compat/linux/etc/host.conf não existe, os aplicativos Linux™ usam o /etc/host.conf e avisam sobre a sintaxe incompatível do FreeBSD. Remova o bind
se um servidor de nomes não estiver configurado usando o /etc/resolv.conf.
10.3. Tópicos Avançados
Esta seção descreve como funciona a compatibilidade binária com o Linux™ e é baseada em um email escrito para Lista de discussão do chat do FreeBSD por Terry Lambert tlambert@primenet.com (Message ID: <199906020108.SAA07001@usr09.primenet.com>
).
O FreeBSD tem uma abstração chamada "loader de classes de execução". Esta é uma cunha na chamada de sistema execve(2) .
Historicamente, o loader UNIX™ examinava o número mágico (geralmente os primeiros 4 ou 8 bytes do arquivo) para ver se era um binário conhecido pelo sistema e, em caso afirmativo, invocava o loader binário.
Se o arquivo não fosse o tipo binário adequado para o sistema, a chamada execve(2) retornava uma falha, e o shell tentava iniciar a execução do mesmo como um comando do shell. A suposição era um padrão de "qualquer que seja o shell atual".
Posteriormente, foi feito um hack para que o sh(1) examinasse os dois primeiros caracteres e se eles fossem :\n
, ele invocava o shell csh(1) em seu lugar.
O FreeBSD tem uma lista de loaders, em vez de um único loader, com um fallback para o loader #!
para executar interpretadores de shell ou scripts de shell.
Para o suporte ao Linux™ABI, o FreeBSD vê o número mágico como um binário ELF. O loader ELF procura por uma marca especializada, que é uma seção de comentários na imagem ELF e que não esteja presente nos binários ELF SVR4/Solaris™.
Para que os binários Linux™ funcionem, eles devem ser marcados como tipo Linux
usando o comando brandelf(1):
# brandelf -t Linux file
Quando o loader ELF vê a marca Linux
, ele substitui um ponteiro na estrutura proc
. Todas as chamadas do sistema são indexadas por esse ponteiro. Além disso, o processo é sinalizado para manipulação especial do vetor trap para o código de trampolim de sinal, e vários outros (menores) reparos que são manipulados pelo módulo do kernel Linux™.
O vetor de chamada do sistema Linux™ contém, entre outras coisas, uma lista de entradas sysent[]
cujos endereços residem no módulo do kernel.
Quando uma chamada de sistema é acionada pelo binário Linux™, o código de interceptação desreferencia o ponteiro de função de chamada do sistema da estrutura proc
e obtém a classe Linux™, não a FreeBSD, como ponto de entrada para a chamada do sistema.
O modo Linux™ procura fazer reroots dinamicamente. Isso é, na verdade, equivalente ao union
para montagens de sistema de arquivos. Primeiro, é feita uma tentativa de procurar o arquivo em /compat/linux/original-path. Se isso falhar, a pesquisa será feita em /original-path. Isso garante que os binários que exigem outros binários possam ser executados. Por exemplo, o conjunto de ferramentas Linux™ pode ser executado sob o suporte da Linux™ABI. Isso também significa que os binários Linux™ podem carregar e executar binários do FreeBSD, se não houver binários Linux™ correspondentes, e que o comando uname(1) pode ser colocado na árvore de diretórios /compat/linux para garantir que os binários Linux™ não possam dizer que não estão rodando em Linux™.
De fato, existe um kernel Linux™ no kernel do FreeBSD. As várias funções subjacentes que implementam todos os serviços fornecidos pelo kernel são idênticas às entradas da tabela de chamada do sistema FreeBSD, e às entradas da tabela de chamada do sistema Linux™: operações do sistema de arquivos, operações de memória virtual, entrega de sinal e System V IPC. A única diferença é que os binários do FreeBSD obtêm as funções de cola do FreeBSD, e os binários Linux™ recebem as funções de cola do Linux™. As funções de cola do FreeBSD estão estaticamente ligadas ao kernel, e as funções de cola do Linux ™ podem ser estaticamente ligadas, ou podem ser acessadas através de um módulo do kernel.
Tecnicamente, isso não é realmente emulação, é uma implementação de ABI. Às vezes é chamado de "emulação™ Linux " porque a implementação foi feita num momento em que não havia outra palavra para descrever o que estava acontecendo. Dizer que o FreeBSD executava os binários do Linux™ não era verdade, já que o código não era compilado nele.
Última alteração em: 9 de março de 2024 por Danilo G. Baio