diff options
-rw-r--r-- | linaro_image_tools/media_create/android_boards.py | 31 | ||||
-rw-r--r-- | linaro_image_tools/media_create/boards.py | 47 | ||||
-rw-r--r-- | linaro_image_tools/media_create/tests/test_media_create.py | 282 |
3 files changed, 338 insertions, 22 deletions
diff --git a/linaro_image_tools/media_create/android_boards.py b/linaro_image_tools/media_create/android_boards.py index 735d2d4..2d8d9c6 100644 --- a/linaro_image_tools/media_create/android_boards.py +++ b/linaro_image_tools/media_create/android_boards.py @@ -37,6 +37,7 @@ from linaro_image_tools.media_create.boards import VexpressA9Config from linaro_image_tools.media_create.boards import ( align_up, align_partition, + classproperty, make_boot_script, install_mx5_boot_loader, ) @@ -238,6 +239,36 @@ class AndroidSnowballEmmcConfig(AndroidBoardConfig, SnowballEmmcConfig): return '%s,%s,0xDA\n%s' % ( loader_start, loader_len, command) + @classmethod + def populate_raw_partition(cls, media, boot_dir): + # To avoid adding a Snowball specific command line option, we assume + # that the user already has unpacked the startfiles to ./startupfiles + config_files_dir = cls.snowball_config(boot_dir) + assert os.path.exists(config_files_dir), ( + "You need to unpack the Snowball startupfiles to the directory " + "'startupfiles' in your current working directory. See " + "igloocommunity.org for more information.") + # We copy the u-boot files from the unpacked boot.tar.bz2 + # and put it with the startfiles. + boot_files = ['u-boot.bin'] + for boot_file in boot_files: + cmd_runner.run(['cp', os.path.join(boot_dir, 'boot', boot_file), + config_files_dir], as_root=True).wait() + super(AndroidSnowballEmmcConfig, cls).populate_raw_partition( + media, boot_dir) + + @classmethod + def snowball_config(cls, chroot_dir): + # The user is expected to have unpacked the startupfiles to this subdir + # of their working dir. + return os.path.join('.', 'startupfiles') + + @classproperty + def delete_startupfiles(cls): + # The startupfiles will have been unpacked to the user's working dir + # and should not be deleted after they have been installed. + return False + class AndroidMx53LoCoConfig(AndroidBoardConfig, Mx53LoCoConfig): extra_boot_args_options = ( diff --git a/linaro_image_tools/media_create/boards.py b/linaro_image_tools/media_create/boards.py index 2b1ce0d..c484f97 100644 --- a/linaro_image_tools/media_create/boards.py +++ b/linaro_image_tools/media_create/boards.py @@ -820,6 +820,13 @@ class BoardConfig(object): # Override in subclass if needed pass + @classmethod + def snowball_config(cls, chroot_dir): + # Override in subclasses where applicable + raise NotImplementedError( + "snowball_config() must only be called on BoardConfigs that use the " + "Snowball startupfiles.") + class OmapConfig(BoardConfig): kernel_flavors = ['linaro-omap4', 'linaro-lt-omap', 'linaro-omap', 'omap4'] @@ -1075,21 +1082,36 @@ class SnowballEmmcConfig(SnowballSdConfig): @classmethod def populate_raw_partition(cls, boot_device_or_file, chroot_dir): # Populate created raw partition with TOC and startup files. - config_files_path = os.path.join(chroot_dir, 'boot') _, toc_filename = tempfile.mkstemp() - new_files = cls.get_file_info(chroot_dir) + config_files_dir = cls.snowball_config(chroot_dir) + new_files = cls.get_file_info(chroot_dir, config_files_dir) with open(toc_filename, 'wb') as toc: cls.create_toc(toc, new_files) cls.install_snowball_boot_loader(toc_filename, new_files, - boot_device_or_file, - cls.SNOWBALL_LOADER_START_S) + boot_device_or_file, + cls.SNOWBALL_LOADER_START_S, + cls.delete_startupfiles) cls.delete_file(toc_filename) - cls.delete_file(os.path.join(config_files_path, - cls.snowball_startup_files_config)) + if cls.delete_startupfiles: + cls.delete_file(os.path.join(config_files_dir, + cls.snowball_startup_files_config)) + + @classmethod + def snowball_config(cls, chroot_dir): + # We will find the startupfiles in the target boot partition. + return os.path.join(chroot_dir, 'boot') + + @classproperty + def delete_startupfiles(cls): + # The startupfiles will have been installed to the target boot + # partition by the hwpack, and should be deleted so we don't leave + # them on the target system. + return True @classmethod def install_snowball_boot_loader(cls, toc_file_name, files, - boot_device_or_file, start_sector): + boot_device_or_file, start_sector, + delete_startupfiles=False): ''' Copies TOC and boot files into the boot partition. A sector size of 1 is used for some files, as they do not necessarily start on an even address. ''' @@ -1107,7 +1129,8 @@ class SnowballEmmcConfig(SnowballSdConfig): else: seek_sectors = start_sector + file['offset'] / SECTOR_SIZE _dd(filename, boot_device_or_file, seek=seek_sectors) - cls.delete_file(filename) + if delete_startupfiles: + cls.delete_file(filename) @classmethod def delete_file(cls, file_path): @@ -1138,14 +1161,14 @@ class SnowballEmmcConfig(SnowballSdConfig): f.write(data) @classmethod - def get_file_info(cls, chroot_dir): + def get_file_info(cls, chroot_dir, config_files_dir): ''' Fills in the offsets of files that are located in non-absolute memory locations depending on their sizes.' Also fills in file sizes''' 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(config_files_dir, + cls.snowball_startup_files_config), 'r') as info_file: for line in info_file: file_data = line.split() @@ -1158,7 +1181,7 @@ class SnowballEmmcConfig(SnowballSdConfig): filename = os.path.join(chroot_dir, file_data[1].lstrip('/')) else: - filename = os.path.join(bin_dir, file_data[1]) + filename = os.path.join(config_files_dir, file_data[1]) assert os.path.exists(filename), "File %s does not exist, " \ "please check the startfiles config file." % file_data[1] address = long(file_data[3], 16) diff --git a/linaro_image_tools/media_create/tests/test_media_create.py b/linaro_image_tools/media_create/tests/test_media_create.py index 08c140c..1be2068 100644 --- a/linaro_image_tools/media_create/tests/test_media_create.py +++ b/linaro_image_tools/media_create/tests/test_media_create.py @@ -65,6 +65,7 @@ from linaro_image_tools.media_create.boards import ( ) from linaro_image_tools.media_create.android_boards import ( android_board_configs, + AndroidSnowballEmmcConfig, ) from linaro_image_tools.media_create.chroot_utils import ( copy_file, @@ -667,10 +668,19 @@ class TestSnowballBootFiles(TestCaseWithFixtures): super(TestSnowballBootFiles, self).setUp() self.tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir() self.temp_bootdir_path = os.path.join(self.tempdir, 'boot') + self.temp_configdir_path = os.path.join(self.tempdir, 'startfiles') if not os.path.exists(self.temp_bootdir_path): os.makedirs(self.temp_bootdir_path) + if not os.path.exists(self.temp_configdir_path): + os.makedirs(self.temp_configdir_path) def setupFiles(self): + return self.create_test_files(self.temp_bootdir_path) + + def setupAndroidFiles(self): + return self.create_test_files(self.temp_configdir_path) + + def create_test_files(self, path): ''' Adds some files in the temp dir that the tested function can use as input: * A config file, which the tested function reads to @@ -687,8 +697,8 @@ class TestSnowballBootFiles(TestCaseWithFixtures): ('NORMAL', 'u-boot.bin', 0, 0xBA0000, '9'), ('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) + cfg_file = os.path.join( + path, 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 @@ -700,7 +710,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): # Define dummy binary files, containing nothing but their own # section names. for line in src_data: - with open(os.path.join(self.temp_bootdir_path, line[1]), 'w') as f: + with open(os.path.join(path, line[1]), 'w') as f: f.write(line[0]) #define the expected values read from the config file expected = [] @@ -711,7 +721,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): len('PWR_MGT'), len('NORMAL'), len('UBOOT_ENV')] i = 0 for line in src_data: - filename = os.path.join(self.temp_bootdir_path, line[1]) + filename = os.path.join(path, line[1]) expected.append({'section_name': line[0], 'filename': filename, 'align': int(line[2]), @@ -731,7 +741,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): 0xBA0000, '9')) with open(os.path.join(self.temp_bootdir_path, uboot_file), 'w') as f: file_info = boards.SnowballEmmcConfig.get_file_info( - self.tempdir) + self.tempdir, self.temp_bootdir_path) self.assertEquals(file_info[0]['filename'], os.path.join(self.temp_bootdir_path, uboot_file)) @@ -747,7 +757,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): 0xBA0000, '9')) with open(uboot_file, 'w') as f: file_info = boards.SnowballEmmcConfig.get_file_info( - self.tempdir) + self.tempdir, self.temp_bootdir_path) self.assertEquals(file_info[0]['filename'], uboot_file) def test_get_file_info_raises(self): @@ -758,7 +768,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): f.write('%s %s %i %#x %s\n' % ('NORMAL', 'u-boot.bin', 0, 0xBA0000, '9')) self.assertRaises(AssertionError, boards.SnowballEmmcConfig.get_file_info, - self.tempdir) + self.tempdir, self.temp_bootdir_path) def test_file_name_size(self): ''' Test using a to large toc file ''' @@ -776,7 +786,7 @@ class TestSnowballBootFiles(TestCaseWithFixtures): toc_filename, files, "boot_device_or_file", boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S) - def test_install_snowball_boot_loader_toc(self): + def test_install_snowball_boot_loader_toc_dont_delete(self): fixture = self.useFixture(MockCmdRunnerPopenFixture()) toc_filename = self.createTempFileAsFixture() files = self.setupFiles() @@ -789,6 +799,33 @@ class TestSnowballBootFiles(TestCaseWithFixtures): boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S), '%s dd if=%s/boot_image_issw.bin of=boot_device_or_file bs=512' \ ' conv=notrunc seek=257' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/boot_image_x-loader.bin of=boot_device_or_file' \ + ' bs=1 conv=notrunc seek=131588' + % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/mem_init.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=3072' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/power_management.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=3200' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/u-boot.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=24064' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/u-boot-env.bin of=boot_device_or_file bs=512' + ' conv=notrunc seek=25080' % (sudo_args, self.temp_bootdir_path)] + + self.assertEqual(expected, fixture.mock.commands_executed) + + def test_install_snowball_boot_loader_toc_delete(self): + fixture = self.useFixture(MockCmdRunnerPopenFixture()) + toc_filename = self.createTempFileAsFixture() + files = self.setupFiles() + boards.SnowballEmmcConfig.install_snowball_boot_loader(toc_filename, + files, "boot_device_or_file", + boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S, True) + expected = [ + '%s dd if=%s of=boot_device_or_file bs=512 conv=notrunc' \ + ' seek=%s' % (sudo_args, toc_filename, + boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S), + '%s dd if=%s/boot_image_issw.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=257' % (sudo_args, self.temp_bootdir_path), '%s rm %s/boot_image_issw.bin' % (sudo_args, self.temp_bootdir_path), '%s dd if=%s/boot_image_x-loader.bin of=boot_device_or_file' \ @@ -812,6 +849,33 @@ class TestSnowballBootFiles(TestCaseWithFixtures): self.assertEqual(expected, fixture.mock.commands_executed) + def test_install_snowball_boot_loader_toc_android(self): + fixture = self.useFixture(MockCmdRunnerPopenFixture()) + toc_filename = self.createTempFileAsFixture() + files = self.setupFiles() + AndroidSnowballEmmcConfig.install_snowball_boot_loader( + toc_filename, files, "boot_device_or_file", + AndroidSnowballEmmcConfig.SNOWBALL_LOADER_START_S) + expected = [ + '%s dd if=%s of=boot_device_or_file bs=512 conv=notrunc' \ + ' seek=%s' % (sudo_args, toc_filename, + AndroidSnowballEmmcConfig.SNOWBALL_LOADER_START_S), + '%s dd if=%s/boot_image_issw.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=257' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/boot_image_x-loader.bin of=boot_device_or_file' \ + ' bs=1 conv=notrunc seek=131588' + % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/mem_init.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=3072' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/power_management.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=3200' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/u-boot.bin of=boot_device_or_file bs=512' \ + ' conv=notrunc seek=24064' % (sudo_args, self.temp_bootdir_path), + '%s dd if=%s/u-boot-env.bin of=boot_device_or_file bs=512' + ' conv=notrunc seek=25080' % (sudo_args, self.temp_bootdir_path)] + + self.assertEqual(expected, fixture.mock.commands_executed) + def test_snowball_make_boot_files(self): fixture = self.useFixture(MockCmdRunnerPopenFixture()) self.useFixture(MockSomethingFixture(tempfile, 'mkstemp', @@ -868,12 +932,12 @@ class TestSnowballBootFiles(TestCaseWithFixtures): '''When the files cannot be read, an IOError should be raised''' self.assertRaises(IOError, boards.SnowballEmmcConfig.get_file_info, - self.tempdir) + self.tempdir, self.temp_bootdir_path) def test_normal_case(self): expected = self.setupFiles() actual = boards.SnowballEmmcConfig.get_file_info( - self.tempdir) + self.tempdir, self.temp_bootdir_path) self.assertEquals(expected, actual) @@ -1026,6 +1090,204 @@ class TestBootSteps(TestCaseWithFixtures): 'make_dtb', 'make_boot_script', 'make_boot_ini'] self.assertEqual(expected, self.funcs_calls) +class TestPopulateRawPartition(TestCaseWithFixtures): + + def setUp(self): + super(TestPopulateRawPartition, self).setUp() + self.funcs_calls = [] + self.mock_all_boards_funcs() + + def mock_all_boards_funcs(self): + """Mock functions of boards module with a call tracer.""" + + def mock_func_creator(name): + return lambda *args, **kwargs: self.funcs_calls.append(name) + + for name in dir(boards): + attr = getattr(boards, name) + if type(attr) == types.FunctionType: + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.boards, name, + mock_func_creator(name))) + + def populate_raw_partition(self, config): + config.populate_raw_partition('', '') + + def test_snowball_config_raises(self): + self.assertRaises(NotImplementedError, + boards.SnowballSdConfig.snowball_config, '') + + def test_beagle_raw(self): + self.populate_raw_partition(android_boards.AndroidBeagleConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_panda_raw(self): + self.populate_raw_partition(android_boards.AndroidPandaConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_snowball_sd_raw(self): + self.populate_raw_partition(boards.SnowballSdConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_snowball_emmc_raw(self): + def mock_func_creator(name): + return classmethod( + lambda *args, **kwargs: self.funcs_calls.append(name)) + + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.boards.SnowballEmmcConfig, + 'get_file_info', + mock_func_creator('get_file_info'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.boards.SnowballEmmcConfig, + 'create_toc', + mock_func_creator('create_toc'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.boards.SnowballEmmcConfig, + 'install_snowball_boot_loader', + mock_func_creator('install_snowball_boot_loader'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.boards.SnowballEmmcConfig, + 'delete_file', + mock_func_creator('delete_file'))) + self.populate_raw_partition(boards.SnowballEmmcConfig) + expected = ['get_file_info', 'create_toc', + 'install_snowball_boot_loader', 'delete_file', + 'delete_file'] + # Test that we run the Snowball populate_raw_partition() and + # delete both the toc and startfiles. + self.assertEqual(expected, self.funcs_calls) + + def test_smdkv310_raw(self): + self.useFixture(MockSomethingFixture(os.path, 'getsize', + lambda file: 1)) + + self.populate_raw_partition(boards.SMDKV310Config) + expected = ['_dd', '_dd', '_dd'] + self.assertEqual(expected, self.funcs_calls) + + def test_mx53loco_raw(self): + self.populate_raw_partition(boards.Mx53LoCoConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_origen_raw(self): + self.useFixture(MockSomethingFixture(os.path, 'getsize', + lambda file: 1)) + + self.populate_raw_partition(boards.OrigenConfig) + expected = ['_dd', '_dd', '_dd'] + self.assertEqual(expected, self.funcs_calls) + + def test_vexpress_a9_raw(self): + self.populate_raw_partition(boards.VexpressA9Config) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + +class TestPopulateRawPartitionAndroid(TestCaseWithFixtures): + + def setUp(self): + super(TestPopulateRawPartitionAndroid, self).setUp() + self.funcs_calls = [] + + def populate_raw_partition(self, config): + config.populate_raw_partition('', '') + + def test_beagle_raw(self): + self.populate_raw_partition(android_boards.AndroidBeagleConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_panda_raw(self): + self.populate_raw_partition(android_boards.AndroidPandaConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_snowball_sd_raw(self): + self.populate_raw_partition(android_boards.AndroidSnowballSdConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_snowball_emmc_raw(self): + def mock_func_creator(name): + return classmethod( + lambda *args, **kwargs: self.funcs_calls.append(name)) + + fixture = MockCmdRunnerPopenFixture() + self.useFixture(fixture) + expected_commands = ['sudo -E cp boot/u-boot.bin ./startupfiles'] + + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.android_boards.AndroidSnowballEmmcConfig, + 'get_file_info', + mock_func_creator('get_file_info'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.android_boards.AndroidSnowballEmmcConfig, + 'create_toc', + mock_func_creator('create_toc'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.android_boards.AndroidSnowballEmmcConfig, + 'install_snowball_boot_loader', + mock_func_creator('install_snowball_boot_loader'))) + self.useFixture(MockSomethingFixture( + linaro_image_tools.media_create.android_boards.AndroidSnowballEmmcConfig, + 'delete_file', + mock_func_creator('delete_file'))) + self.populate_raw_partition(android_boards.AndroidSnowballEmmcConfig) + expected_calls = ['get_file_info', 'create_toc', + 'install_snowball_boot_loader', 'delete_file'] + # Test that we copy the u-boot files to the local startupfiles dir. + self.assertEqual(expected_commands, fixture.mock.commands_executed) + # Test that we run the Snowball populate_raw_partition() and only + # delete the toc. + self.assertEqual(expected_calls, self.funcs_calls) + + def test_smdkv310_raw(self): + fixture = MockCmdRunnerPopenFixture() + self.useFixture(fixture) + expected_commands = [ + 'sudo -E dd if=/dev/zero of= bs=512 conv=notrunc count=32 seek=33', + 'sudo -E dd if=boot/u-boot-mmc-spl.bin of= bs=512 conv=notrunc seek=1', + 'sudo -E dd if=boot/u-boot.bin of= bs=512 conv=notrunc seek=65'] + self.useFixture(MockSomethingFixture(os.path, 'getsize', + lambda file: 1)) + + self.populate_raw_partition(android_boards.AndroidSMDKV310Config) + expected_calls = [] + # Test that we dd the files + self.assertEqual(expected_commands, fixture.mock.commands_executed) + self.assertEqual(expected_calls, self.funcs_calls) + + def test_mx53loco_raw(self): + self.populate_raw_partition(android_boards.AndroidMx53LoCoConfig) + expected = [] + self.assertEqual(expected, self.funcs_calls) + + def test_origen_raw(self): + fixture = MockCmdRunnerPopenFixture() + self.useFixture(fixture) + expected_commands = [ + 'sudo -E dd if=/dev/zero of= bs=512 conv=notrunc count=32 seek=33', + 'sudo -E dd if=boot/u-boot-mmc-spl.bin of= bs=512 conv=notrunc seek=1', + 'sudo -E dd if=boot/u-boot.bin of= bs=512 conv=notrunc seek=65'] + self.useFixture(MockSomethingFixture(os.path, 'getsize', + lambda file: 1)) + + self.populate_raw_partition(android_boards.AndroidOrigenConfig) + expected = [] + # Test that we dd the files + self.assertEqual(expected_commands, fixture.mock.commands_executed) + self.assertEqual(expected, self.funcs_calls) + + def test_vexpress_a9_raw(self): + self.populate_raw_partition(android_boards.AndroidVexpressA9Config) + expected = [] + self.assertEqual(expected, self.funcs_calls) + class TestAlignPartition(TestCase): |