Kernel de 64 bits, mas todos os processos executáveis ​​ELF de 32 bits, como é isso?

9

A saída de uname:

root@debian:~ # uname -a
Linux 5asnb 2.6.32-5-amd64 #1 SMP Mon Jun 13 05:49:32 UTC 2011 x86_64 GNU/Linux

No entanto, o /sbin/initexecutável aparece como 32 bits:

root@debian:~ # file /sbin/init
/sbin/init: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped

Outros aspectos do sistema parecem contradizer as coisas também:

root@debian:~ # echo $HOSTTYPE
i486

root@debian:~ # getconf LONG_BIT
32
kiiwii
fonte

Respostas:

13

O kernel de 64 bits pode ser instalado no Debian 32bit. Você pode ver que o kernel amd64 está disponível para o Debian de 32 bits na página do pacote . Isso pode ser usado como uma alternativa ao uso de um kernel habilitado para PAE para suportar mais de 4G do total de RAM. Observe que os binários de 32 bits ainda não podem acessar mais do que aproximadamente 3G de RAM por processo.

jordanm
fonte
valeu! suas respostas são tão claras quanto uma bola de cristal ~: D Nunca notei que o Debian tratasse o pacote do kernel como este antes.
precisa saber é
1
Isso não é verdade: os programas de 32 bits podem usar todo o 4Gio de seu espaço de endereço virtual quando executados em um kernel de 64 bits (a menos que estejam executando com a personalidade ADDR_LIMIT_3GB).
ysdx
@ysdx Portanto, limitar a 2 GB é algo específico do Windows e endereços acima de 0x80000000 serão permitidos no espaço do usuário de 32 bits?
Paul Stelian
1
@PaulStelian, No Windows de 32 bits, você está limitado, por padrão, aos 2 GB de memória virtual mais baixa para compatibilidade retroativa (acho que alguns programas costumavam reservar ponteiros para os 2 GB de memória virtual mais altos para fins especiais). Você pode definir o sinalizador LARGEADDRESSAWARE em seu executável ( docs.microsoft.com/fr-fr/cpp/build/reference/… ) para ativar o acesso a todos os 4 GB de memória virtual.
ysdx 3/09/19
15

Todos os processadores que suportam o conjunto de instruções x64 (também conhecido como x86_64 ou amd64) também suportam o conjunto de instruções x86 (também conhecido como i386 ou i686, que são estritamente versões específicas do x86). O mesmo vale para o ARM A64 (o novo conjunto de instruções de 64 bits que aparece no ARMv8) e o A32 (o nome do conjunto de instruções "clássico" de 32 bits), para o SPARC64 e SPARC , e acredito para o MIPS64 e o MIPS . Portanto, em todas essas famílias de arquitetura, se um processador pode executar código de 64 bits, também pode executar código de 32 bits.

O kernel Linux suporta a execução de código de usuário de 32 bits com um kernel de 64 bits (em todas as famílias de arquitetura mencionadas acima, eu acho). O kernel deve ser homogêneo (todos os de 64 ou 32 bits) e cada processo deve ser homogêneo, mas você pode ter uma mistura de processos de 32 e 64 bits em um kernel de 64 bits. O inverso não é possível: com um kernel de 32 bits, você não pode executar processos de 64 bits.

Essa é uma opção de design no Linux, motivada pelo desejo de executar binários de 32 bits existentes em instalações de 64 bits. Outras variantes do Unix fizeram escolhas diferentes: o Solaris pode executar programas de 64 bits em um kernel de 32 bits e vice-versa, enquanto o OpenBSD não pode executar programas de 32 bits em um kernel de 64 bits.

Você pode obter informações sobre o CPU no /proc/cpuinfo. Se a sua CPU x86 tem o lmsinalizador, é uma CPU de 64 bits.

Por padrão, uname -mou archmostra a arquitetura para a qual o kernel foi compilado. O Linux pode definir a "personalidade" de um processo (com a personality) chamada do sistema. Você pode executar um subprocesso com uma personalidade diferente com o setarchcomando; setarch i686 someprogramou linux32 someprogramexecuta o programa especificado em um ambiente onde uname -mos retornos i686, enquanto setarch amd64 someprogramou linux64 someprogramexecuta o programa especificado em um ambiente onde uname -mos retornos amd64.

file /sbin/initinforma para qual arquitetura o initprograma é compilado. Embora seja possível misturar executáveis ​​de 32 e 64 bits em uma instalação, geralmente todos os programas principais do SO são da mesma arquitetura, porque é muito mais fácil de gerenciar.

$HOSTYPEé uma variável bash e indica para qual arquitetura o bashprograma foi compilado.

getconf LONG_BITpermite saber se o compilador C padrão está configurado para compilar programas de 32 ou 64 bits. Um teste mais preciso é compilar e executar um programa que imprima sizeof(void*)ou sizeof(size_t)- chamar getconfsó pode fornecer informações sobre o que getconfpensa ser o compilador padrão.

Gilles 'SO- parar de ser mau'
fonte
1
De fato, o Solaris de 32 bits muda para o modo de 64 bits para passar para o processo de 64 bits e depois voltar? Isso deve ter uma enorme sobrecarga e simplesmente não faz sentido, porque o kernel é efetivamente de 64 bits.
Ruslan
1
@Ruslan Por que isso teria uma enorme sobrecarga? Alternar modos em uma alternância de contexto não custa muito (se é que sei, eu não conheço x86 em um nível baixo o suficiente). O kernel permanece 32 bits: endereços virtuais de 32 bits para mapeamentos do kernel, uso de 32 bits do conjunto de instruções.
Gilles 'SO- stop be evil'
1
O kernel deve manter algumas estruturas de dados específicas de 64 bits para suportar aplicativos de 64 bits, pelo menos tabelas de páginas com reconhecimento de 64 bits. Isso faz com que não seja realmente um kernel de 32 bits. Eu não tentei me aprofundar muito no arco amd64, mas acho que desligar o suporte de 64 bits terá uma sobrecarga considerável em contraste com o uso do modo de compatibilidade especialmente projetado.
Ruslan
1
@Ruslan Apenas tabelas de páginas com reconhecimento de 64 bits e realmente necessárias, e é um custo pequeno. Tudo o mais pode ser evitado com o design correto do kernel. Nunca mergulhei no kernel Solaris, presumo que eles tenham organizado para torná-lo flexível o suficiente (eles tinham experiência anterior com o SPARC64).
Gilles 'SO- stop be evil'