From 46d22d4d458781308e57f4d960fa56d4ebb32904 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 3 Jan 2025 09:44:53 +0900 Subject: [PATCH] tizen: sd_fusing.py: Remove sd_fusing.py script sd_fusing.py script was moved to platform/kernel/tizen-fusing-script repo. Remove this script from this repo. - Use script in tizen-fusing-script repo. Change-Id: I0831a53d32a32fe563b79bd224efdaea2a8fc7c1 Signed-off-by: Jaehoon Chung --- scripts/tizen/sd_fusing.py | 1490 ------------------------------------ 1 file changed, 1490 deletions(-) delete mode 100755 scripts/tizen/sd_fusing.py diff --git a/scripts/tizen/sd_fusing.py b/scripts/tizen/sd_fusing.py deleted file mode 100755 index 9f94f345f0..0000000000 --- a/scripts/tizen/sd_fusing.py +++ /dev/null @@ -1,1490 +0,0 @@ -#!/usr/bin/env python3 - -from functools import reduce - -import argparse -import atexit -import errno -import logging -import os -import re -import shutil -import stat -import subprocess -import sys -import tarfile -import tempfile - -__version__ = "1.1.13" - -Format = False -Device = "" -File = "" -Yes = False -SuperDelivered = False - -LOGGING_NOTICE = int((logging.INFO + logging.WARNING) / 2) - -class DebugFormatter(logging.Formatter): - def format(self, record): - if record.levelno == logging.DEBUG: - record.debuginfo = "[{}:{}] ".format(os.path.basename(record.pathname), record.lineno) - else: - record.debuginfo = '' - return logging.Formatter.format(self, record) - -class ColorFormatter(DebugFormatter): - _levelToColor = { - logging.CRITICAL: "\x1b[35;1m", - logging.ERROR: "\x1b[33;1m", - logging.WARNING: "\x1b[33;1m", - LOGGING_NOTICE: "\x1b[0m", - logging.INFO: "\x1b[0m", - logging.DEBUG: "\x1b[30;1m", - logging.NOTSET: "\x1b[30;1m" - } - def format(self, record): - record.levelcolor = self._levelToColor[record.levelno] - record.msg = record.msg - return super().format(record) - -class ColorStreamHandler(logging.StreamHandler): - def __init__(self, stream=None, format=None, datefmt=None, style='%', cformat=None): - logging.StreamHandler.__init__(self, stream) - if os.isatty(self.stream.fileno()): - self.formatter = ColorFormatter(cformat, datefmt, style) - self.terminator = "\x1b[0m\n" - else: - self.formatter = DebugFormatter(format, datefmt, style) - -class Partition: - def __init__(self, name, size, start=None, ptype=None, fstype="raw", bootable=False, **kwargs): - self.name = name - self.size = size - self.size_sectors = kwargs.get("size_sectors", None) - self.start = start - self.start_sector = kwargs.get("start_sector", None) - self.ptype = ptype - self.bootable = bootable - if type(self.size_sectors) == int and self.size_sectors >= 0: - if type(self.size) == int and self.size >= 0: - logging.warning(f"partition:{name} overriding size to the value obtained from size_sectors") - # size is used to calculate free space, so adjust it here - self.size = (self.size_sectors * 512 - 1) / (1024*1024) + 1 - if type(self.start_sector) == int and self.start_sector >= 0: - if type(self.start) == int and self.start >= 0: - logging.warning(f"partition:{name} overriding start to the value obtained from start_sector") - self.size = None - - def __str__(self): - output = [] - if self.start_sector: - output.append(f"start={self.start_sector}") - elif self.start: - output.append(f"start={self.start}MiB") - if type(self.size_sectors) == int and self.size_sectors >= 0: - output.append(f"size={self.size_sectors}") - elif type(self.size) == int and self.size >= 0: - output.append(f"size={self.size}MiB") - if self.name: - output.append(f"name={self.name}") - output.append(f"type={self.ptype}") - if self.bootable: - output.append("bootable") - return ", ".join(output) + "\n" - -class Label: - def __init__(self, part_table, ltype): - self.ltype = ltype - if ltype == 'gpt': - ptype = "0FC63DAF-8483-4772-8E79-3D69D8477DE4" - elif ltype == 'dos': - ptype = '83' - self.part_table = [] - for part in part_table: - part["ptype"] = part.get("ptype", ptype) - self.part_table.append(Partition(**part)) - def __str__(self): - output = f"label: {self.ltype}\n" - if self.ltype == 'gpt': - output += f"first-lba: 34\n" - for part in self.part_table: - output += str(part) - return output - -class SdFusingTarget: - params = (('reboot-param.bin', 'norm'), - ('reboot-param.info', 'norm'), - ('upgrade-progress-status.info', '0'), - ('upgrade-state.info', 'standby'), - ('upgrade-type.info', 'offline')) - - def __init__(self, device, ltype): - # TODO: make a copy of a sublcass part_table - self.with_super = False - self.device = device - total_size = device_size(device) - - # find user partition and calculate its size - n = None - for i, p in enumerate(self.part_table): - if p['name'] == 'user': - n = i; - break - - if n is not None: - self.user_size = total_size - self.reserved_space - \ - reduce(lambda x, y: x + (y["size"] or 0), self.part_table, 0) - if self.user_size < 100: - logging.error(f"Not enough space for user data ({self.user_size}). Use larger storage.") - raise OSError(errno.ENOSPC, os.strerror(errno.ENOSPC), device) - self.part_table[n]["size"] = self.user_size - - self.label = Label(self.part_table, ltype) - self.binaries = self._get_binaries('binaries') - - def apply_partition_sizes(self, partition_sizes): - if partition_sizes is None or len(partition_sizes) == 0: - return 0 - resized_total = 0 - for name, size in partition_sizes.items(): - resized_count = 0 - for part in self.part_table: - if part['name'] == name: - psize = part['size'] - part['size'] = size - logging.debug(f"overriding partition:{name}, old-size:{psize} MiB new-size:{size} MiB") - resized_count = resized_count + 1 - if resized_count == 0: - logging.error(f"partition:{name} not found when attempting to apply_partition_sizes") - resized_total = resized_total + resized_count - return resized_total - - def _get_binaries(self, key): - binaries = {} - for i, p in enumerate(self.part_table): - b = p.get(key, None) - if b is None: - continue - if isinstance(b, str): - binaries[b] = i + 1 - elif isinstance(b, list): - for f in b: - binaries[f] = i + 1 - return binaries - - def get_partition_index_list(self, binary): - if hasattr(self, 'update'): - logging.error("You have requested to update the {} partition set. " - "This target does not support A/B partition sets." - .format(self.update.upper())) - sys.exit(1) - return [self.binaries.get(binary, None)] - - def get_raw_binary_sector(self, binary): - if not hasattr(self, "raw_binary_table"): - return None - - for entry in self.raw_binary_table: - if entry['binaries'] == binary: - return entry['start_sector']; - return None - - def ensure_parttable(self): - logging.notice(f"Verifying that partition table on {Device} matches target specification") - for partnum, part in enumerate(self.part_table, 1): - d = "/dev/" + get_partition_device(Device, partnum) - bo = subprocess.check_output(["blkid", "-o", "export", d]).decode('utf-8') - if "PARTLABEL=" in bo and f"PARTLABEL={part['name']}" not in bo: - logging.error(f'On-device partition label mismatch with selected target: partlabel={part["name"]}, on-device:\n{bo}') - sys.exit(1) - - def initialize_parameters(self): - pass - - def write_parameters(self, params = None): - pass - - def update_parameters(self): - self.write_parameters() - -class SdFusingTargetAB(SdFusingTarget): - def __init__(self, device, ltype): - super().__init__(device, ltype) - self.binaries_b = self._get_binaries('binaries_b') - - def get_partition_index_list(self, binary): - if self.update == 'b': - return [self.binaries_b.get(binary, None)] - elif self.update == 'ab': - return [self.binaries.get(binary, None), self.binaries_b.get(binary, None)] - - return [self.binaries.get(binary, None)] - - def update_parameters(self): - part_ab = 'a' if self.update in [None, '', 'a', 'ab'] else 'b' - part_cloned = '1' if self.update == 'ab' else '0' - params = [('partition-ab.info', part_ab), - ('partition-ab-cloned.info', part_cloned)] - if not self.update in [None, '', 'a', 'ab']: - params.append(('partition-a-status.info', 'ok')) - if self.update in ['b', 'ab']: - params.append(('partition-b-status.info', 'ok')) - self.write_parameters(self.params + tuple(params)) - -class InitParams: - def find_inform(self): - n = None - for i, p in enumerate(self.part_table): - if p['name'] == 'inform': - n = i + 1; - break - d = "/dev/" + get_partition_device(self.device, n) - return d - - def initialize_parameters(self): - logging.debug("Initializing parameters") - d = self.find_inform() - - argv = ['tune2fs', '-O', '^metadata_csum', d] - logging.debug(" ".join(argv)) - subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - - def write_parameters(self, params = None): - d = self.find_inform() - logging.debug(f"Writing parameters to {d}") - with tempfile.TemporaryDirectory() as mnt: - argv = ['mount', '-t', 'ext4', d, mnt] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - if proc.returncode != 0: - logging.error(f"Failed to mount {d} in {mnt} (Has the device been initialized with --format?)") - return - parameters = self.params if params is None else params - for param, value in parameters: - with open(os.path.join(mnt, param), 'w') as f: - logging.debug(f"Writing parameter {param}={value}") - f.write(value + '\n') - argv = ['umount', d] - logging.debug(" ".join(argv)) - subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - -class Rpi3(InitParams, SdFusingTarget): - long_name = "Raspberry Pi 3" - part_table = [ - {"size": 64, "name": "boot", "start": 4, "ptype": "0xe", "bootable": True, - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "ptype": "5", "name": "extended", "start": 4484}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "modules", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal", - "binaries": "hal.img"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 12 - super().__init__(device, "dos") - -class AmlogicMBR(InitParams, SdFusingTarget): - part_table = [ - {"size": 128, "name": "boot", "start": 4, "ptype": "0xe", "bootable": True, - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "ptype": "5", "name": "extended", "start": 4548}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 100, "name": "modules", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 64, "name": "hal", - "binaries": "hal.img"}, - {"size": 128, "name": "reserved2"}, - ] - raw_binary_table = [ - {"name": "bootloader", - "start_sector": 1}, - ] - - def __init__(self, device, args): - self.reserved_space = 12 - for entry in self.raw_binary_table: - if entry['name'] == 'bootloader': - entry['binaries'] = args._bootloader_name - break - super().__init__(device, "dos") - -class OdroidC4(AmlogicMBR): - long_name = "Odroid C4" - - def __init__(self, device, args): - setattr(args, "_bootloader_name", "u-boot-c4.bin") - super().__init__(device, args) - -class OdroidN2(AmlogicMBR): - long_name = "Odroid N2" - - def __init__(self, device, args): - setattr(args, "_bootloader_name", "u-boot-n2.bin") - super().__init__(device, args) - -class KhadasVim3(AmlogicMBR): - long_name = "Khadas VIM3" - - def __init__(self, device, args): - setattr(args, "_bootloader_name", "u-boot-vim3.bin") - super().__init__(device, args) - -class KhadasVim3L(AmlogicMBR): - long_name = "Khadas VIM3L" - - def __init__(self, device, args): - setattr(args, "_bootloader_name", "u-boot-vim3l.bin") - super().__init__(device, args) - -class Rpi4Super(InitParams, SdFusingTargetAB): - long_name = "Raspberry Pi 4 w/ super partition" - part_table = [ - {"size": 64, "name": "boot_a","start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 6657, "name": "super", - "binaries": "super.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": 36, "fstype": "raw", "name": "none"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 64, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"} - ] - - def __init__(self, device, args): - self.reserved_space = 8 - self.update = args.update - super().__init__(device, "gpt") - self.with_super = True - -class Rpi4(InitParams, SdFusingTargetAB): - long_name = "Raspberry Pi 4" - part_table = [ - {"size": 64, "name": "boot_a", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": 36, "name": "none"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 64, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - super().__init__(device, "gpt") - -class Rpi4AoT(InitParams, SdFusingTargetAB): - long_name = "Raspberry Pi 4 for AoT" - part_table = [ - {"size": 64, "name": "boot_a", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": 36, "name": "none"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 64, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 1536, "name": "aot-system_a", - "binaries": "system.img"}, - {"size": 1536, "name": "aot-system_b", - "binaries_b": "system.img"}, - {"size": 256, "name": "aot-vendor_a", - "binaries": "vendor.img"}, - {"size": 256, "name": "aot-vendor_b", - "binaries_b": "vendor.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - super().__init__(device, "gpt") - -class RV64(InitParams, SdFusingTarget): - long_name = "QEMU RISC-V 64-bit" - part_table = [ - {"size": 292, "name": "boot_a", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - -class RV64AB(InitParams, SdFusingTargetAB): - long_name = "QEMU RISC-V 64-bit with A/B" - part_table = [ - {"size": 292, "name": "boot_a", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 292, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - -class RV64Super(InitParams, SdFusingTargetAB): - long_name = "QEMU RISC-V 64-bit with super" - part_table = [ - {"size": 292, "name": "boot_a", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 6656, "name": "super", - "binaries": "super.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 292, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - self.with_super = True - -class VF2(InitParams, SdFusingTargetAB): - long_name = "VisionFive2" - part_table = [ - {"size": 2, "name": "SPL", "start": 4, - "ptype": "2E54B353-1271-4842-806F-E436D6AF6985", - "binaries": ["u-boot-spl.bin.normal.out"],}, - {"size": 4, "name": "u-boot", - "ptype": "5B193300-FC78-40CD-8002-E86C45580B47", - "binaries": ["u-boot.img", "u-boot.itb"],}, - {"size": 128, "name": "boot_a", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 128, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - -class VF2Super(InitParams, SdFusingTargetAB): - long_name = "VisionFive2 w/ super partition" - part_table = [ - {"size": 2, "name": "SPL", "start": 4, - "ptype": "2E54B353-1271-4842-806F-E436D6AF6985", - "binaries": ["u-boot-spl.bin.normal.out"],}, - {"size": 4, "name": "u-boot", - "ptype": "5B193300-FC78-40CD-8002-E86C45580B47", - "binaries": ["u-boot.img", "u-boot.itb"],}, - {"size": 128, "name": "boot_a", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 6656, "name": "super", - "binaries": "super.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 128, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - super().__init__(device, 'gpt') - self.with_super = True - -class LicheePi4A(InitParams, SdFusingTargetAB): - long_name = "LicheePi4A" - part_table = [ - {"size": None, "name": "spl+uboot", - "start_sector": 34, "size_sectors": 4062, - "ptype": "8DA63339-0007-60C0-C436-083AC8230908", - "binaries": ["u-boot-with-spl.bin"],}, - {"size": 128, "name": "boot_a", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 128, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - raw_binary_table = [ - {"name": "bootcode", - "start_sector": 0, # part of protective MBR (bootcode) - "binaries": "bootcode.bin", }, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - -class LicheePi4ASuper(InitParams, SdFusingTargetAB): - long_name = "LicheePi4A w/ super partition" - part_table = [ - {"size": None, "name": "spl+uboot", - "start_sector": 34, "size_sectors": 4062, - "ptype": "8DA63339-0007-60C0-C436-083AC8230908", - "binaries": ["u-boot-with-spl.bin"],}, - {"size": 128, "name": "boot_a", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 6656, "name": "super", - "binaries": "super.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 128, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"} - ] - raw_binary_table = [ - {"name": "bootcode", - "start_sector": 0, # part of protective MBR (bootcode) - "binaries": "bootcode.bin", }, - ] - - def __init__(self, device, args): - self.reserved_space = 8 - self.update = args.update - super().__init__(device, 'gpt') - self.with_super = True - - -class X86emu(SdFusingTarget): - part_table = [ - {"size": 512, "fstype": "vfat", "name": "EFI", "start": 4, - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "",}, - {"size": 512, "name": "boot", - "binaries": "emulator-boot.img",}, - {"size": 2048, "fstype": "ext4", "name": "rootfs", - "binaries": "emulator-rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "emulator-sysdata.img"}, - {"size": 1024, "name": "emulator-swap", - "ptype": "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F"}, - ] - - def __init__(self, device, args): - super().__init__(device, 'gpt') - for p in self.label.part_table: - if p.name == "rootfs": - p.ptype = args._rootfs_uuid - break - -class BpiF3(InitParams, SdFusingTargetAB): - long_name = "BananPi BPI-F3" - part_table = [ - {"size": None, "name": "fsbl", - "start_sector": 256, "size_sectors": 512, - "ptype": "5B193300-FC78-40CD-8002-E86C45580B47", - "binaries": ["FSBL.bin"],}, - {"size": None, "name": "opensbi", - "start_sector": 2048, "size_sectors": 2048, - "ptype": "2E54B353-1271-4842-806F-E436D6AF6985", - "binaries": ["fw_dynamic.itb"],}, - {"size": None, "name": "uboot", - "start_sector": 4096, "size_sectors": 4096, - "ptype": "2E54B353-1271-4842-806F-E436D6AF6985", - "binaries": ["u-boot.itb"],}, - {"size": 256, "name": "boot_a", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries": "boot.img"}, - {"size": 3072, "name": "rootfs_a", - "binaries": "rootfs.img"}, - {"size": 1344, "name": "system-data", - "binaries": "system-data.img"}, - {"size": None, "name": "user", - "binaries": "user.img"}, - {"size": 32, "name": "module_a", - "binaries": "modules.img"}, - {"size": 32, "name": "ramdisk_a", - "binaries": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_a", - "binaries": "ramdisk-recovery.img"}, - {"size": 8, "name": "inform", "fstype": "ext4"}, - {"size": 256, "name": "hal_a", - "binaries": "hal.img"}, - {"size": 128, "name": "boot_b", - "ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", - "binaries_b": "boot.img"}, - {"size": 3072, "name": "rootfs_b", - "binaries_b": "rootfs.img"}, - {"size": 32, "name": "module_b", - "binaries_b": "modules.img"}, - {"size": 32, "name": "ramdisk_b", - "binaries_b": "ramdisk.img"}, - {"size": 32, "name": "ramdisk-recovery_b", - "binaries_b": "ramdisk-recovery.img"}, - {"size": 256, "name": "hal_b", - "binaries_b": "hal.img"}, - {"size": 4, "name": "reserved0"}, - {"size": 64, "name": "reserved1"}, - {"size": 125, "name": "reserved2"}, - ] - raw_binary_table = [ - {"name": "bootinfo_sd", - "start_sector": 0, # part of protective MBR (bootcode) - "binaries": "bootinfo_sd.bin", }, - ] - - def __init__(self, device, args): - self.reserved_space = 5 - self.update = args.update - self.apply_partition_sizes(args.partition_sizes) - super().__init__(device, 'gpt') - - -class X86emu32(X86emu): - long_name = "QEMU x86 32-bit" - - def __init__(self, device, args): - setattr(args, "_rootfs_uuid", "44479540-F297-41B2-9AF7-D131D5F0458A") - super().__init__(device, args) - -class X86emu64(X86emu): - long_name = "QEMU x86 64-bit" - - def __init__(self, device, args): - setattr(args, "_rootfs_uuid", "4f68bce3-e8cd-4db1-96e7-fbcaf984b709") - super().__init__(device, args) - -TARGETS = { - 'rpi3': Rpi3, - 'odroidc4': OdroidC4, - 'odroidn2': OdroidN2, - 'kvim3': KhadasVim3, - 'kvim3l': KhadasVim3L, - 'rpi4': Rpi4, - 'rpi4s': Rpi4Super, - 'rpi4aot': Rpi4AoT, - 'vf2': VF2, - 'vf2s': VF2Super, - 'rv64': RV64, - 'rv64ab': RV64AB, - 'rv64s': RV64Super, - 'lpi4a': LicheePi4A, - 'lpi4as': LicheePi4ASuper, - 'bpif3': BpiF3, - 'x86emu32': X86emu32, - 'x86emu64': X86emu64, -} - -def device_size(device): - argv = ["sfdisk", "-s", device] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - stdout = proc.stdout.decode('utf-8') - try: - size = int(stdout.strip()) >> 10 - except ValueError: - stderr = proc.stderr.decode('utf-8') - logging.error(f"Unexpected sfdisk output:\n{stdout}\n{stderr}\n") - sys.exit(1) - - logging.debug(f"{device} size {size}MiB") - return size - -def check_sfdisk(): - min_major = 2 - min_minor = 26 - min_minor_del = 28 - - proc = subprocess.run(['sfdisk', '-v'], - stdout=subprocess.PIPE) - version = proc.stdout.decode('utf-8').strip() - logging.debug(f"Found {version}") - version_tokens = [int(x) for x in re.findall('[0-9]+', version)] - - if len(version_tokens) == 3: - major, minor, patch = version_tokens[0:3] - version_str = f"{major}.{minor}.{patch}" - elif len(version_tokens) == 2: - major, minor = version_tokens[0:2] - version_str = f"{major}.{minor}" - else: - logging.warning("Did not read version of sfdisk correctly.") - return False,False - - support_delete = False - - if major < min_major or major == min_major and minor < min_minor: - logging.error(f"Your sfdisk {version_str} is too old. Please switch to at least {min_major}.{min_minor}") - return False,False - elif major == min_major and minor >= min_minor_del: - support_delete = True - - return True, support_delete - -def wait_for_udev(): - # Run `udevadm settle` to ensure that partition change made by `sfdisk` or writing bootcode is completely reflected in userspace. - logging.info("Waiting for the udev event queue to empty...") - argv = ['udevadm', 'settle'] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=None, - stderr=None) - if proc.returncode != 0: - logging.warning("udevadm settle exited without clearing the udev event queue.") - else: - logging.info("The udev event queue is empty.") - -def mkpart(args, target): - global Device - new, support_delete = check_sfdisk() - - if not new: - logging.error('sfdisk too old') - sys.exit(1) - - with open('/proc/self/mounts') as mounts: - device_kname = '/dev/' + get_device_kname(Device) - device_re = re.compile(device_kname + '[^ ]*') - logging.debug(f"Checking for mounted partitions on {device_kname}") - for m in mounts: - match = device_re.match(m) - if match: - logging.warning('Found mounted device: ' + match[0]) - argv = ['umount', match[0]] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv) - if proc.returncode != 0: - logging.error(f"Failed to unmount {match[0]}") - sys.exit(1) - - if support_delete: - logging.info("Removing old partitions") - argv = ['sfdisk', '--delete', Device] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv) - if proc.returncode != 0: - logging.error(f"Failed to remove the old partitions from {Device}") - else: - logging.info("Removing old partition table") - argv = ['dd', 'if=/dev/zero', 'of=' + Device, - 'bs=512', 'count=32', 'conv=notrunc'] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv) - if proc.returncode != 0: - logging.error(f"Failed to clear the old partition table on {Device}") - sys.exit(1) - - logging.debug("New partition table:\n" + str(target.label)) - argv = ['sfdisk', '--wipe-partitions', 'always', Device] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=None, - stderr=None, - input=str(target.label).encode()) - if proc.returncode != 0: - logging.error(f"Failed to create partition a new table on {Device}") - logging.error(f"New partition table:\n" + str(target.label)) - sys.exit(1) - - wait_for_udev() - - for i, part in enumerate(target.part_table): - d = "/dev/" + get_partition_device(target.device, i+1) - if not 'fstype' in part: - logging.debug(f"Filesystem not defined for {d}, skipping") - continue - logging.debug(f"Formatting {d} as {part['fstype']}") - if part['fstype'] == 'vfat': - argv = ['mkfs.vfat', '-F', '16', '-n', part['name'], d] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - if proc.returncode != 0: - logging.error(f"Failed to create FAT filesystem on {d}") - sys.exit(1) - elif part['fstype'] == 'ext4': - argv = ['mkfs.ext4', '-F', '-q', '-L', part['name'], d] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - if proc.returncode != 0: - logging.error(f"Failed to create ext4 filesystem on {d}") - sys.exit(1) - elif part['fstype'] == 'swap': - argv = ['mkswap', '-L', part['name'], d] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - if proc.returncode != 0: - logging.error(f"Failed to format swap partition {d}") - sys.exit(1) - elif part['fstype'] == 'raw': - pass - target.initialize_parameters() - -def check_args(args): - global Format - global Yes - global SuperDelivered - - logging.info(f"Device: {args.device}") - - if args.binaries and len(args.binaries) > 0: - logging.info("Fusing binar{}: {}".format("y" if len(args.binaries) == 1 else "ies", - ", ".join(args.binaries))) - - if args.YES: - Yes = True - - if args.create: - Format = True - Yes = True - - if args.format: - if Yes: - Format = True - else: - response = input(f"{args.device} will be formatted. Continue? [y/N] ") - if response.lower() in ('y', 'yes'): - Format = True - else: - Format = False - - if args.super_delivered: - SuperDelivered = True - -def check_device(args): - global Format - global Device - Device = args.device - - if args.create: - if os.path.exists(Device): - logging.error(f"Failed to create '{Device}', the file alread exists") - sys.exit(1) - else: - argv = ["dd", "if=/dev/zero", f"of={Device}", - "conv=sparse", "bs=1M", f"count={args.size}"] - logging.debug(" ".join(argv)) - rc = subprocess.run(argv) - if rc.returncode != 0: - logging.error("Failed to create the backing file") - sys.exit(1) - - if os.path.isfile(Device): - global File - File = Device - - argv = ["losetup", "--show", "--partscan", "--find", f"{File}"] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=subprocess.PIPE) - Device = proc.stdout.decode('utf-8').strip() - if proc.returncode != 0: - logging.error(f"Failed to attach {File} to a loopback device") - sys.exit(1) - logging.debug(f"Loop device found: {Device}") - atexit.register(lambda: subprocess.run(["losetup", "-d", Device])) - - try: - s = os.stat(Device) - if not stat.S_ISBLK(s.st_mode): - raise TypeError - except FileNotFoundError: - logging.error(f"No such device: {Device}") - sys.exit(1) - except TypeError: - logging.error(f"{Device} is not a block device") - sys.exit(1) - -def check_partition_format(args, target): - global Format - global Device - - if not Format: - logging.info(f"Skip formatting of {Device}".format(Device)) - target.ensure_parttable() - return - logging.info(f"Start formatting of {Device}") - mkpart(args, target) - logging.info(f"{Device} formatted") - -def check_ddversion(): - proc = subprocess.run(["dd", "--version"], - stdout=subprocess.PIPE) - version = proc.stdout.decode('utf-8').split('\n')[0].strip() - logging.debug(f"Found {version}") - major, minor = (int(x) for x in re.findall('[0-9]+', version)) - - if major < 8 or major == 8 and minor < 24: - return False - - return True - -def get_partition_device(device, idx): - argv = ['lsblk', device, '-o', 'TYPE,KNAME'] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=subprocess.PIPE) - if proc.returncode != 0: - logging.error("lsblk has failed") - sys.exit(1) - part_re = re.compile(f"^part\s+(.*[^0-9]{idx})$") - for l in proc.stdout.decode('utf-8').splitlines(): - match = part_re.match(l) - if match: - return match[1] - logging.error("device entry not found") - sys.exit(1) - -def get_device_kname(device): - argv = ['lsblk', device, '-o', 'TYPE,KNAME'] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdout=subprocess.PIPE) - if proc.returncode != 0: - logging.error("lsblk has failed") - sys.exit(1) - for l in proc.stdout.decode('utf-8').splitlines(): - match = re.search(f"^(disk|loop)\s+(.*)", l) - if match: - return match[2] - logging.error("kname entry not found") - sys.exit(1) - -def do_fuse_raw(f, name, target, sector): - argv = ['dd', 'bs=512', - 'oflag=direct', - f'seek={sector}', - 'conv=nocreat', - 'status=progress', - f"of={Device}"] - logging.debug(" ".join(argv)) - proc_dd = subprocess.Popen(argv, - bufsize=(1 << 9), - stdin=subprocess.PIPE, - stdout=None, stderr=None) - logging.notice(f"Writing {name} to {Device} at sector {sector}") - f.seek(0) - buf = f.read(1 << 9) - while len(buf) > 0: - proc_dd.stdin.write(buf) - buf = f.read(1 << 9) - proc_dd.communicate() - logging.info("Done") - - # direct writing to block device might trigger kernel/udev to re-read partition table - wait_for_udev() - - #TODO: verification - -def do_fuse_file(f, name, target): - sector = target.get_raw_binary_sector(name) - if sector is not None: - do_fuse_raw(f, name, target, sector) - return - indexes = target.get_partition_index_list(name) - if len(indexes) == 0: - logging.info(f"No partition defined for {name}, skipping.") - return - for idx in indexes: - if idx is None: - logging.info(f"No partition defined for {name}, skipping.") - continue - pdevice = "/dev/" + get_partition_device(Device, idx) - argv = ['dd', 'bs=4M', - 'oflag=direct', - 'iflag=fullblock', - 'conv=nocreat', - 'status=progress', - f"of={pdevice}"] - logging.debug(" ".join(argv)) - proc_dd = subprocess.Popen(argv, - bufsize=(4 << 20), - stdin=subprocess.PIPE, - stdout=None, stderr=None) - logging.notice(f"Writing {name} to {pdevice}") - f.seek(0) - buf = f.read(4 << 20) - while len(buf) > 0: - proc_dd.stdin.write(buf) - buf = f.read(4 << 20) - proc_dd.communicate() - logging.info("Done") - #TODO: verification - -#TODO: functions with the target argument should probably -# be part of some class - -def do_fuse_image_super(tmpd, target): - metadata_slots = 2 - metadata_size = 65536 - header_size = 1024 * 1024 # default alignment used in lpmake - super_size = 0 - - for p in target.label.part_table: - if p.name == "super": - super_size = p.size * 1024 * 1024 # size of parts is in MiB. Change to B - break - - if super_size == 0: - logging.error(f"No information found about super partition, cannot create image") - sys.exit(1) - - group_size = int((super_size - header_size) / 2); - hal_path = os.path.join(tmpd, 'hal.img') - rootfs_path = os.path.join(tmpd, 'rootfs.img') - super_path = os.path.join(tmpd, 'super.img') - - try: - hal_size = os.stat(hal_path).st_size - rootfs_size = os.stat(rootfs_path).st_size - except FileNotFoundError as e: - fn = os.path.split(e.filename)[-1] - logging.error(f"{fn} is missing, cannot create super partition image") - sys.exit(1) - - if group_size < hal_size + rootfs_size: - logging.error(f"rootfs and hal are too big to fit in a slot on a super partition") - sys.exit(1) - - argv = ["lpmake", "-F", - f"-o={super_path}", - f"--device-size={super_size}", - f"--metadata-size={metadata_size}", - f"--metadata-slots={metadata_slots}", - "-g", f"tizen_a:{group_size}", - "-p", f"rootfs_a:none:{rootfs_size}:tizen_a", - "-p", f"hal_a:none:{hal_size}:tizen_a", - "-g", f"tizen_b:{group_size}", - "-p", f"rootfs_b:none:{rootfs_size}:tizen_b", - "-p", f"hal_b:none:{hal_size}:tizen_b", - "-i", f"rootfs_a={rootfs_path}", - "-i", f"rootfs_b={rootfs_path}", - "-i", f"hal_a={hal_path}", - "-i", f"hal_b={hal_path}"] - logging.debug(" ".join(argv)) - proc = subprocess.run(argv, - stdin=subprocess.DEVNULL, - stdout=None, stderr=None) - - if proc.returncode != 0: - logging.error("Failed to create super.img") - sys.exit(1) - do_fuse_image(super_path, target) - -def do_fuse_image_tarball(tarball, tmpd, target): - with tarfile.open(tarball) as tf: - for entry in tf: - if target.with_super and not SuperDelivered: - if entry.name in('hal.img', 'rootfs.img'): - tf.extract(entry, path=tmpd) - continue - f = tf.extractfile(entry) - do_fuse_file(f, entry.name, target) - -def do_fuse_image(img, target): - with open(img, 'rb') as f: - do_fuse_file(f, os.path.basename(img), target) - -def fuse_image(args, target): - global Yes - - if args.binaries is None or len(args.binaries) == 0: - return - - if not Yes and not Format: - print(f"The following images will be written to {args.device} and the " - "existing data will be lost.\n") - print(f"########################## NOTICE ##########################\n") - print(f"sd_fusing.py was moved to tizen-fusing-scripts repository.\n") - print(f"Download sd_fusing.py from tizen-fusing-scripts reposistory!\n") - print(f"############################################################\n") - for b in args.binaries: - print(" " + b) - response = input("\nContinue? [y/N] ") - if not response.lower() in ('y', 'yes'): - return - - with tempfile.TemporaryDirectory() as tmpd: - for b in args.binaries: - if re.search('\.(tar|tar\.gz|tgz)$', b): - do_fuse_image_tarball(b, tmpd, target) - else: - fn = os.path.split(b)[-1] - if target.with_super and fn in ('rootfs.img', 'hal.img') and not SuperDelivered: - shutil.copy(b, os.path.join(tmpd, fn)) - else: - do_fuse_image(b, target) - - if target.with_super and not SuperDelivered: - do_fuse_image_super(tmpd, target) - target.update_parameters() - -def logger_notice(self, msg, *args, **kws): - if self.isEnabledFor(LOGGING_NOTICE): - self._log(LOGGING_NOTICE, msg, args, **kws) -logging.Logger.notice = logger_notice - -def logging_notice(msg, *args, **kws): - if len(logging.root.handlers) == 0: - basicConfig() - logging.root.notice(msg, *args, **kws) -logging.notice = logging_notice - -def check_python_version(): - required_min_ver=(3,8) - if sys.version_info[:2] < required_min_ver: - print("Minimum required Python version is 3.8") - sys.exit(1) - -if __name__ == '__main__': - check_python_version() - parser = argparse.ArgumentParser(description="For {}, version {}".format( - ", ".join([v.long_name for k,v in TARGETS.items()]), - __version__ - )) - parser.add_argument("-b", "--binary", action="extend", dest="binaries", - nargs='+', - help="binary to flash, may be used multiple times") - parser.add_argument("--create", action="store_true", - help="create the backing file and format the loopback device") - parser.add_argument("--debug", action="store_const", const="debug", - default="notice", dest="log_level", - help="set log level to DEBUG") - parser.add_argument("-d", "--device", - help="device node or loopback backing file") - parser.add_argument("--format", action="store_true", - help="create new partition table on the target device") - parser.add_argument("--log-level", dest="log_level", default="notice", - help="Verbosity, possible values: debug, info, notice, warning, " - "error, critical (default: notice)") - parser.add_argument("--partition-size", type=str, action="extend", dest="partition_sizes", - nargs='*', - help="override default partition size (in MiB) (used with --format), " - "may be used multiple times, for example: --partition-size hal_a=256") - parser.add_argument("--size", type=int, default=8192, - help="size of the backing file to create (in MiB)") - parser.add_argument("-t", "--target", required=True, - help="Target device model. Use `--target list`" - " to show supported devices.") - parser.add_argument("--update", choices=['a', 'b', 'ab'], default=None, - help="Choose partition set to update: a or b or ab.") - parser.add_argument("--version", action="version", - version=f"%(prog)s {__version__}") - parser.add_argument("--YES", action="store_true", - help="agree to destroy data on the DEVICE") - parser.add_argument("--super_delivered", action="store_true", - help="indicate that super.img is already in tarball and doesn't have to be created during fusing") - args = parser.parse_args() - - if args.target == 'list': - print("\nSupported devices:\n") - for k,v in TARGETS.items(): - print(f" {k:6} {v.long_name}") - sys.exit(0) - - if args.device is None: - parser.error('-d/--device argument is required for normal operation') - - if args.partition_sizes is not None: - partition_sizes = {} - for eqstr in args.partition_sizes: - ptstr = eqstr.split('=') - if len(ptstr) == 2: - name = ptstr[0] - size = int(ptstr[1]) - partition_sizes[name] = size - else: - parser.error('--partition-size must follow the name=size pattern') - args.partition_sizes = partition_sizes - - logging.addLevelName(LOGGING_NOTICE, "NOTICE") - conh = ColorStreamHandler(format='%(asctime)s.%(msecs)d %(debuginfo)s%(levelname)-8s %(message)s', - cformat='%(asctime)s.%(msecs)d %(debuginfo)s%(levelcolor)s%(message)s', - datefmt='%Y-%m-%dT%H:%M:%S') - log_handlers = [conh] - logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s', - handlers=log_handlers, - level=args.log_level.upper()) - - logging.debug(" ".join(sys.argv)) - check_args(args) - check_device(args) - - target = TARGETS[args.target](Device, args) - - check_partition_format(args, target) - fuse_image(args, target) - subprocess.run(['sync'], - stdin=subprocess.DEVNULL, - stdout=None, stderr=None ) -- 2.34.1