2015-04-01 27 views
1

我的问题根本出版IOMedia:没有简而言之IOBlockStorageDevice

是它KEXT可接受/常见的做法是发布不具有IOBlockStorageDevice在其供应商栈的IOMedia对象?

背景:

我写一个内核扩展,将提供某种形式的虚拟设备到用户空间。 目前我有一个与IOResources相匹配的驱动程序,然后创建一个派生自IOMedia的类的对象并将其附加到'this'。这个媒体对象发布后,标准IOMediaBSDClient附加到它并在/ dev /中创建一个节点。

第一次测试通过,我可以成功地打开创建的设备并从中读取数据,但是当我尝试使用本地FS驱动程序安装它时,我偶然发现了一个问题。设备安装成功,挂载点可浏览,但在此之后的一段时间内,由于vfs代码内部存在段错误,导致内核崩溃。

长时间的调试后,我发现了问题的根源:

  1. IOMediaBSDClient通过这些设备提供和组合,所有的媒体对象通过媒体父母IOBlockStorageDevice对象迭代,然后迭代实现DKIOCGETTHROTTLEMASK IOCTL其BSD单元编号为位掩码。由于我的介质没有任何IOBlockStorageDevice父项,因此生成的掩码为0.
  2. 由此ioctl返回的值由vfs_init_io_attributes()用于填充对应于我的装载的mp struct的mnt_throttle_mask字段。
  3. 在此之后,mnt_throttle_mask被转换为mnt_devbsdunit,通过计算它后面的零。由于在我的情况mnt_throttle_mask是0,mnt_devbsdunit变得64.
  4. mnt_devbsdunit用于通过spec_strategy(和与节流处理一些其他功能)为_throttle_io_info的元件数目,这是LOWPRI_MAX_NUM_DEV元件和LOWPRI_MAX_NUM_DEV的阵列是等于64。 显然,访问_throttle_io_info的64元素会抛出刚好在它后面的数据,在我的情况下是speclisth数组。

此刻,我看到2种方式在我的代码来解决这个问题: 1.实现从IOMediaBSDClient派生的类将corrrectly处理DKIOCGETTHROTTLEMASK IOCTL。 2.重写代码以发布IOBlockStorageDevice对象,并让标准IOBlockStorageDriver发布Media对象。

就我个人而言,我更喜欢第一个解决方案,但我遇到的问题似乎相当顽固,我无法摆脱我正在做一些根本性错误的想法。

我想避免将来出现这样的问题,因此我在问这个问题。

编辑:至少对于OS X 10.8.3和10.8.5是这样。我还没有在其他版本上测试过。

回答

0

我可能会去与IOBlockStorageDevice子类。我用这种方式编写了几个驱动程序,并且从未遇到任何问题。直接IOStorage/IOMedia驱动程序适用于“过滤”驱动程序(逻辑卷管理,RAID,加密等)。 - 任何位于“真实”块设备上的东西),但正如您发现的那样,操作系统的某些区域预计会有一个基金会。

IOStorage转换为IOBlockStorageDevice非常简单:方法名称以“do”或“report”为前缀,在语义上几乎完全相同。从长远来看,它可能会为您节省一些麻烦。不要自己创建IOBlockStorageDriver对象 - 一旦在IOBlockStorageDevice子类实例上调用registerService(),I/O Kit匹配将为您创建IOBlockStorageDriver对象。

有一些例子左右浮动,其中包括一个非常简单的一个在书中OS X and iOS[sic] Kernel Programming - 即使你没有这本书呢,你可以得到示例代码here - 第14章

+0

谢谢您的回答。我将代码转换为IOBlockStorageDevice子类,现在它工作正常。 无论如何,它似乎是这种情况下唯一的选择,因为经过一番调查后,我发现不能简单地在IOMediaBSDClient中重新实现DKIOCGETTHROTTLEMASK ioctl,因为它直接在dkioctl函数中处理。 – 2015-04-04 12:13:07

+0

很高兴你把它全部整理出来!我以前没有意识到DKIOCGETTHROTTLEMASK的问题,你每天都会学到新的东西。 :-) – pmdj 2015-04-04 21:56:29

相关问题