1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| from pathlib import Path import re import subprocess
def calc_last_usable_lba(): DISK_SECTORS = 30535680 BACKUP_GPT_HEADER_LBA = DISK_SECTORS - 1 BACKUP_PARTITION_ENTRIES_START_LBA = BACKUP_GPT_HEADER_LBA - 32 BACKUP_PARTITION_ENTRIES_END_LBA = BACKUP_GPT_HEADER_LBA - 1 LAST_USABLE_LBA = BACKUP_PARTITION_ENTRIES_START_LBA - 1 assert LAST_USABLE_LBA == 30535646 return LAST_USABLE_LBA
LAST_USABLE_LBA = calc_last_usable_lba()
def calc_layout(): boot_start_lba, boot_sectors = 396384, (64*1024*1024) // 512
udisk_start_lba, udisk_end_lba = 11333632, LAST_USABLE_LBA udisk_sectors = udisk_end_lba - udisk_start_lba + 1 assert udisk_sectors == 19202015
persist_start = udisk_start_lba - 2 * 7
system_start_lba = boot_start_lba + boot_sectors system_sectors = persist_start - system_start_lba assert system_sectors == 10806162
return { 22: (boot_start_lba, boot_sectors), 23: (system_start_lba, system_sectors), 24: (persist_start + 2 * 0, 2), 25: (persist_start + 2 * 1, 2), 26: (persist_start + 2 * 2, 2), 27: (persist_start + 2 * 3, 2), 28: (persist_start + 2 * 4, 2), 29: (persist_start + 2 * 5, 2), 30: (persist_start + 2 * 6, 2), 31: (udisk_start_lba, udisk_sectors), }
TARGET_LAYOUT = calc_layout()
def read_partition(index): def pick(pattern, text): match = re.search(pattern, text, re.MULTILINE) if not match: raise SystemExit(f"missing field: {pattern}") return match.group(1)
IMAGE = Path("y927-original-gpt.img") text = subprocess.check_output( ["sgdisk", "-i", str(index), str(IMAGE)], stderr=subprocess.DEVNULL, text=True, ) first = int(pick(r"^First sector: (\d+)", text)) last = int(pick(r"^Last sector: (\d+)", text)) return { "start": first, "size": last - first + 1, "type": pick(r"^Partition GUID code: ([0-9A-F-]+)", text), "uuid": pick(r"^Partition unique GUID: ([0-9A-F-]+)", text), "attrs": pick(r"^Attribute flags: ([0-9A-Fa-f]+)", text), "name": pick(r"^Partition name: '([^']*)'", text), }
lines = [ "label: gpt", "label-id: 98101B32-BBE2-4BF2-A06E-2BB33D000C20", "unit: sectors", "first-lba: 34", f"last-lba: {LAST_USABLE_LBA}", "table-length: 32", "sector-size: 512", "", ]
for index in range(1, 32): part = read_partition(index) if index in TARGET_LAYOUT: part["start"], part["size"] = TARGET_LAYOUT[index]
attrs = ', attrs="GUID:60"' if part["attrs"] == "1000000000000000" else "" lines.append( f"start={part['start']}, size={part['size']}, " f"type={part['type']}, uuid={part['uuid']}, " f"name=\"{part['name']}\"{attrs}" )
Path("y927-linuxroot-system-home-udisk.sfdisk").write_text("\n".join(lines) + "\n")
|