![64位内核,但运行的都是32位ELF可执行进程,这是怎么回事?](https://linux22.com/image/37584/64%E4%BD%8D%E5%86%85%E6%A0%B8%EF%BC%8C%E4%BD%86%E8%BF%90%E8%A1%8C%E7%9A%84%E9%83%BD%E6%98%AF32%E4%BD%8DELF%E5%8F%AF%E6%89%A7%E8%A1%8C%E8%BF%9B%E7%A8%8B%EF%BC%8C%E8%BF%99%E6%98%AF%E6%80%8E%E4%B9%88%E5%9B%9E%E4%BA%8B%EF%BC%9F.png)
输出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
答案1
所有支持的处理器x64指令集(也称为 x86_64 或 amd64)也支持x86指令集(也称为 i386 或 i686,严格来说是 x86 的特定版本)。同样适用于手臂A64(ARMv8 中出现的新 64 位指令集)和 A32(“经典”32 位指令集的名称),用于SPARC64和斯帕克,我相信对于MIPS64和米普斯。因此,在所有这些架构系列中,如果处理器可以运行 64 位代码,那么它也可以运行 32 位代码。
Linux 内核支持在 64 位内核上运行 32 位用户态代码(我认为在上述所有架构系列上)。内核必须是同类的(全部 64 位或全部 32 位),并且每个进程必须是同类的,但您可以在 64 位内核上混合使用 32 位和 64 位进程。反之则不可能:使用 32 位内核,无法运行 64 位进程。
这是 Linux 中的一个设计选择,其动机是希望在 64 位安装上运行现有的 32 位二进制文件。其他 Unix 变体做出了不同的选择:Solaris 可以在 32 位内核上运行 64 位程序,反之亦然,而 OpenBSD 不能在 64 位内核上运行 32 位程序。
你可以得到有关CPU的信息在/proc/cpuinfo
。如果您的 x86 CPU 有该lm
标志,则它是 64 位 CPU。
默认情况下,uname -m
或arch
显示内核编译的体系结构。 Linux 可以设置进程的“个性”(使用personality
) 系统调用。您可以使用以下命令以不同的个性运行子流程setarch
命令; setarch i686 someprogram
or在返回的linux32 someprogram
环境中运行指定的程序,而或在返回的环境中运行指定的程序。uname -m
i686
setarch amd64 someprogram
linux64 someprogram
uname -m
amd64
file /sbin/init
告诉您程序init
是为什么架构编译的。尽管可以在安装中混合使用 32 位和 64 位可执行文件,但通常所有核心操作系统程序都来自同一体系结构,因为这样更容易管理。
$HOSTYPE
是一个 bash 变量,告诉您程序bash
是为什么架构编译的。
getconf LONG_BIT
让您知道默认的 C 编译器是否设置为编译 32 位或 64 位程序。更精确的测试是编译并运行一个打印sizeof(void*)
或sizeof(size_t)
- 调用的程序getconf
只能提供有关getconf
默认编译器的信息。
答案2
64位内核可以安装在Debian 32位上。您可以看到 amd64 内核可用于 32 位 Debian包装页。这可以作为使用启用 PAE 的内核的替代方案来支持超过 4G 的总 RAM。请注意,32 位二进制文件仍然无法访问每个进程超过大约 3G 的 RAM。