在我的 OS X 机器上,内核是 32 位二进制文​​件,但它可以运行 64 位二进制文​​件。这是如何运作的?

cristi:~ diciu$ file ./a.out
./a.out: Mach-O 64-bit executable x86_64
cristi:~ diciu$ file /mach_kernel
/mach_kernel: Mach-O universal binary with 2 architectures
/mach_kernel (for architecture i386):   Mach-O executable i386
/mach_kernel (for architecture ppc):    Mach-O executable ppc
cristi:~ diciu$ ./a.out
cristi:~ diciu$ echo $?
1
有帮助吗?

解决方案

当 CPU 陷入内核上下文时,它可以从 64 位执行模式切换到 32 位,并且仍然可以构建 32 位内核来理解从 64 位用户空间应用程序传入的结构。

无论如何,MacOS X 内核不会直接从用户应用程序取消引用指针,因为它驻留在自己单独的地址空间中。例如,ioctl 调用中的用户空间指针必须首先解析为其物理地址,然后在内核地址空间中创建新的虚拟地址。ioctl 中的指针是 64 位还是 32 位并不重要,在任何一种情况下内核都不会直接取消引用它。

因此,混合 32 位内核和 64 位二进制文​​件可以工作,反之亦然。您不能做的是将 32 位库与 64 位应用程序混合使用,因为它们之间传递的指针将被截断。MacOS X 在每个版本中都提供了更多 32 位和 64 位版本的框架。

其他提示

运行二进制文件的不是内核。这是处理器。

二进制文件确实调用库函数,并且这些函数需要是 64 位的。如果他们需要进行系统调用,他们就有责任应对这样的事实:他们本身是 64 位,但内核只有 32 位。

但这不是您需要担心的事情。

请注意,不 全部 32 位内核能够运行 64 位进程。Windows 当然没有这个属性,而且我从来没有在 Linux 上见过它。

能够加载和运行 64 位二进制文​​件的 32 位内核必须有一些 64 位代码来处理内存映射、程序加载和其他一些 64 位问题。

然而,调度程序和许多其他操作系统操作不需要在 64 位模式下工作来处理其他问题 - 它会根据需要将处理器切换到 32 位模式并返回,以处理驱动程序、任务、内存分配和映射、中断等

事实上,操作系统所做的大部分事情在 64 位上运行时不一定会执行得更快 - 操作系统不是一个重型数据处理器,并且那些部分(流、磁盘 I/O 等)可能会被转换到 64 位(无论如何都是操作系统的插件)。

但如果是 64 位的话,裸内核本身可能不会更快地进行任务切换等。

当大多数人仍在运行 32 位应用程序时尤其如此,因此并不总是需要模式切换,尽管这是一个低开销操作,但确实需要一些时间。

-亚当

ELF32 文件可以包含 64 位指令并在 64 位模式下运行。它唯一的特点是标头和符号的组织是 32 位格式。符号表偏移量为 32 位。符号表条目是 32 位宽等。同时包含 64 位代码和 32 位代码的文件可以将自身公开为 32 位 ELF 文件,其中它使用 64 位寄存器进行内部计算。mach_kernel 就是这样的一个可执行文件。它的优点是 32 位驱动程序 ELF 可以链接到它。如果它负责将位于 4GB 以下的指针传递给其他链接的 ELF 二进制文件,它将正常工作。

对于 64 位内核来说,只会带来内核扩展(即通常是驱动程序)可以是 64 位的有效优势。事实上,您需要拥有所有 64 位内核扩展,或者(就像现在的情况)所有 32 位内核扩展;它们需要原生于正在运行的内核的体系结构。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top