web-dev-qa-db-ja.com

64ビットカーネルですが、すべての32ビットELF実行可能プロセスを実行していますが、どうですか?

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

しかし /sbin/init実行可能ファイルは32ビットとして表示されます。

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

システムの他の側面も同様に矛盾しているようです:

root@debian:~ # echo $HOSTTYPE
i486

root@debian:~ # getconf LONG_BIT
32
9
kiiwii

64ビットカーネルは、Debian 32ビットにインストールできます。 AMD64カーネルは パッケージページ で32ビットDebianに対応しています。これは、PAE対応カーネルを使用して4G以上の合計RAMをサポートする代わりに使用できます。 32ビットのバイナリは、プロセスあたり約3G以上のRAM)にアクセスできないことに注意してください。

13
jordanm

x64 命令セット(x86_64またはAMD64とも呼ばれる)をサポートするすべてのプロセッサは x86 命令セット(i386またはi686とも呼ばれます)もサポートします。 x86の)。同じことが [〜#〜] arm [〜#〜] A64(ARMv8に登場する新しい64ビット命令セット)とA32(「クラシック」32ビット命令セットの名前) )、 SPARC64 および [〜#〜] sparc [〜#〜] の場合、および MIPS64 および [〜 #〜] mips [〜#〜] 。したがって、これらすべてのアーキテクチャファミリで、プロセッサが64ビットコードを実行できる場合、32ビットコードも実行できます。

Linuxカーネルは、64ビットカーネルでの32ビットユーザーランドコードの実行をサポートします(上記のすべてのアーキテクチャファミリーで)。カーネルは同種(すべて64ビットまたはすべて32ビット)である必要があり、各プロセスは同種である必要がありますが、64ビットカーネルで32ビットと64ビットのプロセスを混在させることができます。逆は不可能です。32ビットカーネルでは、64ビットプロセスを実行できません。

これは、64ビットインストールで既存の32ビットバイナリを実行したいという欲求に動機づけられた、Linuxの設計上の選択です。他のUnixバリアントは異なる選択をしました:Solarisは32ビットカーネルで64ビットプログラムを実行でき、その逆も可能ですが、OpenBSDは64ビットカーネルで32ビットプログラムを実行できません。

_/proc/cpuinfo_で CPUに関する情報 を取得できます。 x86 CPUにlmフラグがある場合、それは64ビットCPUです。

デフォルトでは、_uname -m_またはArchは、カーネルがコンパイルされたアーキテクチャを示します。 Linuxは、プロセスの「パーソナリティ」を( personality を使用して)システムコールに設定できます。 setarch コマンドを使用して、別のパーソナリティでサブプロセスを実行できます。 _setarch i686 someprogram_または_linux32 someprogram_は、指定されたプログラムを_uname -m_が_i686_を返す環境で実行し、_setarch AMD64 someprogram_または_linux64 someprogram_は、指定されたプログラムを実行する環境で実行します_uname -m_は_AMD64_を返します。

_file /sbin/init_は、initプログラムがコンパイルされたアーキテクチャを示します。インストール内で32ビットと64ビットの実行可能ファイルを混在させることは可能ですが、通常、すべてのコアOSプログラムは同じアーキテクチャのものです。管理がはるかに簡単だからです。

_$HOSTYPE_はbash変数であり、bashプログラムがコンパイルされたアーキテクチャを示します。

_getconf LONG_BIT_は、デフォルトのCコンパイラが32ビットプログラムと64ビットプログラムのどちらをコンパイルするように設定されているかを示します。より正確なテストは、sizeof(void*)またはsizeof(size_t)を出力するプログラムをコンパイルして実行することです。getconfを呼び出すと、getconfが何を考えているかに関する情報しか得られませんデフォルトのコンパイラです。