From patchwork Tue Aug 30 08:57:09 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mattias Backman X-Patchwork-Id: 3784 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9C80423F4D for ; Tue, 30 Aug 2011 08:57:12 +0000 (UTC) Received: from mail-bw0-f52.google.com (mail-bw0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id 4A340A18050 for ; Tue, 30 Aug 2011 08:57:12 +0000 (UTC) Received: by bkbzs2 with SMTP id zs2so7061387bkb.11 for ; Tue, 30 Aug 2011 01:57:12 -0700 (PDT) Received: by 10.223.62.73 with SMTP id w9mr1837828fah.138.1314694631784; Tue, 30 Aug 2011 01:57:11 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.11.8 with SMTP id m8cs127481lab; Tue, 30 Aug 2011 01:57:11 -0700 (PDT) Received: by 10.216.134.103 with SMTP id r81mr4679106wei.56.1314694630657; Tue, 30 Aug 2011 01:57:10 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com [91.189.90.7]) by mx.google.com with ESMTPS id 47si12839365wel.85.2011.08.30.01.57.10 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 30 Aug 2011 01:57:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QyK86-0007GN-0u for ; Tue, 30 Aug 2011 08:57:10 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id F1A4DE01C5 for ; Tue, 30 Aug 2011 08:57:09 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: linaro-image-tools X-Launchpad-Branch: ~linaro-image-tools/linaro-image-tools/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 428 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-image-tools/linaro-image-tools/trunk] Rev 428: Add hwpacks V2 support for Snowball. Message-Id: <20110830085709.23027.17155.launchpad@ackee.canonical.com> Date: Tue, 30 Aug 2011 08:57:09 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13794"; Instance="initZopeless config overlay" X-Launchpad-Hash: d8bcf018c5331146cb1c2c16d74f76e1e9dcac90 Merge authors: Mattias Backman (mabac) Related merge proposals: https://code.launchpad.net/~mabac/linaro-image-tools/hwpacks-v2-snowball/+merge/72898 proposed by: Mattias Backman (mabac) review: Approve - James Tunnicliffe (dooferlad) ------------------------------------------------------------ revno: 428 [merge] committer: Mattias Backman branch nick: trunk timestamp: Tue 2011-08-30 10:40:19 +0200 message: Add hwpacks V2 support for Snowball. modified: linaro_image_tools/hwpack/config.py linaro_image_tools/hwpack/hardwarepack.py linaro_image_tools/media_create/boards.py linaro_image_tools/media_create/tests/test_media_create.py --- lp:linaro-image-tools https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk You are subscribed to branch lp:linaro-image-tools. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk/+edit-subscription === modified file 'linaro_image_tools/hwpack/config.py' --- linaro_image_tools/hwpack/config.py 2011-08-18 15:46:52 +0000 +++ linaro_image_tools/hwpack/config.py 2011-08-25 13:42:55 +0000 @@ -64,6 +64,7 @@ BOOT_MIN_SIZE_KEY = "boot_min_size" ROOT_MIN_SIZE_KEY = "root_min_size" LOADER_MIN_SIZE_KEY = "loader_min_size" + LOADER_START_KEY = "loader_start" X_LOADER_PACKAGE_KEY = "x_loader_package" X_LOADER_FILE_KEY = "x_loader_file" VMLINUZ_KEY = "kernel_file" @@ -73,11 +74,12 @@ BOOT_SCRIPT_KEY = 'boot_script' UBOOT_IN_BOOT_PART_KEY = 'u_boot_in_boot_part' EXTRA_SERIAL_OPTS_KEY = 'extra_serial_options' + SNOWBALL_STARTUP_FILES_CONFIG_KEY = 'snowball_startup_files_config' DEFINED_PARTITION_LAYOUTS = [ 'bootfs16_rootfs', 'bootfs_rootfs', - #'reserved_bootfs_rootfs', + 'reserved_bootfs_rootfs', ] @@ -119,6 +121,7 @@ self._validate_boot_min_size() self._validate_root_min_size() self._validate_loader_min_size() + self._validate_loader_start() self._validate_x_loader_package() self._validate_x_loader_file() self._validate_vmlinuz() @@ -128,6 +131,7 @@ self._validate_boot_script() self._validate_uboot_in_boot_part() self._validate_extra_serial_opts() + self._validate_snowball_startup_files_config() self._validate_sections() @@ -223,6 +227,15 @@ return self._get_option_from_main_section(self.BOOT_SCRIPT_KEY) @property + def snowball_startup_files_config(self): + """File name of the snowball startfiles config file. + + A str. + """ + return self._get_option_from_main_section( + self.SNOWBALL_STARTUP_FILES_CONFIG_KEY) + + @property def kernel_addr(self): """address where u-boot should load the kernel @@ -313,6 +326,14 @@ return self._get_option_from_main_section(self.LOADER_MIN_SIZE_KEY) @property + def loader_start(self): + """Start of loader partition. If left out, defaults to 1. + + An int. + """ + return self._get_option_from_main_section(self.LOADER_START_KEY) + + @property def origin(self): """The origin that should be recorded in the hwpack. @@ -518,6 +539,14 @@ self._assert_matches_pattern( self.PATH_REGEX, boot_script, "Invalid path: %s" % boot_script) + + def _validate_snowball_startup_files_config(self): + snowball_startup_files_config = self.snowball_startup_files_config + if snowball_startup_files_config is not None: + self._assert_matches_pattern( + self.PATH_REGEX, snowball_startup_files_config, + "Invalid path: %s" % snowball_startup_files_config) + def _validate_serial_tty(self): serial_tty = self.serial_tty if serial_tty is None: @@ -609,6 +638,16 @@ raise HwpackConfigError( "Invalid loader min size %s" % (loader_min_size)) + def _validate_loader_start(self): + loader_start = self.loader_start + if loader_start is None: + return + try: + assert int(loader_start) > 0 + except: + raise HwpackConfigError( + "Invalid loader start %s" % (loader_start)) + def _validate_include_debs(self): try: self.include_debs === modified file 'linaro_image_tools/hwpack/hardwarepack.py' --- linaro_image_tools/hwpack/hardwarepack.py 2011-08-18 13:46:36 +0000 +++ linaro_image_tools/hwpack/hardwarepack.py 2011-08-25 13:42:55 +0000 @@ -84,7 +84,8 @@ loader_min_size=None, vmlinuz=None, initrd=None, dtb_addr=None, extra_boot_options=None, boot_script=None, uboot_in_boot_part=None, - extra_serial_opts=None): + extra_serial_opts=None, loader_start=None, + snowball_startup_files_config=None): """Add fields that are specific to the new format. These fields are not present in earlier config files. @@ -101,6 +102,7 @@ self.boot_min_size = boot_min_size self.root_min_size = root_min_size self.loader_min_size = loader_min_size + self.loader_start = loader_start self.x_loader = None self.vmlinuz = vmlinuz self.initrd = initrd @@ -110,6 +112,7 @@ self.boot_script = boot_script self.uboot_in_boot_part = uboot_in_boot_part self.extra_serial_opts = extra_serial_opts + self.snowball_startup_files_config = snowball_startup_files_config @classmethod def from_config(cls, config, version, architecture): @@ -146,6 +149,7 @@ boot_min_size=config.boot_min_size, root_min_size=config.root_min_size, loader_min_size=config.loader_min_size, + loader_start=config.loader_start, vmlinuz=config.vmlinuz, initrd=config.initrd, dtb_file=config.dtb_file, @@ -153,7 +157,8 @@ extra_boot_options=config.extra_boot_options, boot_script=config.boot_script, uboot_in_boot_part=config.uboot_in_boot_part, - extra_serial_opts=config.extra_serial_opts) + extra_serial_opts=config.extra_serial_opts, + snowball_startup_files_config=config.snowball_startup_files_config) return metadata def __str__(self): @@ -198,6 +203,8 @@ metadata += "ROOT_MIN_SIZE=%s\n" % self.root_min_size if self.loader_min_size is not None: metadata += "LOADER_MIN_SIZE=%s\n" % self.loader_min_size + if self.loader_start is not None: + metadata += "LOADER_START=%s\n" % self.loader_start if self.x_loader is not None: metadata += "X_LOADER=%s\n" % self.x_loader if self.vmlinuz is not None: @@ -214,6 +221,8 @@ metadata += "U_BOOT_IN_BOOT_PART=%s\n" % self.uboot_in_boot_part if self.extra_serial_opts is not None: metadata += "EXTRA_SERIAL_OPTIONS=%s\n" % self.extra_serial_opts + if self.snowball_startup_files_config is not None: + metadata += "SNOWBALL_STARTUP_FILES_CONFIG=%s\n" % self.snowball_startup_files_config return metadata === modified file 'linaro_image_tools/media_create/boards.py' --- linaro_image_tools/media_create/boards.py 2011-08-25 09:57:46 +0000 +++ linaro_image_tools/media_create/boards.py 2011-08-30 08:40:19 +0000 @@ -253,6 +253,8 @@ mmc_id = None vmlinuz = None initrd = None + partition_layout = None + LOADER_START_S = 1 hardwarepack_handler = None @@ -293,7 +295,8 @@ cls.dtb_addr = cls.get_metadata_field('dtb_addr') cls.serial_tty = cls.get_metadata_field('serial_tty') cls.wired_interfaces = cls.get_metadata_field('wired_interfaces') - cls.wireless_interfaces = cls.get_metadata_field('wireless_interfaces') + cls.wireless_interfaces = cls.get_metadata_field( + 'wireless_interfaces') cls.mmc_id = cls.get_metadata_field('mmc_id') cls.vmlinuz = cls.get_metadata_field('kernel_file') cls.initrd = cls.get_metadata_field('initrd_file') @@ -302,14 +305,18 @@ 'extra_boot_options') cls.boot_script = cls.get_metadata_field('boot_script') cls.extra_serial_opts = cls.get_metadata_field('extra_serial_options') + cls.snowball_startup_files_config = cls.get_metadata_field( + 'snowball_startup_files_config') - partition_layout = cls.get_metadata_field('partition_layout') - if partition_layout == 'bootfs_rootfs' or partition_layout is None: + cls.partition_layout = cls.get_metadata_field('partition_layout') + if cls.partition_layout in ['bootfs_rootfs', 'reserved_bootfs_rootfs', + None]: cls.fat_size = 32 - elif partition_layout == 'bootfs16_rootfs': + elif cls.partition_layout == 'bootfs16_rootfs': cls.fat_size = 16 else: - raise AssertionError("Unknown partition layout '%s'." % partition_layout) + raise AssertionError("Unknown partition layout '%s'." % \ + cls.partition_layout) boot_min_size = cls.get_metadata_field('boot_min_size') if boot_min_size is not None: @@ -332,6 +339,10 @@ elif string.lower(uboot_in_boot_part) == 'no': cls.uboot_in_boot_part = False + loader_start = cls.get_metadata_field('loader_start') + if loader_start is not None: + cls.LOADER_START_S = int(loader_start) + @classmethod def get_file(cls, file_alias, default=None): file_in_hwpack = cls.hardwarepack_handler.get_file(file_alias) @@ -341,13 +352,17 @@ return default @classmethod - def get_sfdisk_cmd(cls, should_align_boot_part=False): + def get_v1_sfdisk_cmd(cls, should_align_boot_part=False): """Return the sfdisk command to partition the media. :param should_align_boot_part: Whether to align the boot partition too. This default implementation returns a boot vfat partition of type FAT16 or FAT32, followed by a root partition. + + XXX: This default implementation and all overrides are left for V1 + compatibility only. They should be removed as part of the work to + kill off hwpacks V1. """ if cls.fat_size == 32: partition_type = '0x0C' @@ -379,6 +394,76 @@ boot_start, boot_len, partition_type, root_start) @classmethod + def get_normal_sfdisk_cmd(cls, should_align_boot_part=False): + """Return the sfdisk command to partition the media. + + :param should_align_boot_part: Whether to align the boot partition too. + + This returns a boot vfat partition of type FAT16 + or FAT32, followed by a root partition. + """ + if cls.fat_size == 32: + partition_type = '0x0C' + else: + partition_type = '0x0E' + + # align on sector 63 for compatibility with broken versions of x-loader + # unless align_boot_part is set + # XXX OMAP specific, might break other boards? + boot_align = 63 + if should_align_boot_part: + boot_align = PART_ALIGN_S + + # can only start on sector 1 (sector 0 is MBR / partition table) + boot_start, boot_end, boot_len = align_partition( + 1, cls.BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S) + # apparently OMAP3 ROMs require the vfat length to be an even number + # of sectors (multiple of 1 KiB); decrease the length if it's odd, + # there should still be enough room + # XXX OMAP specific, might break other boards? + boot_len = boot_len - boot_len % 2 + boot_end = boot_start + boot_len - 1 + + # we ignore _root_end / _root_len and return a sfdisk command to + # instruct the use of all remaining space; XXX we now have root size + # config, so we can do something more sensible + root_start, _root_end, _root_len = align_partition( + boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) + + return '%s,%s,%s,*\n%s,,,-' % ( + boot_start, boot_len, partition_type, root_start) + + @classmethod + def get_reserved_sfdisk_cmd(cls, should_align_boot_part=None): + """Return the sfdisk command to partition the media. + + :param should_align_boot_part: Ignored. + + This returns a loader partition, then a boot vfat partition of type + FAT16 or FAT32, followed by a root partition. + """ + loader_start, loader_end, loader_len = align_partition( + cls.LOADER_START_S, cls.LOADER_MIN_SIZE_S, 1, PART_ALIGN_S) + + boot_start, boot_end, boot_len = align_partition( + loader_end + 1, cls.BOOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) + + root_start, _root_end, _root_len = align_partition( + boot_end + 1, cls.ROOT_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S) + + return '%s,%s,0xDA\n%s,%s,0x0C,*\n%s,,,-' % ( + loader_start, loader_len, boot_start, boot_len, root_start) + + @classmethod + def get_sfdisk_cmd(cls, should_align_boot_part=False): + if cls.partition_layout in ['bootfs_rootfs', 'bootfs16_rootfs']: + return cls.get_normal_sfdisk_cmd(should_align_boot_part) + elif cls.partition_layout in ['reserved_bootfs_rootfs']: + return cls.get_reserved_sfdisk_cmd(should_align_boot_part) + else: + return cls.get_v1_sfdisk_cmd(should_align_boot_part) + + @classmethod def _get_bootcmd(cls, d_img_data): """Get the bootcmd for this board. @@ -743,11 +828,11 @@ # puts the MBR, so the boot loader skips that address. supports_writing_to_mmc = False SNOWBALL_LOADER_START_S = (128 * 1024) / SECTOR_SIZE - SNOWBALL_STARTUP_FILES_CONFIG = 'startfiles.cfg' + snowball_startup_files_config = 'startfiles.cfg' TOC_SIZE = 512 @classmethod - def get_sfdisk_cmd(cls, should_align_boot_part=None): + def get_v1_sfdisk_cmd(cls, should_align_boot_part=None): """Return the sfdisk command to partition the media. :param should_align_boot_part: Ignored. @@ -800,7 +885,7 @@ cls.SNOWBALL_LOADER_START_S) cls.delete_file(toc_filename) cls.delete_file(os.path.join(config_files_path, - cls.SNOWBALL_STARTUP_FILES_CONFIG)) + cls.snowball_startup_files_config)) @classmethod def install_snowball_boot_loader(cls, toc_file_name, files, @@ -860,7 +945,7 @@ ofs = cls.TOC_SIZE files = [] bin_dir = os.path.join(chroot_dir, 'boot') - with open(os.path.join(bin_dir, cls.SNOWBALL_STARTUP_FILES_CONFIG), + with open(os.path.join(bin_dir, cls.snowball_startup_files_config), 'r') as info_file: for line in info_file: file_data = line.split() @@ -904,7 +989,7 @@ return cls._extra_serial_opts % cls.serial_tty @classmethod - def get_sfdisk_cmd(cls, should_align_boot_part=None): + def get_v1_sfdisk_cmd(cls, should_align_boot_part=None): """Return the sfdisk command to partition the media. :param should_align_boot_part: Ignored. @@ -1020,7 +1105,7 @@ return cls._extra_serial_opts % cls.serial_tty @classmethod - def get_sfdisk_cmd(cls, should_align_boot_part=False): + def get_v1_sfdisk_cmd(cls, should_align_boot_part=False): # bootloaders partition needs to hold BL1, U-Boot environment, and BL2 loaders_min_len = ( SAMSUNG_V310_BL2_START + SAMSUNG_V310_BL2_LEN - === modified file 'linaro_image_tools/media_create/tests/test_media_create.py' --- linaro_image_tools/media_create/tests/test_media_create.py 2011-08-25 09:57:46 +0000 +++ linaro_image_tools/media_create/tests/test_media_create.py 2011-08-30 08:40:19 +0000 @@ -46,6 +46,7 @@ from linaro_image_tools.media_create.boards import ( SAMSUNG_V310_BL1_START, SAMSUNG_V310_BL2_START, + SAMSUNG_V310_BL2_LEN, SECTOR_SIZE, align_up, align_partition, @@ -685,7 +686,7 @@ ('UBOOT_ENV', 'u-boot-env.bin', 0, 0x00C1F000, '10')] # Create a config file cfg_file = os.path.join(self.temp_bootdir_path, - boards.SnowballEmmcConfig.SNOWBALL_STARTUP_FILES_CONFIG) + boards.SnowballEmmcConfig.snowball_startup_files_config) with open(cfg_file, 'w') as f: for line in src_data: # Write comments, so we test that the parser can read them @@ -719,7 +720,7 @@ def test_get_file_info_relative_path(self): # Create a config file cfg_file = os.path.join(self.temp_bootdir_path, - boards.SnowballEmmcConfig.SNOWBALL_STARTUP_FILES_CONFIG) + boards.SnowballEmmcConfig.snowball_startup_files_config) uboot_file = 'u-boot.bin' with open(cfg_file, 'w') as f: f.write('%s %s %i %#x %s\n' % ('NORMAL', uboot_file, 0, @@ -733,7 +734,7 @@ def test_get_file_info_abs_path(self): # Create a config file cfg_file = os.path.join(self.temp_bootdir_path, - boards.SnowballEmmcConfig.SNOWBALL_STARTUP_FILES_CONFIG) + boards.SnowballEmmcConfig.snowball_startup_files_config) uboot_dir = tempfile.mkdtemp(dir=self.tempdir) uboot_file = os.path.join(uboot_dir, 'u-boot.bin') uboot_relative_file = uboot_file.replace(self.tempdir, '') @@ -748,7 +749,7 @@ def test_get_file_info_raises(self): # Create a config file cfg_file = os.path.join(self.temp_bootdir_path, - boards.SnowballEmmcConfig.SNOWBALL_STARTUP_FILES_CONFIG) + boards.SnowballEmmcConfig.snowball_startup_files_config) with open(cfg_file, 'w') as f: f.write('%s %s %i %#x %s\n' % ('NORMAL', 'u-boot.bin', 0, 0xBA0000, '9')) @@ -1142,6 +1143,50 @@ '794624,-,E\n794624,524288,L\n1318912,1048576,L\n2367488,,,-', android_boards.AndroidSnowballEmmcConfig.get_sfdisk_cmd()) +class TestGetSfdiskCmdV2(TestCase): + + def test_mx5(self): + class config(boards.Mx5Config): + partition_layout = 'reserved_bootfs_rootfs' + self.assertEqual( + '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', + config.get_sfdisk_cmd()) + + def test_snowball_sd(self): + class config(boards.SnowballSdConfig): + partition_layout = 'bootfs_rootfs' + self.assertEqual( + '63,106432,0x0C,*\n106496,,,-', + config.get_sfdisk_cmd()) + + def test_snowball_emmc(self): + class config(boards.SnowballEmmcConfig): + partition_layout = 'reserved_bootfs_rootfs' + LOADER_START_S = (128 * 1024) / SECTOR_SIZE + self.assertEqual( + '256,7936,0xDA\n8192,106496,0x0C,*\n114688,,,-', + config.get_sfdisk_cmd()) + + def test_smdkv310(self): + class config(board_configs['smdkv310']): + partition_layout = 'reserved_bootfs_rootfs' + LOADER_MIN_SIZE_S = (SAMSUNG_V310_BL2_START + + SAMSUNG_V310_BL2_LEN - + SAMSUNG_V310_BL1_START) + self.assertEquals( + '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', + config.get_sfdisk_cmd()) + + def test_origen(self): + class config(board_configs['origen']): + partition_layout = 'reserved_bootfs_rootfs' + LOADER_MIN_SIZE_S = (SAMSUNG_V310_BL2_START + + SAMSUNG_V310_BL2_LEN - + SAMSUNG_V310_BL1_START) + self.assertEquals( + '1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-', + config.get_sfdisk_cmd()) + class TestGetBootCmd(TestCase):