没有用于启动挂载的公共 KPI,我什至不知道com.apple.kpi.private
. 然而,在用户空间中,您可以使用的不仅仅是 DiskImages.framework:还有 . DiskArbitration.framework
,当然还有mount(2)
.
我认为您可能在这里混淆了 2 个概念,它们实际上是完全独立的:
- 打开磁盘映像并创建虚拟块设备以访问其内容
- 在块设备上挂载文件系统。
磁盘映像支持不是 xnu 内核的固有部分。它们在IOHDIXController
对象中实现(此代码在 kext 中),您可以IOResources
在 IORegistry 中找到附加的对象。当用户双击 .dmg 文件或类似文件时,diskimages-helper
守护程序会打开并解析它并指示 IOHDIXController 创建一个新IODiskImageBlockStorageDeviceOutKernel
实例(IOBlockStorageDevice
子类)。这对操作系统来说就像一个物理块设备,通常的IOBlockStorageDriver
-> IOMedia
-> IOPartitionScheme
-> IOMedia
->IOMediaBSDClient
对象堆栈在它之上配置自己。然后这会导致设备发现事件在 中触发diskarbitrationd
,这将进入过程的第二部分:适当地调用mount(2)
新发现的IOMedia
对象的/dev/diskXsY
节点。
据我所知,HDIX 子系统尚未开放。因此,如果您想实现自己的磁盘映像格式,则需要重新创建类似于 Applediskimage-helper
和IOHDIXController.kext
. 如果您愿意,您可能可以完全在内核中实现它,尽管这可能不是一个好主意。
第二部分,挂载,如果您使用 IOStorage 堆栈,则由 diskarbitrationd 自动完成,但您可以通过磁盘仲裁异议者来影响它。有关详细信息,请参阅 DiskArbitration.framework。但这也可以让您影响由 处理的磁盘映像的挂载diskimages-helper
,因此如果您使用它支持的映像格式,则无需编写自己的,并且可以简单地拦截挂载并自己做任何您想做的事情.
您也可以完全绕过 IOStorage 堆栈,只在您的 kext 中创建 BSD 开发节点。在这种情况下,disarbitrationd 不应该注意到它,您需要mount()
从您的守护程序显式调用。
我希望这能澄清事情。