mach_vm_allocate
と の違いを知りたいvm_allocate
です。OS X でのみ利用でき、iOS では利用できないことはわかっmach_vm_allocate
ていますが、その理由はわかりません。関数のすべての関数プロトタイプを含むファイルmach_vm_...
は、iOS に(mach/mach_vm.h)
のみあります。#error mach_vm.h unsupported.
4 に答える
Mac OS X 10.4 で導入された新しい Mach VM API。新しい API は、プログラマーの観点から見ると、基本的に古い API と同じですが、次の主な違いがあります。
-ルーチン名には mach_ プレフィックスが付いています。たとえば、vm_allocate() は mach_vm_allocate() になります。
- ルーチンで使用されるデータ型が更新され、64 ビットと 32 ビットの両方のタスクがサポートされるようになりました。したがって、新しい API はあらゆるタスクで使用できます。
新しい API と古い API は、それぞれ異なる MIG サブシステム ( mach_vm と vm_map ) によってエクスポートされます。対応するヘッダー ファイルは、それぞれ <mach/mach_vm.h> と <mach/vm_map.h> です。
Mac OS X 10.4 で導入された新しい Mach VM API。新しい API は、プログラマーの観点からは基本的に古い API と同じですが、次の主な違いがあります。
ルーチン名には
mach_ prefixfor
例vm_allocate()
がmach_vm_allocate()
あります。ルーチンで使用されるデータ型が更新され、64 ビットと 32 ビットの両方のタスクがサポートされるようになりました。したがって、新しい API はあらゆるタスクで使用できます。
mach_vm
新しい API と古い API は、それぞれ異なる MIG サブシステムによってエクスポートされますvm_map
。対応するヘッダー ファイルは<mach/mach_vm.h>
、<mach/vm_map.h>
それぞれ と です。
この情報は、本OS X Internals A System Approachから得られたものです。
私は他の答えに満足していません。2 つは同じ情報源から引用しているようで (1 つは正しく帰属していません)、この情報源は誤解を招きます。
古い APIのデータ型は可変サイズです。i386 CPU アーキテクチャ用にコンパイルしている場合は 32 ビットであり、x86_64 CPU アーキテクチャ用にコンパイルしている場合は 64 ビットです。
新しい APIのデータ型は固定サイズで、常に 64 ビットです。
32 ビット プロセスは 32 ビット データ型のみを必要とし、64 ビット プロセスは古い API でも既に 64 ビット型を持っているため、新しい API が必要な理由はまったく明らかではありません。しかし、Apple のカーネル設計を見れば明らかです。
macOS の実際のカーネルはMach 3マイクロ カーネルです。マイクロ カーネルであるため、プロセスとスレッドの管理、IPC、仮想メモリの管理、およびプロセス/スレッドのスケジューリングのみを処理します。それでおしまい。通常、マイクロカーネルを使用する場合、他のすべてはユーザー空間で行われますが、それは遅いため、Apple は別のアプローチを採用しました。
Apple は FreeBSD モノリシック カーネルを採用し、FreeBSD カーネルを特別な特権を持つ単一のプロセス (タスク) として実行するマイクロ カーネルにラップしました (タスクであるにもかかわらず、コードはユーザー空間ではなくカーネル空間内で実行されます。システム)。結合されたカーネルの名前はXNUです。
以前は、Apple はシステム内で 32 ビットと 64 ビットを混在させる任意の組み合わせをサポートしていました。システムで 32 ビット カーネルを実行し、その上で 32 ビットまたは 64 ビットのプロセスを実行することも、64 ビット カーネルを実行し、32 ビットまたは 64 ビットを実行することもできました。その上で処理します。あなたはすでにこれがどこに向かっているのかを見ているかもしれませんね.
プロセスとカーネルのビット幅が異なる場合、古い API は役に立ちません。たとえば、API 呼び出しのすべてのデータ型は 32 ビット カーネル タスクでは 32 ビットのみになるため、32 ビット カーネルは 64 ビット プロセスのメモリと対話するためにそれを使用できませんが、64 ビット プロセスには 64 ビット メモリ空間があります。カーネル自体が持っていない場合。
実際には、その API の 3 番目のバージョンさえあります。Apple のカーネル ソースからのコメントを引用するには:
* 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 をユーザー空間でのみ使用し、古いプロセスのメモリ管理にのみ使用している限り、64 ビット プロセスの場合でも、すべてのデータ型が 64 ビットになるため、古い API を使用しても問題ありません。
新しい API が必要になるのは、プロセスの境界を越えて作業する場合と、両方のプロセスが 32 ビットまたは 64 ビットであることが確実でない場合のみです。ただし、Apple はずっと前に 32 ビット カーネルのサポートを終了しました。その間、すべてのシステム ライブラリは 10.15 (Catalina) から 64 ビット ライブラリとしてのみ出荷されるため、32 ビット ユーザー空間のサポートも終了しました。
iOS では、iOS 用のカーネル コードを書くことができず、iOS のセキュリティの概念により、他のプロセス空間との直接的なやり取りが禁止されているため、新しい API は必要ありませんでした。iOS では、その API を使用して独自のプロセス空間とやり取りすることしかできません。そのため、常に正しいデータ型になります。