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 à opção union
para montagens de sistema de arquivos. Primeiro, é feita uma tentativa de procurar o arquivo em /compat/linux/
. 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 original-path
/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.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.