import subprocess
import sys
import tarfile
+import tempfile
__version__ = "1.0.0"
def get_partition_index(self, binary):
return self.binaries.get(binary, None)
+ params = ()
+ def initialize_parameters(self):
+ pass
+
class SdFusingTargetAB(SdFusingTarget):
def get_partition_index(self, binary):
if self.update == 'b':
return self.binaries_b.get(binary, None)
return self.binaries.get(binary, None)
-class Rpi3(SdFusingTarget):
+class RpiInitParams:
+ def initialize_parameters(self):
+ logging.debug("Initializing parameterss")
+ n = None
+ for i, p in enumerate(self.part_table):
+ if p['name'] == 'inform':
+ n = i + 1;
+ d = "/dev/" + get_partition_device(self.device, n)
+
+ subprocess.run(['tune2fs', '-O', '^metadata_csum', d],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None)
+
+ with tempfile.TemporaryDirectory() as mnt:
+ proc = subprocess.run(['mount', '-t', 'ext4', d, mnt],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None)
+ if proc.returncode != 0:
+ logging.error("Failed to mount {d} in {mnt}")
+ return
+ for param, value in self.params:
+ with open(os.path.join(mnt, param), 'w') as f:
+ f.write(value + '\n')
+ subprocess.run(['umount', d],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None)
+
+class Rpi3(SdFusingTarget,RpiInitParams):
long_name = "Raspberry Pi 3"
part_table = [
{"size": 64, "fstype": "vfat", "name": "boot", "start": 4, "ptype": "0xe", "bootable": True},
{"size": 32, "fstype": "ext4", "name": "modules"},
{"size": 32, "fstype": "ext4", "name": "ramdisk"},
{"size": 32, "fstype": "ext4", "name": "ramdisk-recovery"},
- {"size": 8, "fstype": "raw", "name": "inform"},
+ {"size": 8, "fstype": "ext4", "name": "inform"},
{"size": 256, "fstype": "ext4", "name": "hal"},
- {"size": 125, "fstype": "raw", "name": "reserved2"},
+ {"size": 125, "fstype": "ext4", "name": "reserved2"},
]
binaries = {
"boot.img": 1,
"ramdisk-recovery.img": 8,
"hal.img": 10,
}
+ params = (('reboot-param.bin', ''),)
def __init__(self, device, args):
self.reserved_space = 12
self.user_partition = 4
super().__init__(device, "dos")
-class Rpi4Super(SdFusingTargetAB):
+class Rpi4Super(SdFusingTargetAB, RpiInitParams):
long_name = "Raspberry Pi 4 w/ super partition"
part_table = [
{"size": 64, "fstype": "vfat", "name": "boot_a","start": 4,
{"size": 32, "fstype": "ext4", "name": "module_a"},
{"size": 32, "fstype": "ext4", "name": "ramdisk_a"},
{"size": 32, "fstype": "ext4", "name": "ramdisk-recovery_a"},
- {"size": 8, "fstype": "raw", "name": "inform"},
+ {"size": 8, "fstype": "ext4", "name": "inform"},
{"size": 0, "fstype": "raw", "name": "empty"},
{"size": 64, "fstype": "vfat", "name": "boot_b",
"ptype": "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"},
"ramdisk.img": 14,
"ramdisk-recovery.img": 15,
}
+ params = (('reboot-param.bin', 'norm'),
+ ('reboot-param.info', 'norm'),
+ ('partition-ab.info', 'a'),
+ ('partition-ab-cloned.info', '1'),
+ ('upgrade-status.info', '0'),
+ ('partition-a-status.info', 'ok'),
+ ('partition-b-status.info', 'ok'))
def __init__(self, device, args):
self.reserved_space = 8
self.user_partition = 4
self.update = args.update
super().__init__(device, "gpt")
+ self.with_super = True
+
-class Rpi4(SdFusingTargetAB):
+class Rpi4(SdFusingTargetAB, RpiInitParams):
long_name = "Raspberry Pi 4"
part_table = [
{"size": 64, "fstype": "vfat", "name": "boot_a", "start": 4,
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)
- #TODO: mkfs
+
+ 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':
+ proc = subprocess.run(['mkfs.vfat', '-F', '16', '-n', part['name'], d],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None)
+ if proc.returncode != 0:
+ log.error(f"Failed to create FAT filesystem on {d}")
+ sys.exit(1)
+ elif part['fstype'] == 'ext4':
+ proc = subprocess.run(['mkfs.ext4', '-q', '-L', part['name'], d],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None)
+ if proc.returncode != 0:
+ log.error(f"Failed to create ext4 filesystem on {d}")
+ sys.exit(1)
+ elif part['fstype'] == 'raw':
+ pass
+ target.initialize_parameters()
def check_args(args):
global Format
help="Target device model. Use `--target list`"
" to show supported devices.")
parser.add_argument("--update", choices=['a', 'b'], default=None,
- help="Choose partition set to update: A or B.")
+ help="Choose partition set to update: a or b.")
parser.add_argument("--version", action="version",
version=f"%(prog)s {__version__}")
args = parser.parse_args()
check_device(args)
check_partition_format(args)
fuse_image(args)
+ subprocess.run(['sync'],
+ stdin=subprocess.DEVNULL,
+ stdout=None, stderr=None )