我正在尝试对Mac上的磁盘分区表进行微妙的修改; 特别是,我需要更改分区的类型.diskutil不支持这个,所以我不能使用它.gpt如果磁盘未使用,它可以正常工作(例如,通过修改的命令行实用程序).如果是,则在打开设备文件时失败:
int fd = open("/dev/disk1", O_RDWR);
Run Code Online (Sandbox Code Playgroud)
fd为-1并errno指示错误"资源忙".
我意识到我可以从不同的驱动器重启机器,从那里修改原始磁盘,然后重新启动.但是,从我的应用程序内部实现自动化/可靠性并不容易.此外,diskutil编辑实时设备的分区表没有问题,也没有bootcamp安装程序.
有没有一种已知的方法来做到这一点?最糟糕的情况是,我可以尝试在内核中执行此操作,但是kexts并非真正用于执行一次性操作,而我需要做的事情在用户空间中非常简单,但在内核中却相当困难.
有任何想法吗?
注意:我正在运行所有内容sudo,因此它不应该是权限问题.
经过一些调查otool和反汇编,我确定Apple diskutil使用一些私有框架来完成这项工作.(我查看了命令行版本,但GUI 磁盘工具的功能集和状态/错误消息与它非常接近,我怀疑是否存在差异)特别是,Objective-C DiskManagement.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进行更改,然后再次卸载它.它花了我2天的最佳时间,但效果很好.
| 归档时间: |
|
| 查看次数: |
4305 次 |
| 最近记录: |