=== modified file 'linaro-android-media-create'
@@ -133,12 +133,13 @@
unpack_android_binary_tarball(args.system, SYSTEM_DIR)
unpack_android_binary_tarball(args.userdata, DATA_DIR)
- # Create partitions
+ # Create partitions
boot_partition, system_partition, cache_partition, \
data_partition, sdcard_partition = setup_android_partitions( \
board_config, media, args.image_size, args.boot_label,
args.should_create_partitions, args.should_align_boot_part)
+ board_config.populate_raw_partition(args.device, BOOT_DIR)
populate_partition(BOOT_DIR + "/boot", BOOT_DISK, boot_partition)
board_config.populate_boot_script(boot_partition, BOOT_DISK, args.consoles)
populate_partition(SYSTEM_DIR + "/system", SYSTEM_DISK, system_partition)
=== modified file 'linaro_image_tools/media_create/android_boards.py'
@@ -28,6 +28,8 @@
from linaro_image_tools.media_create.boards import PART_ALIGN_S
from linaro_image_tools.media_create.boards import BeagleConfig
from linaro_image_tools.media_create.boards import PandaConfig
+from linaro_image_tools.media_create.boards import SnowballSdConfig
+from linaro_image_tools.media_create.boards import SnowballEmmcConfig
from linaro_image_tools.media_create.boards import (
align_up,
align_partition,
@@ -37,6 +39,7 @@
from linaro_image_tools import cmd_runner
import os
+
class AndroidBoardConfig(object):
@classmethod
def _get_bootargs(cls, consoles):
@@ -78,7 +81,7 @@
as_root=True).wait()
boot_env = cls._get_boot_env(consoles)
- cmdline_filepath = os.path.join(boot_disk, "cmdline")
+ cmdline_filepath = os.path.join(boot_disk, "cmdline")
cmdline_file = open(cmdline_filepath, 'r')
android_kernel_cmdline = cmdline_file.read()
boot_env['bootargs'] = boot_env['bootargs'] + ' ' + \
@@ -96,7 +99,8 @@
pass
@classmethod
- def get_sfdisk_cmd(cls, should_align_boot_part=False):
+ def get_sfdisk_cmd(cls, should_align_boot_part=False,
+ start_addr=0, extra_part=False):
if cls.fat_size == 32:
partition_type = '0x0C'
else:
@@ -116,7 +120,7 @@
# can only start on sector 1 (sector 0 is MBR / partition table)
boot_start, boot_end, boot_len = align_partition(
- 1, BOOT_MIN_SIZE_S, boot_align, PART_ALIGN_S)
+ start_addr + 1, 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
@@ -131,12 +135,28 @@
_cache_end + 1, USERDATA_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
sdcard_start, _sdcard_end, _sdcard_len = align_partition(
_userdata_end + 1, SDCARD_MIN_SIZE_S, PART_ALIGN_S, PART_ALIGN_S)
-
+
+ # Snowball board needs a raw partition added to the beginning of image.
+ # If extra_part is True an extra primary partition will be added.
+ # Due to a maximum of 4 primary partitions cache data will be placed in
+ # a extended partition
+ if extra_part == True:
+ assert start_addr > 0, ("Not possible to add extra partition" \
+ "when boot partition starts at '0'")
+ return '%s,%s,%s,*\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,%s,L\n%s,,,-' % (
+ boot_start, boot_len, partition_type, system_start, _system_len,
+ cache_start, cache_start, _cache_len, userdata_start,
+ _userdata_len, sdcard_start)
+
return '%s,%s,%s,*\n%s,%s,L\n%s,%s,L\n%s,-,E\n%s,%s,L\n%s,,,-' % (
boot_start, boot_len, partition_type, system_start, _system_len,
cache_start, _cache_len, userdata_start, userdata_start,
_userdata_len, sdcard_start)
+ @classmethod
+ def populate_raw_partition(cls, media, boot_dir):
+ super(AndroidBoardConfig, cls).populate_raw_partition(boot_dir, media)
+
class AndroidOmapConfig(AndroidBoardConfig):
pass
@@ -155,7 +175,44 @@
android_specific_args = 'init=/init androidboot.console=ttyO2'
+class AndroidSnowballSdConfig(AndroidBoardConfig, SnowballSdConfig):
+ extra_boot_args_options = (
+ 'earlyprintk rootdelay=1 fixrtc nocompcache '
+ 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M hwmem=167M@216M '
+ 'mem_issw=1M@383M mem=640M@384M vmalloc=256M')
+ _extra_serial_opts = 'console=tty0 console=ttyO2,115200n8'
+ android_specific_args = 'init=/init androidboot.console=ttyAMA2'
+
+
+class AndroidSnowballEmmcConfig(AndroidBoardConfig, SnowballEmmcConfig):
+ extra_boot_args_options = (
+ 'earlyprintk rootdelay=1 fixrtc nocompcache '
+ 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M hwmem=167M@216M '
+ 'mem_issw=1M@383M mem=640M@384M vmalloc=256M')
+ _extra_serial_opts = 'console=tty0 console=ttyAMA2,115200n8'
+ android_specific_args = 'init=/init androidboot.console=ttyAMA2'
+
+ @classmethod
+ def get_sfdisk_cmd(cls, should_align_boot_part=False):
+
+ LOADER_MIN_SIZE_S = align_up(
+ 1 * 1024 * 1024, SECTOR_SIZE) / SECTOR_SIZE
+
+ loader_start, loader_end, loader_len = align_partition(
+ SnowballEmmcConfig.SNOWBALL_LOADER_START_S,
+ LOADER_MIN_SIZE_S, 1, PART_ALIGN_S)
+
+ command = super(AndroidSnowballEmmcConfig, cls).get_sfdisk_cmd(
+ should_align_boot_part=True, start_addr=loader_end,
+ extra_part=True)
+
+ return '%s,%s,0xDA\n%s' % (
+ loader_start, loader_len, command)
+
+
android_board_configs = {
'beagle': AndroidBeagleConfig,
'panda': AndroidPandaConfig,
+ 'snowball_sd': AndroidSnowballSdConfig,
+ 'snowball_emmc': AndroidSnowballEmmcConfig,
}
=== modified file 'linaro_image_tools/media_create/boards.py'
@@ -58,6 +58,7 @@
# align on 4 MiB
PART_ALIGN_S = 4 * 1024 * 1024 / SECTOR_SIZE
+
def align_up(value, align):
"""Round value to the next multiple of align."""
return (value + align - 1) / align * align
@@ -104,6 +105,7 @@
assert SAMSUNG_V310_BL2_LEN * SECTOR_SIZE == 512 * 1024, (
"BL1 expects BL2 (u-boot) to be 512 KiB")
+
def align_partition(min_start, min_length, start_alignment, end_alignment):
"""Compute partition start and end offsets based on specified constraints.
@@ -125,6 +127,7 @@
"""A descriptor that provides @property behavior on class methods."""
def __init__(self, getter):
self.getter = getter
+
def __get__(self, instance, cls):
return self.getter(cls)
@@ -337,6 +340,11 @@
"No kernel found matching %s for flavors %s" % (
KERNEL_GLOB, " ".join(cls.kernel_flavors)))
+ @classmethod
+ def populate_raw_partition(cls, media, boot_dir):
+ # Override in subclass if needed
+ pass
+
class OmapConfig(BoardConfig):
kernel_flavors = ['linaro-omap4', 'linaro-lt-omap', 'linaro-omap', 'omap4']
@@ -517,7 +525,7 @@
and u-boot.'''
# Boot ROM looks for a boot table of contents (TOC) at 0x20000
# Actually, it first looks at address 0, but that's where l-m-c
- # puts the MBR, so the boot loader skips that address.
+ # 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'
@@ -537,11 +545,11 @@
This is done since the boot rom always boots off the internal memory;
there simply is no point to having a loader partition on SD card.
"""
- # boot ROM expects bootloader at 0x20000, which is sector 0x100
+ # boot ROM expects bootloader at 0x20000, which is sector 0x100
# with the usual SECTOR_SIZE of 0x200.
# (sector 0 is MBR / partition table)
loader_start, loader_end, loader_len = align_partition(
- SnowballEmmcConfig.SNOWBALL_LOADER_START_S,
+ SnowballEmmcConfig.SNOWBALL_LOADER_START_S,
LOADER_MIN_SIZE_S, 1, PART_ALIGN_S)
boot_start, boot_end, boot_len = align_partition(
@@ -562,15 +570,22 @@
make_uImage(cls.load_addr, k_img_data, boot_dir)
boot_script_path = os.path.join(boot_dir, cls.boot_script)
make_boot_script(boot_env, boot_script_path)
+ cls.populate_raw_partition(chroot_dir, boot_device_or_file)
+
+ @classmethod
+ def populate_raw_partition(cls, chroot_dir, boot_device_or_file):
+ # Populate created raw partition with TOC and startup files.
+ config_files_path = os.path.join(chroot_dir, 'boot')
_, toc_filename = tempfile.mkstemp()
- atexit.register(os.unlink, toc_filename)
- config_files_path = os.path.join(chroot_dir, 'boot')
new_files = cls.get_file_info(config_files_path)
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)
+ cls.delete_file(toc_filename)
+ cls.delete_file(os.path.join(config_files_path,
+ cls.SNOWBALL_STARTUP_FILES_CONFIG))
@classmethod
def install_snowball_boot_loader(cls, toc_file_name, files,
@@ -584,13 +599,21 @@
for file in files:
# XXX We need checks that these files do not overwrite each
# other. This code assumes that offset and file sizes are ok.
+ filename = file['filename']
if (file['offset'] % SECTOR_SIZE) != 0:
seek_bytes = start_sector * SECTOR_SIZE + file['offset']
- _dd(file['filename'], boot_device_or_file, block_size=1,
+ _dd(filename, boot_device_or_file, block_size=1,
seek=seek_bytes)
else:
- seek_sectors = start_sector + file['offset']/SECTOR_SIZE
- _dd(file['filename'], boot_device_or_file, seek=seek_sectors)
+ seek_sectors = start_sector + file['offset'] / SECTOR_SIZE
+ _dd(filename, boot_device_or_file, seek=seek_sectors)
+ cls.delete_file(filename)
+
+ @classmethod
+ def delete_file(cls, file_path):
+ cmd = ["rm", "%s" % file_path]
+ proc = cmd_runner.run(cmd, as_root=True)
+ proc.wait()
@classmethod
def create_toc(cls, f, files):
@@ -605,6 +628,8 @@
# i; int; load_address,
# 12s; string of char; name
# http://igloocommunity.org/support/index.php/ConfigPartitionOverview
+ assert len(file['section_name']) < 12, (
+ "Section name %s too large" % file['section_name'])
flags = 0
load_adress = file['align']
data = struct.pack('<IIIii12s', file['offset'], file['size'],
@@ -748,6 +773,7 @@
make_uImage(cls.load_addr, k_img_data, boot_dir)
make_uInitrd(i_img_data, boot_dir)
+
class SMDKV310Config(BoardConfig):
uboot_flavor = 'smdkv310'
serial_tty = 'ttySAC1'
@@ -825,7 +851,7 @@
'efikamx': EfikamxConfig,
'efikasb': EfikasbConfig,
'mx51evk': Mx51evkConfig,
- 'mx53loco' : Mx53LoCoConfig,
+ 'mx53loco': Mx53LoCoConfig,
'overo': OveroConfig,
'smdkv310': SMDKV310Config,
}
=== modified file 'linaro_image_tools/media_create/partitions.py'
@@ -3,7 +3,7 @@
# Author: Guilherme Salgado <guilherme.salgado@linaro.org>
#
# This file is part of Linaro Image Tools.
-#
+#
# Linaro Image Tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@@ -28,6 +28,7 @@
Device,
Disk,
PARTITION_NORMAL,
+ PARTITION_EXTENDED,
)
from linaro_image_tools import cmd_runner
@@ -71,9 +72,8 @@
bootfs = partitions[0]
system = partitions[1]
cache = partitions[2]
- data = partitions[4]
- sdcard = partitions[5]
-
+ data = partitions[3]
+ sdcard = partitions[4]
print "\nFormating boot partition\n"
proc = cmd_runner.run(
@@ -98,6 +98,7 @@
return bootfs, system, cache, data, sdcard
+
# I wonder if it'd make sense to convert this into a small shim which calls
# the appropriate function for the given type of device? I think it's still
# small enough that there's not much benefit in doing that, but if it grows we
@@ -296,18 +297,28 @@
# Here we can use parted.Device to read the partitions because we're
# reading from a regular file rather than a block device. If it was a
# block device we'd need root rights.
+ vfat_partition = None
disk = Disk(Device(image_file))
partition_info = []
for partition in disk.partitions:
- geometry = partition.geometry
- partition_info.append((geometry.start * SECTOR_SIZE,
- geometry.length * SECTOR_SIZE))
+ # Will ignore any partitions before boot and of type EXTENDED
+ if 'boot' in partition.getFlagsAsString():
+ vfat_partition = partition
+ geometry = partition.geometry
+ partition_info.append((geometry.start * SECTOR_SIZE,
+ geometry.length * SECTOR_SIZE))
+ elif (vfat_partition is not None and
+ partition.type != PARTITION_EXTENDED):
+ geometry = partition.geometry
+ partition_info.append((geometry.start * SECTOR_SIZE,
+ geometry.length * SECTOR_SIZE))
# NB: don't use vfat_partition.nextPartition() as that might return
# a partition of type PARTITION_FREESPACE; it's much easier to
# iterate disk.partitions which only returns
# parted.PARTITION_NORMAL partitions
-
- assert len(partition_info) == 6
+ assert vfat_partition is not None, (
+ "Couldn't find boot partition on %s" % image_file)
+ assert len(partition_info) == 5
return partition_info
@@ -347,6 +358,7 @@
return boot_partition, system_partition, cache_partition, \
data_partition, sdcard_partition
+
def get_boot_and_root_partitions_for_media(media, board_config):
"""Return the device files for the boot and root partitions of media.
=== modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
@@ -28,6 +28,7 @@
import textwrap
import time
import types
+import struct
from testtools import TestCase
@@ -38,6 +39,7 @@
boards,
partitions,
rootfs,
+ android_boards,
)
from linaro_image_tools.media_create.boards import (
LOADER_MIN_SIZE_S,
@@ -206,6 +208,256 @@
self.assertEquals(uboot_file, _get_smdk_uboot(chroot_dir, uboot_flavor))
+class TestCreateToc(TestCaseWithFixtures):
+ ''' Tests boards.SnowballEmmcConfig.create_toc()'''
+
+ def setUp(self):
+ ''' Create a temporary directory to work in'''
+ super(TestCreateToc, self).setUp()
+ self.tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir()
+ #Create the test's input data structures
+ zero = '\x00\x00\x00\x00'
+ line1 = zero + zero + zero + zero + zero + 'b' + zero + zero + \
+ '\x00\x00\x00'
+ maxint = '\xFF\xFF\xFF\x7F'
+ minint = '\xFF\xFF\xFF\xFF'
+ line2 = maxint + maxint + zero + minint + minint + \
+ 'hello' + zero + '\x00\x00\x00'
+ line3 = '\x01\x00\x00\x00' '\x64\x00\x00\x00' + zero + \
+ '\x05\x00\x00\x00' '\x05\x00\x00\x00' \
+ 'hello' + zero + '\x00\x00\x00'
+ self.expected = line1 + line2 + line3
+
+ def create_files_structure(self, src_data):
+ ''' Creates the data structure that the tested function
+ needs as input'''
+ files = []
+ for line in src_data:
+ files.append({'section_name': line[5],
+ 'filename': 'N/A',
+ 'align': line[3],
+ 'offset': line[0],
+ 'size': line[1],
+ 'load_adress': 'N/A'})
+ return files
+
+ def test_create_toc_normal_case(self):
+ ''' Creates a toc file, and then reads the created
+ file and compares it to precomputed data'''
+ correct_data = [(0, 0, 0, 0, 0, 'b'),
+ (0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, -1, -1, 'hello'),
+ (1, 100, 1000, 5, 10, 'hello')]
+ files = self.create_files_structure(correct_data)
+ filename = os.path.join(self.tempdir, 'toc')
+ with open(filename, 'w') as f:
+ boards.SnowballEmmcConfig.create_toc(f, files)
+ with open(filename, 'r') as f:
+ actual = f.read()
+ self.assertEquals(96, len(actual))
+ for i in range(len(actual)):
+ self.assertEquals(self.expected[i], actual[i], 'Mismatch at ix' \
+ ' %d, ref=%c, actual=%c' % (i, self.expected[i], actual[i]))
+
+ def test_create_toc_error_too_large_section_name(self):
+ '''Verify that trying to write past the end of the
+ section name field raises an exception'''
+ illegal_name_data = [(0, 0, 0, 0, 0, 'Too_longName')]
+ files = self.create_files_structure(illegal_name_data)
+ with open(os.path.join(self.tempdir, 'toc'), 'w') as f:
+ self.assertRaises(AssertionError,
+ boards.SnowballEmmcConfig.create_toc,
+ f, files)
+
+ def test_create_toc_error_negative_unsigned(self):
+ '''Verify that trying to write a negative number to an unsigned
+ field raises an exception'''
+ illegal_unsigned_data = [(-3, 0, 0, 0, 0, 'xxx')]
+ files = self.create_files_structure(illegal_unsigned_data)
+ with open(os.path.join(self.tempdir, 'toc'), 'w') as f:
+ self.assertRaises(struct.error,
+ boards.SnowballEmmcConfig.create_toc,
+ f, files)
+
+
+class TestSnowballBootFiles(TestCaseWithFixtures):
+ ''' Tests boards.SnowballEmmcConfig.install_snowball_boot_loader()'''
+ ''' Tests boards.SnowballEmmcConfig._make_boot_files()'''
+ ''' Tests boards.SnowballEmmcConfig.get_file_info()'''
+
+ def setUp(self):
+ ''' Create temporary directory to work in'''
+ super(TestSnowballBootFiles, self).setUp()
+ self.tempdir = self.useFixture(CreateTempDirFixture()).get_temp_dir()
+ self.temp_bootdir_path = os.path.join(self.tempdir, 'boot')
+ if not os.path.exists(self.temp_bootdir_path):
+ os.makedirs(self.temp_bootdir_path)
+
+ def setupFiles(self):
+ ''' Adds some files in the temp dir that the tested function
+ can use as input:
+ * A config file, which the tested function reads to
+ discover which binary files should be written to
+ the loader partition.
+ * Test versions of the binary files themselves,
+ containing dummy data.
+ Returns the expected value that the tested function should
+ return, given these input files. '''
+ src_data = [('ISSW', 'boot_image_issw.bin', -1, 0, '5'),
+ ('X-LOADER', 'boot_image_x-loader.bin', -1, 0, '6'),
+ ('MEM_INIT', 'mem_init.bin', 0, 0x160000, '7'),
+ ('PWR_MGT', 'power_management.bin', 0, 0x170000, '8'),
+ ('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)
+ with open(cfg_file, 'w') as f:
+ for line in src_data:
+ # Write comments, so we test that the parser can read them
+ f.write('#Yet another comment\n')
+ f.write('%s %s %i %#x %s\n' % line)
+ expected = []
+ # 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:
+ f.write(line[0])
+ #define the expected values read from the config file
+ expected = []
+ ofs = [boards.SnowballEmmcConfig.TOC_SIZE,
+ boards.SnowballEmmcConfig.TOC_SIZE + len('ISSW'), 0x160000,
+ 0x170000, 0xBA0000, 0xC1F000]
+ size = [len('ISSW'), len('X-LOADER'), len('MEM_INIT'), \
+ 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])
+ expected.append({'section_name': line[0],
+ 'filename': filename,
+ 'align': int(line[2]),
+ 'offset': ofs[i],
+ 'size': long(size[i]),
+ 'load_adress': line[4]})
+ i += 1
+ return expected
+
+ def test_file_name_size(self):
+ ''' Test using a to large toc file '''
+ _, toc_filename = tempfile.mkstemp()
+ atexit.register(os.unlink, toc_filename)
+ filedata = 'X'
+ bytes = boards.SnowballEmmcConfig.TOC_SIZE + 1
+ tmpfile = open(toc_filename, 'wb')
+ for n in xrange(bytes):
+ tmpfile.write(filedata)
+ tmpfile.close()
+ files = self.setupFiles()
+ self.assertRaises(AssertionError,
+ boards.SnowballEmmcConfig.install_snowball_boot_loader,
+ toc_filename, files, "boot_device_or_file",
+ boards.SnowballEmmcConfig.SNOWBALL_LOADER_START_S)
+
+ def test_install_snowball_boot_loader_toc(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)
+ 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' \
+ ' bs=1 conv=notrunc seek=131588'
+ % (sudo_args, self.temp_bootdir_path),
+ '%s rm %s/boot_image_x-loader.bin' % (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 rm %s/mem_init.bin' % (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 rm %s/power_management.bin' % (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 rm %s/u-boot.bin' % (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),
+ '%s rm %s/u-boot-env.bin' % (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',
+ lambda: (-1, '/tmp/temp_snowball_make_boot_files')))
+ self.setupFiles()
+ k_img_file = os.path.join(self.tempdir, 'vmlinuz-1-ux500')
+ i_img_file = os.path.join(self.tempdir, 'initrd.img-1-ux500')
+
+ boot_env = board_configs['snowball_emmc']._get_boot_env(
+ is_live=False, is_lowmem=False, consoles=[],
+ rootfs_uuid="test_boot_env_uuid", d_img_data=None)
+ boards.SnowballEmmcConfig._make_boot_files(boot_env, self.tempdir,
+ self.temp_bootdir_path, 'boot_device_or_file', k_img_file,
+ i_img_file, None)
+ expected = [
+ '%s mkimage -A arm -O linux -T kernel -C none -a 0x00008000 -e' \
+ ' 0x00008000 -n Linux -d %s %s/boot/uImage' % (sudo_args,
+ k_img_file, self.tempdir),
+ '%s cp /tmp/temp_snowball_make_boot_files %s/boot/boot.txt'
+ % (sudo_args, self.tempdir),
+ '%s mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n boot' \
+ ' script -d %s/boot/boot.txt %s/boot/flash.scr'
+ % (sudo_args, self.tempdir, self.tempdir),
+ '%s dd if=/tmp/temp_snowball_make_boot_files' \
+ ' of=boot_device_or_file bs=512 conv=notrunc seek=256'
+ % (sudo_args),
+ '%s dd if=%s/boot/boot_image_issw.bin of=boot_device_or_file' \
+ ' bs=512 conv=notrunc seek=257' % (sudo_args, self.tempdir),
+ '%s rm %s/boot_image_issw.bin' % (sudo_args,
+ self.temp_bootdir_path),
+ '%s dd if=%s/boot/boot_image_x-loader.bin of=boot_device_or_file' \
+ ' bs=1 conv=notrunc seek=131588' % (sudo_args, self.tempdir),
+ '%s rm %s/boot_image_x-loader.bin' % (sudo_args,
+ self.temp_bootdir_path),
+ '%s dd if=%s/boot/mem_init.bin of=boot_device_or_file bs=512' \
+ ' conv=notrunc seek=3072' % (sudo_args, self.tempdir),
+ '%s rm %s/mem_init.bin' % (sudo_args, self.temp_bootdir_path),
+ '%s dd if=%s/boot/power_management.bin of=boot_device_or_file' \
+ ' bs=512 conv=notrunc seek=3200' % (sudo_args, self.tempdir),
+ '%s rm %s/power_management.bin' % (sudo_args,
+ self.temp_bootdir_path),
+ '%s dd if=%s/boot/u-boot.bin of=boot_device_or_file bs=512' \
+ ' conv=notrunc seek=24064' % (sudo_args, self.tempdir),
+ '%s rm %s/u-boot.bin' % (sudo_args, self.temp_bootdir_path),
+ '%s dd if=%s/boot/u-boot-env.bin of=boot_device_or_file bs=512' \
+ ' conv=notrunc seek=25080' % (sudo_args, self.tempdir),
+ '%s rm %s/u-boot-env.bin' % (sudo_args, self.temp_bootdir_path),
+ '%s rm /tmp/temp_snowball_make_boot_files' % (sudo_args),
+ '%s rm %s/startfiles.cfg' % (sudo_args, self.temp_bootdir_path)]
+
+ self.assertEqual(expected, fixture.mock.commands_executed)
+
+ def test_missing_files(self):
+ '''When the files cannot be read, an IOError should be raised'''
+ self.assertRaises(IOError,
+ boards.SnowballEmmcConfig.get_file_info,
+ self.tempdir)
+
+ def test_normal_case(self):
+ expected = self.setupFiles()
+ actual = boards.SnowballEmmcConfig.get_file_info(
+ self.temp_bootdir_path)
+ self.assertEquals(expected, actual)
+
+
class TestBootSteps(TestCaseWithFixtures):
def setUp(self):
@@ -410,6 +662,18 @@
'1,8191,0xDA\n8192,106496,0x0C,*\n114688,,,-',
board_configs['smdkv310'].get_sfdisk_cmd())
+ def test_panda_android(self):
+ self.assertEqual(
+ '63,270272,0x0C,*\n270336,524288,L\n794624,524288,L\n' \
+ '1318912,-,E\n1318912,1048576,L\n2367488,,,-',
+ android_boards.AndroidPandaConfig.get_sfdisk_cmd())
+
+ def test_snowball_emmc_android(self):
+ self.assertEqual(
+ '256,7936,0xDA\n8192,262144,0x0C,*\n270336,524288,L\n' \
+ '794624,-,E\n794624,524288,L\n1318912,1048576,L\n2367488,,,-',
+ android_boards.AndroidSnowballEmmcConfig.get_sfdisk_cmd())
+
class TestGetBootCmd(TestCase):
@@ -583,6 +847,21 @@
'fatload mmc 0:1 0x81600000 uInitrd; '
'bootm 0x80200000 0x81600000'}
self.assertEqual(expected, boot_commands)
+
+ def test_android_snowball_emmc(self):
+ boot_commands = (android_boards.AndroidSnowballEmmcConfig.
+ _get_boot_env(consoles=[]))
+ expected = {
+ 'bootargs': 'console=tty0 console=ttyAMA2,115200n8 '
+ 'rootwait ro earlyprintk '
+ 'rootdelay=1 fixrtc nocompcache '
+ 'mem=128M@0 mali.mali_mem=64M@128M mem=24M@192M '
+ 'hwmem=167M@216M mem_issw=1M@383M mem=640M@384M '
+ 'vmalloc=256M init=/init androidboot.console=ttyAMA2',
+ 'bootcmd': 'fatload mmc 1:1 0x00100000 uImage; '
+ 'fatload mmc 1:1 0x08000000 uInitrd; '
+ 'bootm 0x00100000 0x08000000'}
+ self.assertEqual(expected, boot_commands)
class TestUnpackBinaryTarball(TestCaseWithFixtures):
@@ -986,13 +1265,21 @@
(63 * SECTOR_SIZE, 32768 * SECTOR_SIZE),
(32831 * SECTOR_SIZE, 65536 * SECTOR_SIZE),
(98367 * SECTOR_SIZE, 65536 * SECTOR_SIZE),
- (294975 * SECTOR_SIZE, (self.android_image_size -
- 294975 * SECTOR_SIZE)),
((294975 + ext_part_size) * SECTOR_SIZE,
(131072 - ext_part_size) * SECTOR_SIZE),
((426047 + ext_part_size) * SECTOR_SIZE,
self.android_image_size - (426047 + ext_part_size) * SECTOR_SIZE)
]
+
+ self.android_snowball_offsets_and_sizes = [
+ (8192 * SECTOR_SIZE, 24639 * SECTOR_SIZE),
+ (32831 * SECTOR_SIZE, 65536 * SECTOR_SIZE),
+ ((98367 + ext_part_size)* SECTOR_SIZE,
+ (65536 - ext_part_size) * SECTOR_SIZE),
+ (294975 * SECTOR_SIZE, 131072 * SECTOR_SIZE),
+ ((426047 + ext_part_size) * SECTOR_SIZE,
+ self.android_image_size - (426047 + ext_part_size) * SECTOR_SIZE)
+ ]
def tearDown(self):
super(TestPartitionSetup, self).tearDown()
@@ -1009,6 +1296,13 @@
'63,32768,0x0C,*\n32831,65536,L\n98367,65536,L\n294975,-,E\n' \
'294975,131072,L\n426047,,,-', '%s' % self.android_image_size)
+ def _create_snowball_android_tmpfile(self):
+ # raw, boot, system, cache, (extended), userdata and sdcard partitions
+ return self._create_qemu_img_with_partitions(
+ '256,7936,0xDA\n8192,24639,0x0C,*\n32831,65536,L\n' \
+ '98367,-,E\n98367,65536,L\n294975,131072,L\n' \
+ '426047,,,-', '%s' % self.android_image_size)
+
def test_convert_size_no_suffix(self):
self.assertEqual(524288, convert_size_to_bytes('524288'))
@@ -1038,6 +1332,15 @@
self.android_offsets_and_sizes):
self.assertEqual(device_pair, expected_pair)
+ def test_calculate_snowball_android_partition_size_and_offset(self):
+ tmpfile = self._create_snowball_android_tmpfile()
+ device_info = calculate_android_partition_size_and_offset(tmpfile)
+ # We use map(None, ...) since it would catch if the lists are not of
+ # equal length and zip() would not in all cases.
+ for device_pair, expected_pair in map(None, device_info,
+ self.android_snowball_offsets_and_sizes):
+ self.assertEqual(device_pair, expected_pair)
+
def test_partition_numbering(self):
# another Linux partition at +24 MiB after the boot/root parts
tmpfile = self._create_qemu_img_with_partitions(
@@ -1147,7 +1450,7 @@
# get_boot_and_root_loopback_devices will also setup two exit handlers
# to de-register the loopback devices set up above.
- self.assertEqual(6, len(atexit_fixture.mock.funcs))
+ self.assertEqual(5, len(atexit_fixture.mock.funcs))
popen_fixture.mock.calls = []
atexit_fixture.mock.run_funcs()
# We did not really run losetup above (as it requires root) so here we
@@ -1158,7 +1461,6 @@
'%s losetup -d ' % sudo_args,
'%s losetup -d ' % sudo_args,
'%s losetup -d ' % sudo_args,
- '%s losetup -d ' % sudo_args,
'%s losetup -d ' % sudo_args],
popen_fixture.mock.commands_executed)