在 Mac OS X 上打开磁盘设备文件进行写访问

2024-01-19

我正在尝试对 Mac 上的磁盘分区表进行细微修改;特别是,我需要更改分区的类型。diskutil不支持这个,所以我不能使用它。它工作正常(例如通过修改gpt命令行实用程序)(如果磁盘未使用)。如果是,则打开设备文件失败:

int fd = open("/dev/disk1", O_RDWR);

fd是 -1 并且errno指示错误“资源繁忙”。

我意识到我可以从不同的驱动器重新启动机器,从那里修改原始磁盘,然后重新启动。然而,从我的应用程序内部实现自动化/可靠并不容易。除了,diskutil编辑实时设备的分区表没有问题,bootcamp 安装程序也没有问题。

有已知的方法可以做到这一点吗?最坏的情况是,我可以尝试在内核中执行此操作,但 kext 并不是真正为执行一次性操作而设计的,而且我需要做的事情在用户空间中实际上在概念上非常简单,但在内核中却相当困难。

有任何想法吗?

Note:我正在运行一切sudo,所以应该不是权限问题。


苹果是如何做到的

经过一番侦查后otool和一个反汇编程序,我确定苹果的diskutil使用一些私有框架来完成这项工作。 (我查看了命令行版本,但 GUI 的功能集和状态/错误消息磁盘工具匹配得如此接近,我怀疑是否有区别)特别是 Objective-CDiskManagement.framework包含 1:1 映射到的类和方法diskutil命令。很多错误消息似乎来自MediaKit.framework,它不是基于 Objective-C 的,因此它的 API 在以下位置不可见otool.

简单看一下部分功能的反汇编,看来Mach Ports和MIG被大量使用。我不知道逆向工程的兔子洞有多深,也不知道它是否会带来任何有用的东西。毕竟,DiskManagement.framework似乎确实做了什么diskutil确实如此,仅此而已,因此不包括直接编辑分区表。即使我弄清楚它在幕后是如何工作的,这也可能无法帮助我解决我的问题。

我是怎么做的

因此,为了避免在成功机会存疑的活动上浪费更多时间,我最终通过内核扩展来完成这件事,这正是我试图避免的。我基本上建立了一个通用的IOService子类以及IOUserClient同伴子类。这向以 root 身份运行的用户空间进程公开了一些用新分区表替换现有分区表的方法。它搜索IOMedia与设备名称相对应的对象,并通过一些技巧,直接对其进行读/写操作。我将旧的分区表传递给它,以便它可以验证它确实更新了正确的内容。在用户空间方面,我修改了gpt使用用户空间 I/O Kit 库与 kext 对话的实用程序。我只是暂时加载 kext 进行更改,然后再次卸载。我花了两天的时间,但效果很好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Mac OS X 上打开磁盘设备文件进行写访问 的相关文章

随机推荐