=== modified file 'linaro_image_tools/hwpack/config.py'
--- linaro_image_tools/hwpack/config.py	2011-08-18 14:11:28 +0000
+++ linaro_image_tools/hwpack/config.py	2011-08-18 15:46:52 +0000
@@ -21,6 +21,7 @@
 
 import ConfigParser
 import re
+import string
 
 from linaro_image_tools.hwpack.hardwarepack_format import (
     HardwarePackFormatV1,
@@ -43,6 +44,7 @@
     PACKAGES_KEY = "packages"
     PACKAGE_REGEX = NAME_REGEX
     PATH_REGEX = r"\w[\w+\-./_]+$"
+    GLOB_REGEX = r"\w[\w+\-./_\*]+$"
     ORIGIN_KEY = "origin"
     MAINTAINER_KEY = "maintainer"
     ARCHITECTURES_KEY = "architectures"
@@ -53,6 +55,7 @@
     KERNEL_ADDR_KEY = "kernel_addr"
     INITRD_ADDR_KEY = "initrd_addr"
     LOAD_ADDR_KEY = "load_addr"
+    DTB_ADDR_KEY = "dtb_addr"
     WIRED_INTERFACES_KEY = "wired_interfaces"
     WIRELESS_INTERFACES_KEY = "wireless_interfaces"
     PARTITION_LAYOUT_KEY = "partition_layout"
@@ -63,6 +66,13 @@
     LOADER_MIN_SIZE_KEY = "loader_min_size"
     X_LOADER_PACKAGE_KEY = "x_loader_package"
     X_LOADER_FILE_KEY = "x_loader_file"
+    VMLINUZ_KEY = "kernel_file"
+    INITRD_KEY = "initrd_file"
+    DTB_FILE_KEY = "dtb_file"
+    EXTRA_BOOT_OPTIONS_KEY = 'extra_boot_options'
+    BOOT_SCRIPT_KEY = 'boot_script'
+    UBOOT_IN_BOOT_PART_KEY = 'u_boot_in_boot_part'
+    EXTRA_SERIAL_OPTS_KEY = 'extra_serial_options'
 
     DEFINED_PARTITION_LAYOUTS = [
         'bootfs16_rootfs',
@@ -101,6 +111,7 @@
             self._validate_kernel_addr()
             self._validate_initrd_addr()
             self._validate_load_addr()
+            self._validate_dtb_addr()
             self._validate_wired_interfaces()
             self._validate_wireless_interfaces()
             self._validate_partition_layout()
@@ -110,6 +121,13 @@
             self._validate_loader_min_size()
             self._validate_x_loader_package()
             self._validate_x_loader_file()
+            self._validate_vmlinuz()
+            self._validate_initrd()
+            self._validate_dtb_file()
+            self._validate_extra_boot_options()
+            self._validate_boot_script()
+            self._validate_uboot_in_boot_part()
+            self._validate_extra_serial_opts()
 
         self._validate_sections()
 
@@ -150,6 +168,11 @@
         except ConfigParser.NoOptionError:
             return True
 
+    @property
+    def uboot_in_boot_part(self):
+        """Whether uboot binary should be put in the boot partition. A str."""
+        return self.parser.get(self.MAIN_SECTION, self.UBOOT_IN_BOOT_PART_KEY)
+
     def _get_option_from_main_section(self, key):
         """Get the value from the main section for the given key.
 
@@ -176,6 +199,30 @@
         return self._get_option_from_main_section(self.SERIAL_TTY_KEY)
 
     @property
+    def extra_boot_options(self):
+        """Extra boot arg options.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.EXTRA_BOOT_OPTIONS_KEY)
+
+    @property
+    def extra_serial_opts(self):
+        """Extra serial options.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.EXTRA_SERIAL_OPTS_KEY)
+
+    @property
+    def boot_script(self):
+        """File name of the target boot script.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.BOOT_SCRIPT_KEY)
+
+    @property
     def kernel_addr(self):
         """address where u-boot should load the kernel 
 
@@ -200,6 +247,14 @@
         return self._get_option_from_main_section(self.LOAD_ADDR_KEY)
 
     @property
+    def dtb_addr(self):
+        """address for dtb image generation
+
+        An int.
+        """
+        return self._get_option_from_main_section(self.DTB_ADDR_KEY)
+
+    @property
     def wired_interfaces(self):
         """The interfaces for wired networks
 
@@ -333,6 +388,30 @@
         return self._get_option_from_main_section(self.X_LOADER_FILE_KEY)
 
     @property
+    def vmlinuz(self):
+        """The path to the vmlinuz kernel.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.VMLINUZ_KEY)
+
+    @property
+    def initrd(self):
+        """The path to initrd
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.INITRD_KEY)
+
+    @property
+    def dtb_file(self):
+        """The path to the device tree binary.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.DTB_FILE_KEY)
+
+    @property
     def architectures(self):
         """The architectures to build the hwpack for.
 
@@ -399,6 +478,46 @@
                 self.PATH_REGEX, x_loader_file, "Invalid path: %s" % \
                     x_loader_file)
 
+    def _validate_vmlinuz(self):
+        vmlinuz = self.vmlinuz
+        if not vmlinuz:
+            raise HwpackConfigError("No kernel_file in the [%s] section" % \
+                                        self.MAIN_SECTION)
+        self._assert_matches_pattern(
+            self.GLOB_REGEX, vmlinuz, "Invalid path: %s" % vmlinuz)
+
+    def _validate_initrd(self):
+        initrd = self.initrd
+        if not initrd:
+            raise HwpackConfigError("No initrd_file in the [%s] section" % \
+                                        self.MAIN_SECTION)
+        self._assert_matches_pattern(
+            self.GLOB_REGEX, initrd, "Invalid path: %s" % initrd)
+
+    def _validate_dtb_file(self):
+        dtb_file = self.dtb_file
+        if dtb_file is not None:
+            self._assert_matches_pattern(
+                self.GLOB_REGEX, dtb_file, "Invalid path: %s" % dtb_file)
+        
+    def _validate_extra_boot_options(self):
+        # Optional and tricky to determine a valid pattern.
+        pass
+
+    def _validate_extra_serial_opts(self):
+        # Optional and tricky to determine a valid pattern.
+        pass
+
+    def _validate_boot_script(self):
+        boot_script = self.boot_script
+        if not boot_script:
+            raise HwpackConfigError(
+                "No boot_script in the [%s] section" % \
+                    self.MAIN_SECTION)
+        else:
+            self._assert_matches_pattern(
+                self.PATH_REGEX, boot_script, "Invalid path: %s" % boot_script)
+
     def _validate_serial_tty(self):
         serial_tty = self.serial_tty
         if serial_tty is None:
@@ -430,6 +549,13 @@
         if not self._validate_addr(addr):
             raise HwpackConfigError("Invalid load address: %s" % addr)
 
+    def _validate_dtb_addr(self):
+        addr = self.dtb_addr
+        if addr is None:
+            return
+        if not self._validate_addr(addr):
+            raise HwpackConfigError("Invalid dtb address: %s" % addr)
+
     def _validate_wired_interfaces(self):
         pass
 
@@ -491,6 +617,13 @@
                 "Invalid value for include-debs: %s"
                 % self.parser.get("hwpack", "include-debs"))
 
+    def _validate_uboot_in_boot_part(self):
+        uboot_in_boot_part = self.uboot_in_boot_part
+        if string.lower(uboot_in_boot_part) not in ['yes', 'no']:
+            raise HwpackConfigError(
+                "Invalid value for u_boot_in_boot_part: %s"
+                % self.parser.get("hwpack", "u_boot_in_boot_part"))
+
     def _validate_support(self):
         support = self.support
         if support not in (None, "supported", "unsupported"):

=== modified file 'linaro_image_tools/hwpack/hardwarepack.py'
--- linaro_image_tools/hwpack/hardwarepack.py	2011-08-02 16:46:24 +0000
+++ linaro_image_tools/hwpack/hardwarepack.py	2011-08-18 13:46:36 +0000
@@ -78,10 +78,13 @@
 
     @classmethod
     def add_v2_config(self, serial_tty=None, kernel_addr=None, initrd_addr=None,
-                      load_addr=None, fdt=None, wired_interfaces=[],
+                      load_addr=None, dtb_file=None, wired_interfaces=[],
                       wireless_interfaces=[], partition_layout=None,
                       mmc_id=None, boot_min_size=None, root_min_size=None,
-                      loader_min_size=None):
+                      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):
         """Add fields that are specific to the new format.
 
         These fields are not present in earlier config files.
@@ -99,6 +102,14 @@
         self.root_min_size = root_min_size
         self.loader_min_size = loader_min_size
         self.x_loader = None
+        self.vmlinuz = vmlinuz
+        self.initrd = initrd
+        self.dtb_file = dtb_file
+        self.dtb_addr = dtb_addr
+        self.extra_boot_options = extra_boot_options
+        self.boot_script = boot_script
+        self.uboot_in_boot_part = uboot_in_boot_part
+        self.extra_serial_opts = extra_serial_opts
 
     @classmethod
     def from_config(cls, config, version, architecture):
@@ -134,7 +145,15 @@
                                    mmc_id=config.mmc_id,
                                    boot_min_size=config.boot_min_size,
                                    root_min_size=config.root_min_size,
-                                   loader_min_size=config.loader_min_size)
+                                   loader_min_size=config.loader_min_size,
+                                   vmlinuz=config.vmlinuz,
+                                   initrd=config.initrd,
+                                   dtb_file=config.dtb_file,
+                                   dtb_addr=config.dtb_addr,
+                                   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)
         return metadata
 
     def __str__(self):
@@ -162,6 +181,8 @@
             metadata += "INITRD_ADDR=%s\n" % self.initrd_addr
         if self.load_addr is not None:
             metadata += "LOAD_ADDR=%s\n" % self.load_addr
+        if self.dtb_addr is not None:
+            metadata += "DTB_ADDR=%s\n" % self.dtb_addr
         if self.wired_interfaces != []:
             metadata += "WIRED_INTERFACES=%s\n" % " ".join(self.wired_interfaces)
         if self.wireless_interfaces != []:
@@ -179,6 +200,20 @@
             metadata += "LOADER_MIN_SIZE=%s\n" % self.loader_min_size
         if self.x_loader is not None:
             metadata += "X_LOADER=%s\n" % self.x_loader
+        if self.vmlinuz is not None:
+            metadata += "KERNEL_FILE=%s\n" % self.vmlinuz
+        if self.initrd is not None:
+            metadata += "INITRD_FILE=%s\n" % self.initrd
+        if self.dtb_file is not None:
+            metadata += "DTB_FILE=%s\n" % self.dtb_file
+        if self.extra_boot_options is not None:
+            metadata += "EXTRA_BOOT_OPTIONS=%s\n" % self.extra_boot_options
+        if self.boot_script is not None:
+            metadata += "BOOT_SCRIPT=%s\n" % self.boot_script
+        if self.uboot_in_boot_part is not None:
+            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
 
         return metadata
 

=== modified file 'linaro_image_tools/hwpack/tests/test_builder.py'
--- linaro_image_tools/hwpack/tests/test_builder.py	2011-08-18 14:11:28 +0000
+++ linaro_image_tools/hwpack/tests/test_builder.py	2011-08-18 14:12:33 +0000
@@ -119,7 +119,11 @@
                           'u-boot-file': 'wanted-file', 
                           'partition_layout': 'bootfs_rootfs',
                           'x_loader_package': 'x-loader-omap4-panda',
-                          'x_loader_file': 'usr/lib/x-loader/omap4430panda/MLO'}
+                          'x_loader_file': 'usr/lib/x-loader/omap4430panda/MLO',
+                          'kernel_file': 'boot/vmlinuz-3.0.0-1002-linaro-omap',
+                          'initrd_file': 'boot/initrd.img-3.0.0-1002-linaro-omap',
+                          'boot_script': 'boot.scr',
+                          'u_boot_in_boot_part': 'no'}
 
     def test_raises_on_missing_configuration(self):
         e = self.assertRaises(

=== modified file 'linaro_image_tools/hwpack/tests/test_config.py'
--- linaro_image_tools/hwpack/tests/test_config.py	2011-08-18 14:11:28 +0000
+++ linaro_image_tools/hwpack/tests/test_config.py	2011-08-18 15:46:52 +0000
@@ -37,7 +37,15 @@
                              "u-boot.bin\nserial_tty=ttySAC1\n" \
                              "partition_layout = bootfs_rootfs\n"\
                              "x_loader_package = x-loader-omap4-panda\n"\
-                             "x_loader_file = usr/lib/x-loader/omap4430panda/MLO\n")
+                             "x_loader_file = usr/lib/x-loader/omap4430panda/MLO\n"\
+                             "kernel_file = boot/vmlinuz-*-linaro-omap\n"\
+                             "initrd_file = boot/initrd.img-*-linaro-omap\n"\
+                             "dtb_file = boot/dt-*-linaro-omap/omap4-panda.dtb\n"\
+                             "boot_script = boot.scr\n"\
+                             "extra_serial_options = console=tty0 console=ttyO2,115200n8\n"\
+                             "extra_boot_options = earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000\n"\
+                             "boot_script = boot.scr\n"\
+                             "u_boot_in_boot_part = Yes\n")
     valid_end = "[ubuntu]\nsources-entry = foo bar\n"
 
     def test_create(self):
@@ -199,6 +207,72 @@
                                      "u_boot_file = ~~\n")
         self.assertValidationError("Invalid path: ~~", config)
 
+    def test_validate_invalid_kernel_file(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = ~~\n")
+        self.assertValidationError("Invalid path: ~~", config)
+
+    def test_validate_empty_kernel_file(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n"
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = \n")
+        self.assertValidationError("No kernel_file in the [hwpack] section", config)
+
+    def test_validate_invalid_initrd_file(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = ~~\n")
+        self.assertValidationError("Invalid path: ~~", config)
+
+    def test_validate_empty_initrd_file(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n"
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = \n")
+        self.assertValidationError("No initrd_file in the [hwpack] section", config)
+
+    def test_validate_empty_boot_script(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n"
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = boot/initrd.img-3.0.0-1002-linaro-omap\n")
+        self.assertValidationError("No boot_script in the [hwpack] section", config)
+
+    def test_validate_invalid_boot_script(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = boot/initrd.img-3.0.0-1002-linaro-omap\n"\
+                                     "u_boot_in_boot_part = No\n"\
+                                     "boot_script = ~~\n")
+        self.assertValidationError("Invalid path: ~~", config)
+
+    def test_validate_invalid_dtb_file(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = boot/initrd.img-3.0.0-1002-linaro-omap\n"\
+                                     "boot_script = boot.scr\n"\
+                                     "u_boot_in_boot_part = No\n"\
+                                     "dtb_file = ~~\n")
+        self.assertValidationError("Invalid path: ~~", config)
+
     def test_validate_invalid_x_loader_package_name(self):
         config = self.get_config(
             self.valid_start_v2 + "u-boot-package = u-boot-linaro-s5pv310\n" \
@@ -236,6 +310,28 @@
     def test_validate_wireless_interfaces(self):
         self.assertTrue("XXX What is an invalid interface name?")
 
+    def test_validate_u_boot_in_boot_part(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = boot/initrd.img-3.0.0-1002-linaro-omap\n"\
+                                     "boot_script = boot.scr\n"\
+                                     "u_boot_in_boot_part = Nope\n")
+        self.assertValidationError("Invalid value for u_boot_in_boot_part: Nope", config)
+
+    def test_validate_u_boot_in_boot_part_bool(self):
+        config = self.get_config(self.valid_start_v2 + 
+                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
+                                     "u-boot-file = u-boot.bin\n" \
+                                     "partition_layout = bootfs_rootfs\n"\
+                                     "kernel_file = boot/vmlinuz-3.0.0-1002-linaro-omap\n"\
+                                     "initrd_file = boot/initrd.img-3.0.0-1002-linaro-omap\n"\
+                                     "boot_script = boot.scr\n"\
+                                     "u_boot_in_boot_part = True\n")
+        self.assertValidationError("Invalid value for u_boot_in_boot_part: True", config)
+
     def test_validate_serial_tty(self):
         config = self.get_config(self.valid_start_v2 +
                                  "u_boot_package = u-boot-linaro-s5pv310\n" \
@@ -300,6 +396,17 @@
                                  "load_addr = 80000000\n")
         self.assertValidationError("Invalid load address: 80000000", config)
 
+    def test_validate_dtb_addr(self):
+        config = self.get_config(self.valid_complete_v2 + 
+                                 "dtb_addr = 0x8000000\n")
+        self.assertValidationError("Invalid dtb address: 0x8000000", config)
+        config = self.get_config(self.valid_complete_v2 + 
+                                 "dtb_addr = 0x8000000x\n")
+        self.assertValidationError("Invalid dtb address: 0x8000000x", config)
+        config = self.get_config(self.valid_complete_v2 + 
+                                 "dtb_addr = 80000000\n")
+        self.assertValidationError("Invalid dtb address: 80000000", config)
+
     def test_wired_interfaces(self):
         config = self.get_config(self.valid_complete_v2 + 
                                  "wired_interfaces = eth0\n" + 
@@ -348,6 +455,48 @@
         self.assertEqual("usr/lib/x-loader/omap4430panda/MLO",
                          config.x_loader_file)
 
+    def test_kernel_file(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("boot/vmlinuz-*-linaro-omap",
+                         config.vmlinuz)
+
+    def test_initrd_file(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("boot/initrd.img-*-linaro-omap",
+                         config.initrd)
+
+    def test_dtb_file(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("boot/dt-*-linaro-omap/omap4-panda.dtb",
+                         config.dtb_file)
+
+    def test_extra_boot_options(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000",
+                         config.extra_boot_options)
+
+    def test_extra_serial_opts(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("console=tty0 console=ttyO2,115200n8",
+                         config.extra_serial_opts)
+
+    def test_boot_script(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("boot.scr",
+                         config.boot_script)
+
+    def test_u_boot_in_boot_part(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("Yes",
+                         config.uboot_in_boot_part)
+
     def test_x_loader_package(self):
         config = self.get_config(self.valid_complete_v2 + self.valid_end)
         config.validate()
@@ -423,6 +572,18 @@
         config.validate()
         self.assertEqual("0x8aBcdEFf", config.load_addr)
 
+    def test_dtb_addr(self):
+        config = self.get_config(self.valid_complete_v2 + 
+                                 "dtb_addr = 0x80000000\n" + 
+                                 self.valid_end)
+        config.validate()
+        self.assertEqual("0x80000000", config.dtb_addr)
+        config = self.get_config(self.valid_complete_v2 + 
+                                 "dtb_addr = 0x8aBcdEFf\n" + 
+                                 self.valid_end)
+        config.validate()
+        self.assertEqual("0x8aBcdEFf", config.dtb_addr)
+
     def test_name(self):
         config = self.get_config(
             "[hwpack]\nname = ahwpack\npackages = foo\n"

=== modified file 'linaro_image_tools/hwpack/tests/test_hardwarepack.py'
--- linaro_image_tools/hwpack/tests/test_hardwarepack.py	2011-06-29 14:30:25 +0000
+++ linaro_image_tools/hwpack/tests/test_hardwarepack.py	2011-08-18 13:46:36 +0000
@@ -147,6 +147,15 @@
             "LOAD_ADDR=0x80000000\n",
             str(metadata))
 
+    def test_str_with_dtb_addr(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(dtb_addr='0x80000000')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "DTB_ADDR=0x80000000\n",
+            str(metadata))
+
     def test_str_with_wired_interfaces(self):
         metadata = Metadata("ahwpack", "4", "armel",
                             format=HardwarePackFormatV2())
@@ -210,6 +219,60 @@
             "LOADER_MIN_SIZE=1\n",
             str(metadata))
 
+    def test_str_with_kernel_file(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(vmlinuz='boot/vmlinuz-3.0.0-1002-linaro-omap')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "KERNEL_FILE=boot/vmlinuz-3.0.0-1002-linaro-omap\n",
+            str(metadata))
+
+    def test_str_with_initrd_file(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(initrd='boot/initrd.img-3.0.0-1002-linaro-omap')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "INITRD_FILE=boot/initrd.img-3.0.0-1002-linaro-omap\n",
+            str(metadata))
+
+    def test_str_with_dtb_file(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(dtb_file='boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "DTB_FILE=boot/dt-3.0.0-1002-linaro-omap/omap4-panda.dtb\n",
+            str(metadata))
+
+    def test_str_with_boot_script(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(boot_script='boot.scr')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "BOOT_SCRIPT=boot.scr\n",
+            str(metadata))
+
+    def test_str_with_extra_boot_options(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(extra_boot_options='earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "EXTRA_BOOT_OPTIONS=earlyprintk fixrtc nocompcache vram=48M omapfb.vram=0:24M mem=456M@0x80000000 mem=512M@0xA0000000\n",
+            str(metadata))
+
+    def test_str_with_extra_serial_options(self):
+        metadata = Metadata("ahwpack", "4", "armel",
+                            format=HardwarePackFormatV2())
+        metadata.add_v2_config(extra_serial_opts='console=tty0 console=ttyO2,115200n8')
+        self.assertEqual(
+            "NAME=ahwpack\nVERSION=4\nARCHITECTURE=armel\n"
+            "EXTRA_SERIAL_OPTIONS=console=tty0 console=ttyO2,115200n8\n",
+            str(metadata))
+
     def test_from_config(self):
         class Config:
             name = "foo"

=== modified file 'linaro_image_tools/media_create/boards.py'
--- linaro_image_tools/media_create/boards.py	2011-08-24 14:04:45 +0000
+++ linaro_image_tools/media_create/boards.py	2011-08-24 14:05:56 +0000
@@ -34,6 +34,7 @@
 import tarfile
 import ConfigParser
 import shutil
+import string
 
 from linaro_image_tools import cmd_runner
 
@@ -243,17 +244,20 @@
     load_addr = None
     dtb_addr = None
     dtb_name = None
+    dtb_file = None
     kernel_flavors = None
     boot_script = None
     serial_tty = None
     wired_interfaces = None
     wireless_interfaces = None
     mmc_id = None
+    vmlinuz = None
+    initrd = None
 
     hardwarepack_handler = None
 
     @classmethod
-    def get_metadata_field(cls, target, field_name):
+    def get_metadata_field(cls, field_name):
         """ Return the metadata value for field_name if it can be found.
         """
         data, _ = cls.hardwarepack_handler.get_field(
@@ -276,24 +280,30 @@
                 cls.load_addr = None
                 cls.serial_tty = None
                 cls.fat_size = None
+                cls.dtb_name = None
+                cls.dtb_addr = None
+                cls.extra_boot_args_options = None
+                cls.boot_script = None
+                cls.kernel_flavors = None
 
             # Set new values from metadata.
-            cls.kernel_addr = cls.get_metadata_field(
-                cls.kernel_addr, 'kernel_addr')
-            cls.initrd_addr = cls.get_metadata_field(
-                cls.initrd_addr, 'initrd_addr')
-            cls.load_addr = cls.get_metadata_field(
-                cls.load_addr, 'load_addr')
-            cls.serial_tty = cls.get_metadata_field(
-                cls.serial_tty, 'serial_tty')
-            cls.wired_interfaces = cls.get_metadata_field(
-                cls.wired_interfaces, 'wired_interfaces')
-            cls.wireless_interfaces = cls.get_metadata_field(
-                cls.wireless_interfaces, 'wireless_interfaces')
-            cls.mmc_id = cls.get_metadata_field(
-                cls.mmc_id, 'mmc_id')
+            cls.kernel_addr = cls.get_metadata_field('kernel_addr')
+            cls.initrd_addr = cls.get_metadata_field('initrd_addr')
+            cls.load_addr = cls.get_metadata_field('load_addr')
+            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.mmc_id = cls.get_metadata_field('mmc_id')
+            cls.vmlinuz = cls.get_metadata_field('kernel_file')
+            cls.initrd = cls.get_metadata_field('initrd_file')
+            cls.dtb_file = cls.get_metadata_field('dtb_file')
+            cls.extra_boot_args_options = cls.get_metadata_field(
+                'extra_boot_options')
+            cls.boot_script = cls.get_metadata_field('boot_script')
+            cls.extra_serial_opts = cls.get_metadata_field('extra_serial_options')
 
-            partition_layout = cls.get_metadata_field(cls.fat_size, 'partition_layout')
+            partition_layout = cls.get_metadata_field('partition_layout')
             if partition_layout == 'bootfs_rootfs' or partition_layout is None:
                 cls.fat_size = 32
             elif partition_layout == 'bootfs16_rootfs':
@@ -301,22 +311,26 @@
             else:
                 raise AssertionError("Unknown partition layout '%s'." % partition_layout)
 
-            boot_min_size = cls.get_metadata_field(
-                cls.BOOT_MIN_SIZE_S, 'boot_min_size')
+            boot_min_size = cls.get_metadata_field('boot_min_size')
             if boot_min_size is not None:
                 cls.BOOT_MIN_SIZE_S = align_up(int(boot_min_size) * 1024**2,
                                                SECTOR_SIZE) / SECTOR_SIZE
-            root_min_size = cls.get_metadata_field(
-                cls.ROOT_MIN_SIZE_S, 'root_min_size')
+            root_min_size = cls.get_metadata_field('root_min_size')
             if root_min_size is not None:
                 cls.ROOT_MIN_SIZE_S = align_up(int(root_min_size) * 1024**2,
                                                SECTOR_SIZE) / SECTOR_SIZE
-            loader_min_size = cls.get_metadata_field(
-                cls.LOADER_MIN_SIZE_S, 'loader_min_size')
+            loader_min_size = cls.get_metadata_field('loader_min_size')
             if loader_min_size is not None:
                 cls.LOADER_MIN_SIZE_S = align_up(int(loader_min_size) * 1024**2,
                                                SECTOR_SIZE) / SECTOR_SIZE
 
+            uboot_in_boot_part = cls.get_metadata_field('u_boot_in_boot_part')
+            if uboot_in_boot_part is None:
+                cls.uboot_in_boot_part = None  
+            elif string.lower(uboot_in_boot_part) == 'yes':
+                cls.uboot_in_boot_part = True
+            elif string.lower(uboot_in_boot_part) == 'no':
+                cls.uboot_in_boot_part = False
 
     @classmethod
     def get_file(cls, file_alias, default=None):
@@ -436,7 +450,7 @@
     def make_boot_files(cls, uboot_parts_dir, is_live, is_lowmem, consoles,
                         chroot_dir, rootfs_uuid, boot_dir, boot_device_or_file):
         (k_img_data, i_img_data, d_img_data) = cls._get_kflavor_files(
-                                                   uboot_parts_dir)
+            uboot_parts_dir)
         boot_env = cls._get_boot_env(is_live, is_lowmem, consoles, rootfs_uuid,
                                      d_img_data)
         cls._make_boot_files(
@@ -487,6 +501,11 @@
     @classmethod
     def _get_kflavor_files(cls, path):
         """Search for kernel, initrd and optional dtb in path."""
+        if cls.kernel_flavors is None:
+            # V2 metadata specifies each glob, not flavors.
+            # XXX This duplication is temporary until V1 dies.
+            return cls._get_kflavor_files_v2(path)
+
         for flavor in cls.kernel_flavors:
             kregex = KERNEL_GLOB % {'kernel_flavor' : flavor}
             iregex = INITRD_GLOB % {'kernel_flavor' : flavor}
@@ -508,6 +527,23 @@
                 KERNEL_GLOB, " ".join(cls.kernel_flavors)))
 
     @classmethod
+    def _get_kflavor_files_v2(cls, path):
+        kernel = _get_file_matching(os.path.join(path, cls.vmlinuz))
+        if kernel is not None:
+            initrd = _get_file_matching(os.path.join(path, cls.initrd))
+            if initrd is not None:
+                dtb = None
+                if cls.dtb_file is not None:
+                    dtb = _get_file_matching(os.path.join(path, cls.dtb_file))
+                print "Will use kernel=%s, initrd=%s, dtb=%s." % (kernel, initrd, dtb)
+                return (kernel, initrd, dtb)
+            raise ValueError(
+                "Found kernel matching %s but no initrd matching %s" % (
+                    cls.vmlinuz, cls.initrd))
+        raise ValueError(
+            "No kernel found matching %s." % (cls.vmlinuz))
+
+    @classmethod
     def populate_raw_partition(cls, media, boot_dir):
         # Override in subclass if needed
         pass

