Skip to content

userdata 布局 ​

userdata 分区承载 Darwin 根文件系统。UniXNU 保留原始磁盘镜像不变,并添加 manifest 把每个镜像映射到分区窗口。

manifest ​

struct shngroot_header {
  char     magic[8];        /* "SHNGROOT" */
  uint32_t version;         /* 1 */
  uint32_t count;           /* 窗口数 */
  uint64_t image_bytes;     /* 镜像总大小 */
  struct {
    char     name[32];
    uint64_t offset;
    uint64_t size;
    uint32_t block_size;    /* 512 */
    uint32_t flags;         /* bit 0: 只读 */
    uint8_t  sha256[32];
    uint8_t  reserved[40];
  } window[count];
  uint8_t  reserved[32];
  uint8_t  manifest_sha256[32];
};

头部占 4096 字节,零填充到 1 MiB。第一个窗口从 0x100000 开始,每个窗口按 1 MiB 对齐。

窗口 ​

窗口IPSW 组件内容
OSOS系统卷
SystemOSCryptex1,SystemOScryptex 系统卷

镜像按字节从 IPSW 磁盘镜像复制。userdata 步骤用 hdiutil 只读挂载每个磁盘镜像并读取原始设备。

容量 ​

(last_lba - first_lba + 1) * lba_bytes

步骤拒绝超过容量的镜像。报告记录容量和镜像大小。

根卷匹配 ​

XNU 通过 /chosen/root-matching 选择根卷:

xml
<dict>
  <key>IOProviderClass</key><string>IOMedia</string>
  <key>IOPropertyMatch</key>
  <dict>
    <key>UUID</key><string>00000000-0000-0000-0000-000000000000</string>
  </dict>
</dict>

UUID 是 OS 窗口的卷 UUID。原生块驱动发布 userdata 分区,分区方案发布卷,XNU 匹配 UUID。

Data 卷 ​

可写 Data 卷独立于 userdata 镜像,来自负载中的 Data ramdisk 种子。种子是负载步骤的输入,负载报告记录其哈希。

--skip-setup 写出把 Setup 标记为完成的种子副本,副本按种子哈希缓存。

报告 ​

userdata-root.json 记录:

字段含义
image_bytes镜像总大小
image_sha256镜像哈希
manifest_sha256manifest 哈希
windows每个窗口的名称、偏移、大小和哈希
userdata_bytes分区容量
flash_commandfastboot flash userdata <image>
source本地或远程 IPSW
hardware_tested验证状态

下一步 ​

Released under the BSD-2-Clause-Patent License.