mach_vm_allocate和vm_allocate之间有什么区别?

时间:2013-02-24 07:33:54

标签: ios macos kernel mach

我想知道mach_vm_allocatevm_allocate之间的区别。我知道mach_vm_allocate仅适用于OS X而非iOS,但我不确定原因。包含mach_vm_...函数(mach/mach_vm.h)的所有函数原型的文件在iOS中只有#error mach_vm.h unsupported.

4 个答案:

答案 0 :(得分:3)

Mac OS X 10.4中引入的新Mach VM API。从程序员的角度来看,新API与旧API基本相同,但主要区别如下。

  

- 例程名称有mach_前缀,例如,vm_allocate()变为mach_vm_allocate()。

     

- 例程中使用的数据类型已更新,以支持64位和32位任务。因此,新API可以用于任何任务。

     

新旧API由不同的MIG子系统导出:   mach_vm和vm_map分别为。相应的头文件是   <马赫/ mach_vm.h>和< mach / vm_map.h>分别。

答案 1 :(得分:2)

Mac OS X 10.4中引入的新Mach VM API。从程序员的角度来看,新API基本上与旧API相同,但主要区别如下:

  • 常规名称包含mach_ prefixfor示例,vm_allocate()变为mach_vm_allocate();

  • 例程中使用的数据类型已更新,以支持64位和32位任务。因此,新API可以用于任何任务。

新旧API由不同的MIG子系统导出:mach_vmvm_map。相应的头文件分别为<mach/mach_vm.h><mach/vm_map.h>

该信息来自本书 OS X Internals A System Approach

答案 2 :(得分:1)

那些是/usr/include/mach/mach_vm.h和/usr/include/mach/vm_map.h。你可以在/ usr / include / mach中使用grep来获取它们。

在内核中,API基本上使用相同的实现。在iOS上,您可以非常好地使用“旧”API。

答案 3 :(得分:0)

我对其他答案不满意。两个似乎引用了同一个来源(一个没有正确归因),这个来源相当具有误导性。

old API 中的数据类型是可变大小的。如果您为 i386 CPU 架构编译,它们是 32 位,如果您为 x86_64 CPU 架构编译,它们是 64 位。

new API 中的数据类型是固定大小且始终为 64 位。

由于 32 位进程只需要 32 位数据类型,而 64 位进程即使使用旧 API 也已经具有 64 位类型,因此根本不清楚为什么需要新 API。但是如果你看看苹果的内核设计就会很明显:​​

macOS 的真正内核是一个 Mach 3 微内核。作为一个微内核,它只负责进程和线程管理、IPC、虚拟内存管理和进程/线程调度。而已。通常,当使用 micros 内核时,其他所有工作都会在用户空间中完成,但速度很慢,因此 Apple 采取了不同的方法。

Apple 采用 FreeBSD 单片内核并将其包裹在微内核周围,微内核将 FreeBSD 内核作为具有特殊权限的单个进程(任务)执行(尽管是任务,但代码在内核空间中运行,而不是在用户空间中运行)系统中的任务)。组合内核的名称为 XNU

在过去,Apple 支持在系统内混合 32 位和 64 位的任意组合:您的系统可以运行 32 位内核并在其上运行 32 或 64 位进程,或者它可以运行 64 位内核并运行 32或 64 位进程。您可能已经看到这是怎么回事,不是吗?

如果进程和内核的位宽不同,那么旧的 API 就没有用了。例如,32 位内核不能使用它与 64 位进程的内存交互,因为 API 调用的所有数据类型在 32 位内核任务中都只有 32 位,但 64 位进程甚至有 64 位内存空间如果内核本身没有。

实际上,该 API 甚至还有第三个版本。引用来自 Apple's kernel source 的评论:

 * There are three implementations of the "XXX_allocate" functionality in
 * the kernel: mach_vm_allocate (for any task on the platform), vm_allocate
 * (for a task with the same address space size, especially the current task),
 * and vm32_vm_allocate (for the specific case of a 32-bit task). vm_allocate
 * in the kernel should only be used on the kernel_task. vm32_vm_allocate only
 * makes sense on platforms where a user task can either be 32 or 64, or the kernel
 * task can be 32 or 64. mach_vm_allocate makes sense everywhere, and is preferred
 * for new code.

只要您仅在用户空间中使用该 API 并且仅用于旧进程的内存管理,使用旧 API 仍然可以,即使对于 64 位进程也是如此,因为在这种情况下所有数据类型都是 64 位。

新的 API 仅在跨进程边界工作时才需要,并且仅当不确定两个进程都是 32 位还是 64 位时才需要。然而,Apple 早就放弃了 32 位内核支持,同时他们也放弃了 32 位用户空间支持,因为从 10.15 (Catalina) 开始,所有系统库仅作为 64 位库提供。

在 iOS 上,从来不需要新的 API,因为您永远无法为 iOS 编写内核代码,而且 iOS 的安全概念禁止与其他进程空间直接交互。在 iOS 上,您只能使用该 API 与您自己的进程空间进行交互,因此它始终具有正确的数据类型。

相关问题