
Provide a way to create disk images which consist of multiple filesystem images. Signed-off-by: Simon Glass <sjg@chromium.org> --- test/py/tests/fs_helper.py | 90 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/test/py/tests/fs_helper.py b/test/py/tests/fs_helper.py index 7d20dbacf76..5c147e7750f 100644 --- a/test/py/tests/fs_helper.py +++ b/test/py/tests/fs_helper.py @@ -149,6 +149,96 @@ class FsHelper: self.cleanup() +class DiskHelper: + """Helper class for creating disk images containing filesytems + + Usage: + with DiskHelper(ubman.config, 0, 'mmc') as img, \ + FsHelper(ubman.config, 'ext1', 1, 'mmc') as fsh: + # Write files to fsh.srcdir + ... + + # Create the filesystem + fsh.mk_fs() + + # Add this filesystem to the disk + img.add_fs(fsh, DiskHelper.VFAT) + + # Add more filesystems as needed (add another 'with' clause) + ... + + # Get the final disk image + data = img.create() + """ + + # Partition-type codes + VFAT = 0xc + EXT4 = 0x83 + + def __init__(self, config, devnum, prefix): + """Set up a new disk image + + Args: + config (u_boot_config): U-Boot configuration + leaf (str): Leafname of the image, which will be placed in the + persistent-data directory + """ + self.fs_list = [] + self.fname = os.path.join(config.persistent_data_dir, + f'{prefix}{devnum}.img') + + def add_fs(self, fs_img, part_type, bootable=False): + """Add a new filesystem + + Args: + fs_img (FsHelper): Filesystem to add + part_type (DiskHelper.FAT or DiskHelper.EXT4): Partition type + bootable (bool): True to set the 'bootable' flat + """ + self.fs_list.append([fs_img, part_type, bootable]) + + def create(self): + """Create the disk image + + Create an image with a partition table and the filesystems + """ + spec = '' + pos = 1 # Reserve 1MB for the partition table itself + for fsi, part_type, bootable in self.fs_list: + if spec: + spec += '\n' + spec += f'type={part_type:x}, size={fsi.size_mb}M, start={pos}M' + if bootable: + spec += ', bootable' + pos += fsi.size_mb + + img_size = pos + try: + check_call(f'qemu-img create {self.fname} {img_size}M', shell=True) + check_call(f'printf "{spec}" | sfdisk {self.fname}', shell=True) + except CalledProcessError: + os.remove(self.fname) + raise + + pos = 1 # Reserve 1MB for the partition table itself + for fsi, part_type, bootable in self.fs_list: + check_call( + f'dd if={fsi.fs_img} of={self.fname} bs=1M seek={pos} conv=notrunc', + shell=True) + pos += fsi.size_mb + return self.fname + + def cleanup(self, remove_full_img=False): + """Remove created file""" + os.remove(self.fname) + + def __enter__(self): + return self + + def __exit__(self, extype, value, traceback): + self.cleanup() + + def mk_fs(config, fs_type, size, prefix, src_dir=None, size_gran = 0x100000, fs_img=None, quiet=False): """Create a file system volume -- 2.43.0