diff options
author | Guilherme Salgado <salgado@canonical.com> | 2011-01-13 08:52:27 -0600 |
---|---|---|
committer | Guilherme Salgado <salgado@canonical.com> | 2011-01-13 08:52:27 -0600 |
commit | 206c760a88ca9cca7222fdc46336dd8e413c7823 (patch) | |
tree | a563ce9554f72e088454fec576e40a6a9d183ddd | |
parent | e900bcc6f483de4da95b6367d1f2d1d748012f9c (diff) | |
parent | 65030232c0a6cbc27f9e026732d889bfdde610fb (diff) |
Move remaining board-specific code from populate_boot.py to boards.py
-rwxr-xr-x | linaro-media-create | 4 | ||||
-rw-r--r-- | linaro_media_create/boards.py | 187 | ||||
-rw-r--r-- | linaro_media_create/populate_boot.py | 134 | ||||
-rw-r--r-- | linaro_media_create/tests/test_media_create.py | 34 |
4 files changed, 201 insertions, 158 deletions
diff --git a/linaro-media-create b/linaro-media-create index cd5e0ee..d53b47f 100755 --- a/linaro-media-create +++ b/linaro-media-create @@ -100,8 +100,8 @@ if __name__ == '__main__': if args.should_format_bootfs: populate_boot( - args.board, board_config, ROOTFS_DIR, boot_partition, BOOT_DISK, - args.device, TMP_DIR, args.is_live, args.is_lowmem, args.consoles) + board_config, ROOTFS_DIR, boot_partition, BOOT_DISK, args.device, + args.is_live, args.is_lowmem, args.consoles) if args.should_format_rootfs: create_swap = False diff --git a/linaro_media_create/boards.py b/linaro_media_create/boards.py index 4ca4fad..0a6d69f 100644 --- a/linaro_media_create/boards.py +++ b/linaro_media_create/boards.py @@ -1,35 +1,48 @@ """Configuration for boards supported by linaro-media-create. -To add support for a new board, you just need to create a subclass of -BoardConfig and set appropriate values for its variables. +To add support for a new board, you need to create a subclass of +BoardConfig, set appropriate values for its variables and add it to +board_configs at the bottom of this file. """ +import atexit +import glob +import os +import tempfile import uuid +from linaro_media_create import cmd_runner + ROOTFS_UUID = str(uuid.uuid4()) class BoardConfig(object): """The configuration used when building an image for a board.""" + # These attributes may not need to be redefined on some subclasses. uboot_flavor = None mmc_option = '0:1' mmc_part_offset = 0 - extra_serial_opts = None - live_serial_opts = None + fat_size = 32 + extra_serial_opts = '' + live_serial_opts = '' + extra_boot_args_options = None + + # These attributes must be defined on all subclasses. kernel_addr = None initrd_addr = None load_addr = None sub_arch = None boot_script = None - extra_boot_args_options = None - fat_size = 32 @classmethod - def get_boot_cmd(cls, is_live, is_lowmem, consoles): - """Get the boot command for this board.""" + def _get_boot_cmd(cls, is_live, is_lowmem, consoles): + """Get the boot command for this board. + + In general subclasses should not have to override this. + """ boot_args_options = 'rootwait ro' - if cls.extra_boot_args_options: - boot_args_options += " %s" % cls.extra_boot_args_options + if cls.extra_boot_args_options is not None: + boot_args_options += ' %s' % cls.extra_boot_args_options serial_opts = '' if consoles is not None: for console in consoles: @@ -63,6 +76,24 @@ class BoardConfig(object): "%(boot_snippet)s %(boot_args_options)s'\n" "boot" % replacements) + @classmethod + def make_boot_files(cls, uboot_parts_dir, is_live, is_lowmem, consoles, + root_dir, boot_dir, boot_script, boot_device_or_file): + boot_cmd = cls._get_boot_cmd(is_live, is_lowmem, consoles) + cls._make_boot_files( + uboot_parts_dir, boot_cmd, root_dir, boot_dir, boot_script, + boot_device_or_file) + + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, root_dir, boot_dir, + boot_script, boot_device_or_file): + """Make the necessary boot files for this board. + + This is usually board-specific so ought to be defined in every + subclass. + """ + raise NotImplementedError() + class BeagleConfig(BoardConfig): uboot_flavor = 'omap3_beagle' @@ -77,6 +108,17 @@ class BeagleConfig(BoardConfig): 'earlyprintk fixrtc nocompcache vram=12M omapfb.debug=y ' 'omapfb.mode=dvi:1280x720MR-16@60') + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script, boot_device_or_file): + mlo_file = os.path.join( + chroot_dir, 'usr', 'lib', 'x-loader-omap', 'MLO') + install_omap_boot_loader(mlo_file, boot_dir) + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + make_boot_script(boot_cmd, boot_script) + make_boot_ini(boot_script, boot_dir) + class PandaConfig(BoardConfig): uboot_flavor = 'omap4_panda' @@ -91,10 +133,29 @@ class PandaConfig(BoardConfig): 'earlyprintk fixrtc nocompcache vram = 32M omapfb.debug = y ' 'omapfb.vram = 0:8M mem = 463M ip = none') + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script, boot_device_or_file): + mlo_file = os.path.join( + chroot_dir, 'usr', 'lib', 'x-loader-omap4', 'MLO') + install_omap_boot_loader(mlo_file, boot_dir) + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + make_boot_script(boot_cmd, boot_script) + make_boot_ini(boot_script, boot_dir) + class IgepConfig(BeagleConfig): uboot_flavor = None + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script, boot_device_or_file): + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + make_boot_script(boot_cmd, boot_script) + make_boot_ini(boot_script, boot_dir) + class Ux500Config(BoardConfig): extra_serial_opts = 'console = tty0 console = ttyAMA2,115200n8' @@ -111,6 +172,13 @@ class Ux500Config(BoardConfig): 'hwmem = 48M@302M mem = 152M@360M') mmc_option = '1:1' + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script, boot_device_or_file): + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + make_boot_script(boot_cmd, boot_script) + class Mx51evkConfig(BoardConfig): extra_serial_opts = 'console = tty0 console = ttymxc0,115200n8' @@ -123,6 +191,16 @@ class Mx51evkConfig(BoardConfig): mmc_part_offset = 1 mmc_option = '0:2' + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script, boot_device_or_file): + uboot_file = os.path.join( + chroot_dir, 'usr', 'lib', 'u-boot', 'mx51evk', 'u-boot.imx') + install_mx51evk_boot_loader(uboot_file, boot_device_or_file) + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + make_boot_script(boot_cmd, boot_script) + class VexpressConfig(BoardConfig): uboot_flavor = 'ca9x4_ct_vxp' @@ -137,6 +215,12 @@ class VexpressConfig(BoardConfig): # only allows for FAT16 fat_size = 16 + @classmethod + def _make_boot_files(cls, uboot_parts_dir, boot_cmd, chroot_dir, + boot_dir, boot_script): + make_uImage(cls.load_addr, uboot_parts_dir, cls.sub_arch, boot_dir) + make_uInitrd(uboot_parts_dir, cls.sub_arch, boot_dir) + board_configs = { 'beagle': BeagleConfig, @@ -146,3 +230,86 @@ board_configs = { 'ux500': Ux500Config, 'mx51evk': Mx51evkConfig, } + + +def _run_mkimage(img_type, load_addr, entry_point, name, img_data, img, + stdout=None, as_root=True): + cmd = ['mkimage', + '-A', 'arm', + '-O', 'linux', + '-T', img_type, + '-C', 'none', + '-a', load_addr, + '-e', load_addr, + '-n', name, + '-d', img_data, + img] + proc = cmd_runner.run(cmd, as_root=as_root, stdout=stdout) + proc.wait() + return proc.returncode + + +def _get_file_matching(regex): + """Return a file whose path matches the given regex. + + If zero or more than one files match, raise a ValueError. + """ + files = glob.glob(regex) + if len(files) == 1: + return files[0] + elif len(files) == 0: + raise ValueError( + "No files found matching '%s'; can't continue" % regex) + else: + # TODO: Could ask the user to chosse which file to use instead of + # raising an exception. + raise ValueError("Too many files matching '%s' found." % regex) + + +def make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk): + img_data = _get_file_matching( + '%s/vmlinuz-*-%s' % (uboot_parts_dir, sub_arch)) + img = '%s/uImage' % boot_disk + return _run_mkimage( + 'kernel', load_addr, load_addr, 'Linux', img_data, img) + + +def make_uInitrd(uboot_parts_dir, sub_arch, boot_disk): + img_data = _get_file_matching( + '%s/initrd.img-*-%s' % (uboot_parts_dir, sub_arch)) + img = '%s/uInitrd' % boot_disk + return _run_mkimage('ramdisk', '0', '0', 'initramfs', img_data, img) + + +def make_boot_script(boot_script_data, boot_script): + # Need to save the boot script data into a file that will be passed to + # mkimage. + _, tmpfile = tempfile.mkstemp() + atexit.register(os.unlink, tmpfile) + with open(tmpfile, 'w') as fd: + fd.write(boot_script_data) + return _run_mkimage( + 'script', '0', '0', 'boot script', tmpfile, boot_script) + + +def install_mx51evk_boot_loader(imx_file, boot_device_or_file): + proc = cmd_runner.run([ + "dd", + "if=%s" % imx_file, + "of=%s" % boot_device_or_file, + "bs=1024", + "seek=1", + "conv=notrunc"], as_root=True) + proc.wait() + + +def install_omap_boot_loader(mlo_file, boot_disk): + cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait() + # XXX: Is this really needed? + cmd_runner.run(["sync"]).wait() + + +def make_boot_ini(boot_script, boot_disk): + proc = cmd_runner.run( + ["cp", "-v", boot_script, "%s/boot.ini" % boot_disk], as_root=True) + proc.wait() diff --git a/linaro_media_create/populate_boot.py b/linaro_media_create/populate_boot.py index f3a1589..ccd090c 100644 --- a/linaro_media_create/populate_boot.py +++ b/linaro_media_create/populate_boot.py @@ -1,94 +1,11 @@ import errno -import glob import os from linaro_media_create import cmd_runner -def _run_mkimage(img_type, load_addr, entry_point, name, img_data, img, - stdout=None, as_root=True): - cmd = ['mkimage', - '-A', 'arm', - '-O', 'linux', - '-T', img_type, - '-C', 'none', - '-a', load_addr, - '-e', load_addr, - '-n', name, - '-d', img_data, - img] - proc = cmd_runner.run(cmd, as_root=as_root, stdout=stdout) - proc.wait() - return proc.returncode - - -def _get_file_matching(regex): - """Return a file whose path matches the given regex. - - If zero or more than one files match, raise a ValueError. - """ - files = glob.glob(regex) - if len(files) == 1: - return files[0] - elif len(files) == 0: - raise ValueError( - "No files found matching '%s'; can't continue" % regex) - else: - # TODO: Could ask the user to chosse which file to use instead of - # raising an exception. - raise ValueError("Too many files matching '%s' found." % regex) - - -def make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk): - img_data = _get_file_matching( - '%s/vmlinuz-*-%s' % (uboot_parts_dir, sub_arch)) - img = '%s/uImage' % boot_disk - return _run_mkimage( - 'kernel', load_addr, load_addr, 'Linux', img_data, img) - - -def make_uInitrd(uboot_parts_dir, sub_arch, boot_disk): - img_data = _get_file_matching( - '%s/initrd.img-*-%s' % (uboot_parts_dir, sub_arch)) - img = '%s/uInitrd' % boot_disk - return _run_mkimage('ramdisk', '0', '0', 'initramfs', img_data, img) - - -def make_boot_script(boot_script_data, tmp_dir, boot_script): - # Need to save the boot script data into a file that will be passed to - # mkimage. - data_file = '%s/boot.cmd' % tmp_dir - with open(data_file, 'w') as fd: - fd.write(boot_script_data) - return _run_mkimage( - 'script', '0', '0', 'boot script', data_file, boot_script) - - -def install_mx51evk_boot_loader(imx_file, boot_device_or_file): - proc = cmd_runner.run([ - "dd", - "if=%s" % imx_file, - "of=%s" % boot_device_or_file, - "bs=1024", - "seek=1", - "conv=notrunc"], as_root=True) - proc.wait() - - -def install_omap_boot_loader(mlo_file, boot_disk): - cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait() - # XXX: Is this really needed? - cmd_runner.run(["sync"]).wait() - - -def make_boot_ini(boot_script, boot_disk): - proc = cmd_runner.run( - ["cp", "-v", boot_script, "%s/boot.ini" % boot_disk], as_root=True) - proc.wait() - - -def populate_boot(board, board_config, chroot_dir, boot_partition, boot_disk, - boot_device_or_file, tmp_dir, is_live, is_lowmem, consoles): +def populate_boot(board_config, chroot_dir, boot_partition, boot_disk, + boot_device_or_file, is_live, is_lowmem, consoles): parts_dir = 'boot' if is_live: @@ -115,50 +32,9 @@ def populate_boot(board, board_config, chroot_dir, boot_partition, boot_disk, dict(boot_disk=boot_disk, boot_script_name=board_config.boot_script)) - load_addr = board_config.load_addr - sub_arch = board_config.sub_arch - boot_cmd = board_config.get_boot_cmd(is_live, is_lowmem, consoles) - - # TODO: Once linaro-media-create is fully ported to python, we should - # split this into several board-specific functions that are defined - # somewhere else and just called here. - if board in ["beagle", "panda"]: - xloader_dir = 'x-loader-omap' - if board == "panda": - xloader_dir = 'x-loader-omap4' - mlo_file = os.path.join( - chroot_dir, 'usr', 'lib', xloader_dir, 'MLO') - install_omap_boot_loader(mlo_file, boot_disk) - make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk) - make_uInitrd(uboot_parts_dir, sub_arch, boot_disk) - make_boot_script(boot_cmd, tmp_dir, boot_script) - make_boot_ini(boot_script, boot_disk) - - elif board == "igep": - make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk) - make_uInitrd(uboot_parts_dir, sub_arch, boot_disk) - make_boot_script(boot_cmd, tmp_dir, boot_script) - make_boot_ini(boot_script, boot_disk) - - elif board == "ux500": - make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk) - make_uInitrd(uboot_parts_dir, sub_arch, boot_disk) - make_boot_script(boot_cmd, tmp_dir, boot_script) - - elif board == "vexpress": - make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk) - make_uInitrd(uboot_parts_dir, sub_arch, boot_disk) - - elif board == "mx51evk": - install_mx51evk_boot_loader( - "binary/usr/lib/u-boot/mx51evk/u-boot.imx", boot_device_or_file) - make_uImage(load_addr, uboot_parts_dir, sub_arch, boot_disk) - make_uInitrd(uboot_parts_dir, sub_arch, boot_disk) - make_boot_script(boot_cmd, tmp_dir, boot_script) - - else: - raise AssertionError( - "Internal error; missing support for board: %s" % board) + board_config.make_boot_files( + uboot_parts_dir, is_live, is_lowmem, consoles, chroot_dir, boot_disk, + boot_script, boot_device_or_file) cmd_runner.run(['sync']).wait() try: diff --git a/linaro_media_create/tests/test_media_create.py b/linaro_media_create/tests/test_media_create.py index c6c4668..1266ad4 100644 --- a/linaro_media_create/tests/test_media_create.py +++ b/linaro_media_create/tests/test_media_create.py @@ -6,6 +6,7 @@ import random import string import subprocess import sys +import tempfile import time from testtools import TestCase @@ -16,13 +17,18 @@ from linaro_media_create import ( check_device, cmd_runner, ensure_command, - populate_boot, + boards, partitions, rootfs, ) from linaro_media_create.boards import ( board_configs, + make_boot_script, + make_uImage, + make_uInitrd, ROOTFS_UUID, + _get_file_matching, + _run_mkimage, ) from linaro_media_create.hwpack import ( copy_file, @@ -43,13 +49,6 @@ from linaro_media_create.partitions import ( run_sfdisk_commands, setup_partitions, ) -from linaro_media_create.populate_boot import ( - make_boot_script, - make_uImage, - make_uInitrd, - _get_file_matching, - _run_mkimage, - ) from linaro_media_create.remove_binary_dir import remove_dir from linaro_media_create.rootfs import ( create_flash_kernel_config, @@ -96,7 +95,7 @@ class TestEnsureCommand(TestCase): class TestGetBootCmd(TestCase): def test_vexpress(self): - boot_cmd = board_configs['vexpress'].get_boot_cmd( + boot_cmd = board_configs['vexpress']._get_boot_cmd( is_live=False, is_lowmem=False, consoles=None) expected = ( "setenv bootcmd 'fatload mmc 0:1 0x60008000 uImage; fatload mmc " @@ -106,7 +105,7 @@ class TestGetBootCmd(TestCase): self.assertEqual(expected, boot_cmd) def test_mx51evk(self): - boot_cmd = board_configs['mx51evk'].get_boot_cmd( + boot_cmd = board_configs['mx51evk']._get_boot_cmd( is_live=False, is_lowmem=False, consoles=None) expected = ( "setenv bootcmd 'fatload mmc 0:2 0x90000000 uImage; fatload mmc " @@ -116,7 +115,7 @@ class TestGetBootCmd(TestCase): self.assertEqual(expected, boot_cmd) def test_ux500(self): - boot_cmd = board_configs['ux500'].get_boot_cmd( + boot_cmd = board_configs['ux500']._get_boot_cmd( is_live=False, is_lowmem=False, consoles=None) expected = ( "setenv bootcmd 'fatload mmc 1:1 0x00100000 uImage; fatload mmc " @@ -130,7 +129,7 @@ class TestGetBootCmd(TestCase): self.assertEqual(expected, boot_cmd) def test_panda(self): - boot_cmd = board_configs['panda'].get_boot_cmd( + boot_cmd = board_configs['panda']._get_boot_cmd( is_live=False, is_lowmem=False, consoles=None) expected = ( "setenv bootcmd 'fatload mmc 0:1 0x80200000 uImage; fatload mmc " @@ -142,7 +141,7 @@ class TestGetBootCmd(TestCase): self.assertEqual(expected, boot_cmd) def test_beagle(self): - boot_cmd = board_configs['beagle'].get_boot_cmd( + boot_cmd = board_configs['beagle']._get_boot_cmd( is_live=False, is_lowmem=False, consoles=None) expected = ( "setenv bootcmd 'fatload mmc 0:1 0x80000000 uImage; " @@ -229,7 +228,7 @@ class TestPopulateBoot(TestCaseWithFixtures): def _mock_get_file_matching(self): self.useFixture(MockSomethingFixture( - populate_boot, '_get_file_matching', + boards, '_get_file_matching', lambda regex: regex)) def _mock_Popen(self): @@ -258,14 +257,15 @@ class TestPopulateBoot(TestCaseWithFixtures): self.assertEqual([expected], fixture.mock.calls) def test_make_boot_script(self): + self.useFixture(MockSomethingFixture( + tempfile, 'mkstemp', lambda: (-1, '/tmp/random-abxzr'))) self._mock_get_file_matching() fixture = self._mock_Popen() - tempdir = self.useFixture(CreateTempDirFixture()).tempdir - make_boot_script('boot script data', tempdir, 'boot_script') + make_boot_script('boot script data', 'boot_script') expected = [ 'sudo', 'mkimage', '-A', 'arm', '-O', 'linux', '-T', 'script', '-C', 'none', '-a', '0', '-e', '0', '-n', 'boot script', - '-d', '%s/boot.cmd' % tempdir, 'boot_script'] + '-d', '/tmp/random-abxzr', 'boot_script'] self.assertEqual([expected], fixture.mock.calls) def test_get_file_matching(self): |