LwVM

LwVM (Lightweight Volume Manager) - partition table, which is used by iOS since 5.0.

com.apple.driver.LightweightVolumeManager kext wraps the block device where the actual LwVM partition table is stored and publishes   with emulated GPT which can be edited from user-land using conventional GPT editing tools (e.g. gptfdisk). All edits are trapped by the kext and before shutting down (after the volumes are unmounted) it writes the corresponding changes to LwVM partition table on  (implemented in   function from the LwVM kext). After next boot new devices (e.g. ) are published by the kext. This mechanism is used during OTA Updates to create third partition where the update ramdisk is copied to and booted into by setting nvram  to    and probably also   to   (partitions are indexed from 0, so third partition).

The update partition is set up by  (XPC service accompanying softwareupdated). It shrinks HFS of the second (data) partition using  as illustrated in hfs_resize. It then edits GPT on  to reflect the size of shrunk HFS and creates new entry for the update partition in the freed space and creates new HFS on it. To create file-system manually you can use e.g.:.

Structure
typedef struct _LwVMPartitionRecord { uint64_t type[2]; //Should be equal to LwVMPartitionTypeHFS (see below) on an unmodified device. uint64_t guid[2]; //Random. uint64_t begin; //Partitions begin in bytes. uint64_t end; //End. uint64_t attribute; // 0 == unencrypted; 0x1000000000000 == encrypted uint16_t partitionName[0x24]; // UTF-16 encoded } __attribute__ ((packed)) LwVMPartitionRecord;

typedef struct _LwVM { uint64_t type[2]; //Should be LwVMType or LwVMType_noCRC. uint64_t guid[2]; //Random. uint64_t mediaSize; //Size in bytes. uint32_t numPartitions; //Number of partitions. uint32_t crc32; uint8_t unkn[464]; //Some unknown bytes, usually nulls. LwVMPartitionRecord partitions[12]; uint16_t chunks[1024]; // chunks[0] should be 0xF000 } __attribute__ ((packed)) LwVM;

static const char LwVMType[] = { 0x6A, 0x90, 0x88, 0xCF, 0x8A, 0xFD, 0x63, 0x0A, 0xE3, 0x51, 0xE2, 0x48, 0x87, 0xE0, 0xB9, 0x8B };

static const char LwVMType_noCRC[] = { 0xB1, 0x89, 0xA5, 0x19, 0x4F, 0x59, 0x4B, 0x1D, 0xAD, 0x44, 0x1E, 0x12, 0x7A, 0xAF, 0x45, 0x39 };

static const char LwVMPartitionTypeHFS[] = { 0x48, 0x46, 0x53, 0x00, 0x00, 0x00, 0x11, 0xAA, 0xAA, 0x11, 0x00, 0x30, 0x65, 0x43, 0xEC, 0xAC };

LightweightVolumeManager IOService
Running 'ioreg | grep "Lightweight"' shows, that there's an IOService with such name. I tried fuzzing IOConnectCallStructMethod selectors (very bad idea). The first call which returned KERN_SUCCESS was done with selector 1. Next, I tried this code: <...> kern_ret = IOConnectCallStructMethod(lwvm_conn, 1, NULL, 0, &info_sz, &o_sz); if (kern_ret == KERN_SUCCESS) {          printf("OK.\n"); void *info = malloc(info_sz); IOConnectCallStructMethod(lwvm_conn, 1, NULL, 0, info, &info_sz); <...> All disk read operations started resulting with errors. Then my device rebooted and entered a boot loop. The code possibly messed the partition table up.

Tools
lwvmedit