=== modified file 'linaro_image_tools/hwpack/builder.py'
--- linaro_image_tools/hwpack/builder.py	2011-07-28 10:33:14 +0000
+++ linaro_image_tools/hwpack/builder.py	2011-08-02 16:46:24 +0000
@@ -123,6 +123,8 @@
                 packages = self.config.packages[:]
                 if self.config.u_boot_package is not None:
                     packages.append(self.config.u_boot_package)
+                if self.config.x_loader_package is not None:
+                    packages.append(self.config.x_loader_package)
                 local_packages = [
                     FetchedPackage.from_deb(deb)
                     for deb in self.local_debs]
@@ -148,6 +150,13 @@
                                 u_boot_package, self.config.u_boot_file,
                                 package_unpacker, hwpack, hwpack.U_BOOT_DIR)
 
+                        if self.config.x_loader_package is not None:
+                            x_loader_package = self.find_fetched_package(
+                                packages, self.config.x_loader_package)
+                            hwpack.metadata.x_loader = self.add_file_to_hwpack(
+                                x_loader_package, self.config.x_loader_file,
+                                package_unpacker, hwpack, hwpack.U_BOOT_DIR)
+
                         logger.debug("Adding packages to hwpack")
                         hwpack.add_packages(packages)
                         for local_package in local_packages:

=== modified file 'linaro_image_tools/hwpack/config.py'
--- linaro_image_tools/hwpack/config.py	2011-07-01 14:55:14 +0000
+++ linaro_image_tools/hwpack/config.py	2011-08-18 14:11:28 +0000
@@ -42,13 +42,13 @@
     SOURCES_ENTRY_KEY = "sources-entry"
     PACKAGES_KEY = "packages"
     PACKAGE_REGEX = NAME_REGEX
-    PATH_REGEX = r"[a-z0-9][a-z0-9+\-./_]+$"
+    PATH_REGEX = r"\w[\w+\-./_]+$"
     ORIGIN_KEY = "origin"
     MAINTAINER_KEY = "maintainer"
     ARCHITECTURES_KEY = "architectures"
     ASSUME_INSTALLED_KEY = "assume-installed"
-    U_BOOT_PACKAGE_KEY = "u-boot-package"
-    U_BOOT_FILE_KEY = "u-boot-file"
+    U_BOOT_PACKAGE_KEY = "u_boot_package"
+    U_BOOT_FILE_KEY = "u_boot_file"
     SERIAL_TTY_KEY = "serial_tty"
     KERNEL_ADDR_KEY = "kernel_addr"
     INITRD_ADDR_KEY = "initrd_addr"
@@ -61,6 +61,8 @@
     BOOT_MIN_SIZE_KEY = "boot_min_size"
     ROOT_MIN_SIZE_KEY = "root_min_size"
     LOADER_MIN_SIZE_KEY = "loader_min_size"
+    X_LOADER_PACKAGE_KEY = "x_loader_package"
+    X_LOADER_FILE_KEY = "x_loader_file"
 
     DEFINED_PARTITION_LAYOUTS = [
         'bootfs16_rootfs',
@@ -106,6 +108,8 @@
             self._validate_boot_min_size()
             self._validate_root_min_size()
             self._validate_loader_min_size()
+            self._validate_x_loader_package()
+            self._validate_x_loader_file()
 
         self._validate_sections()
 
@@ -313,6 +317,22 @@
         return self._get_option_from_main_section(self.U_BOOT_FILE_KEY)
 
     @property
+    def x_loader_package(self):
+        """The x-loader package that contains the x-loader bin.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.X_LOADER_PACKAGE_KEY)
+
+    @property
+    def x_loader_file(self):
+        """The x-loader bin file that will be unpacked from the x-loader package.
+
+        A str.
+        """
+        return self._get_option_from_main_section(self.X_LOADER_FILE_KEY)
+
+    @property
     def architectures(self):
         """The architectures to build the hwpack for.
 
@@ -368,11 +388,16 @@
 
     def _validate_u_boot_file(self):
         u_boot_file = self.u_boot_file
-        if not u_boot_file:
-            raise HwpackConfigError("No u_boot_file in the [%s] section" % \
-                                        self.MAIN_SECTION)
-        self._assert_matches_pattern(
-            self.PATH_REGEX, u_boot_file, "Invalid path: %s" % u_boot_file)
+        if u_boot_file is not None:
+            self._assert_matches_pattern(
+                self.PATH_REGEX, u_boot_file, "Invalid path: %s" % u_boot_file)
+
+    def _validate_x_loader_file(self):
+        x_loader_file = self.x_loader_file
+        if x_loader_file is not None:
+            self._assert_matches_pattern(
+                self.PATH_REGEX, x_loader_file, "Invalid path: %s" % \
+                    x_loader_file)
 
     def _validate_serial_tty(self):
         serial_tty = self.serial_tty
@@ -486,14 +511,20 @@
 
     def _validate_u_boot_package(self):
         u_boot_package = self.u_boot_package
-        if not u_boot_package:
-            raise HwpackConfigError(
-                "No %s in the [%s] section"
-                % (self.U_BOOT_PACKAGE_KEY, self.MAIN_SECTION))
-        self._assert_matches_pattern(
-            self.PACKAGE_REGEX, u_boot_package, "Invalid value in %s in the " \
-                "[%s] section: %s" % (self.U_BOOT_PACKAGE_KEY,
-                                      self.MAIN_SECTION, u_boot_package))
+        if u_boot_package is not None:
+            self._assert_matches_pattern(
+                self.PACKAGE_REGEX, u_boot_package, "Invalid value in %s in " \
+                    "the [%s] section: %s" % (self.U_BOOT_PACKAGE_KEY,
+                                              self.MAIN_SECTION, u_boot_package))
+
+    def _validate_x_loader_package(self):
+        x_loader_package = self.x_loader_package
+        if x_loader_package is not None:
+            self._assert_matches_pattern(
+                self.PACKAGE_REGEX, x_loader_package, "Invalid value in %s in " \
+                    "the [%s] section: %s" % (self.X_LOADER_PACKAGE_KEY,
+                                              self.MAIN_SECTION,
+                                              x_loader_package))
 
     def _validate_architectures(self):
         architectures = self.architectures

=== modified file 'linaro_image_tools/hwpack/hardwarepack.py'
--- linaro_image_tools/hwpack/hardwarepack.py	2011-06-29 14:25:49 +0000
+++ linaro_image_tools/hwpack/hardwarepack.py	2011-08-02 16:46:24 +0000
@@ -98,6 +98,7 @@
         self.boot_min_size = boot_min_size
         self.root_min_size = root_min_size
         self.loader_min_size = loader_min_size
+        self.x_loader = None
 
     @classmethod
     def from_config(cls, config, version, architecture):
@@ -176,6 +177,8 @@
             metadata += "ROOT_MIN_SIZE=%s\n" % self.root_min_size
         if self.loader_min_size is not None:
             metadata += "LOADER_MIN_SIZE=%s\n" % self.loader_min_size
+        if self.x_loader is not None:
+            metadata += "X_LOADER=%s\n" % self.x_loader
 
         return metadata
 

=== modified file 'linaro_image_tools/hwpack/tests/test_builder.py'
--- linaro_image_tools/hwpack/tests/test_builder.py	2011-06-20 13:46:16 +0000
+++ linaro_image_tools/hwpack/tests/test_builder.py	2011-08-18 14:11:28 +0000
@@ -115,6 +115,11 @@
     def setUp(self):
         super(HardwarePackBuilderTests, self).setUp()
         self.useFixture(ChdirToTempdirFixture())
+        self.extra_config={'format': '2.0', 'u-boot-package': 'wanted-package',
+                          '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'}
 
     def test_raises_on_missing_configuration(self):
         e = self.assertRaises(
@@ -156,9 +161,7 @@
                                                     wanted_package])
         _, config = self.makeMetaDataAndConfigFixture(
             [package_name, wanted_package_name], sources_dict,
-            extra_config={'format': '2.0', 'u-boot-package': 'wanted-package',
-                          'u-boot-file': 'wanted-file', 
-                          'partition_layout': 'bootfs_rootfs'})
+            extra_config=self.extra_config)
         builder = HardwarePackBuilder(config.filename, "1.0", [])
         found_package = builder.find_fetched_package(
             [available_package, wanted_package], wanted_package_name)
@@ -174,9 +177,7 @@
                                                     wanted_package])
         _, config = self.makeMetaDataAndConfigFixture(
             [package_name, wanted_package_name], sources_dict,
-            extra_config={'format': '2.0', 'u-boot-package': 'wanted-package',
-                          'u-boot-file': 'wanted-file', 
-                          'partition_layout': 'bootfs_rootfs'})
+            extra_config=self.extra_config)
         builder = HardwarePackBuilder(config.filename, "1.0", [])
         packages = [available_package, wanted_package]
         builder.find_fetched_package(packages, wanted_package_name)
@@ -190,9 +191,7 @@
         sources_dict = self.sourcesDictForPackages([available_package])
         _, config = self.makeMetaDataAndConfigFixture(
             [package_name], sources_dict,
-            extra_config={'format': '2.0', 'u-boot-package': 'wanted-package',
-                          'u-boot-file': 'wanted-file', 
-                          'partition_layout': 'bootfs_rootfs'})
+            extra_config=self.extra_config)
         builder = HardwarePackBuilder(config.filename, "1.0", [])
         packages = [available_package]
         self.assertRaises(AssertionError, builder.find_fetched_package,

=== modified file 'linaro_image_tools/hwpack/tests/test_config.py'
--- linaro_image_tools/hwpack/tests/test_config.py	2011-06-29 14:25:49 +0000
+++ linaro_image_tools/hwpack/tests/test_config.py	2011-08-18 14:11:28 +0000
@@ -32,10 +32,12 @@
         "[hwpack]\nname = ahwpack\npackages = foo\narchitectures = armel\n")
     valid_start_v2 = valid_start + "format = 2.0\n"
     valid_complete_v2 = (valid_start_v2 +
-                         "u-boot-package = u-boot-linaro-s5pv310\n" \
-                             "u-boot-file = usr/lib/u-boot/smdkv310/" \
+                         "u_boot_package = u-boot-linaro-s5pv310\n" \
+                             "u_boot_file = usr/lib/u-boot/smdkv310/" \
                              "u-boot.bin\nserial_tty=ttySAC1\n" \
-                             "partition_layout = bootfs_rootfs\n")
+                             "partition_layout = bootfs_rootfs\n"\
+                             "x_loader_package = x-loader-omap4-panda\n"\
+                             "x_loader_file = usr/lib/x-loader/omap4430panda/MLO\n")
     valid_end = "[ubuntu]\nsources-entry = foo bar\n"
 
     def test_create(self):
@@ -186,39 +188,40 @@
 
     def test_validate_invalid_u_boot_package_name(self):
         config = self.get_config(
-                self.valid_start_v2 + "u-boot-package = ~~\n")
+                self.valid_start_v2 + "u_boot_package = ~~\n")
         self.assertValidationError(
-            "Invalid value in u-boot-package in the [hwpack] section: ~~",
+            "Invalid value in u_boot_package in the [hwpack] section: ~~",
             config)
 
-    def test_validate_empty_u_boot_package(self):
-        config = self.get_config(
-            self.valid_start_v2 + "u-boot-package = \n")
-        self.assertValidationError(
-            "No u-boot-package in the [hwpack] section", config)
-
-    def test_validate_no_u_boot_file(self):
-        config = self.get_config(self.valid_start_v2 + 
-                                 "u-boot-package = u-boot-linaro-s5pv310\n")
-        self.assertValidationError("No u_boot_file in the [hwpack] section",
-                                   config)
-
-    def test_validate_empty_u_boot_file(self):
-        config = self.get_config(self.valid_start_v2 + 
-                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
-                                     "u-boot-file = \n")
-        self.assertValidationError("No u_boot_file in the [hwpack] section", config)
-
     def test_validate_invalid_u_boot_file(self):
         config = self.get_config(self.valid_start_v2 + 
+                                 "u_boot_package = u-boot-linaro-s5pv310\n" \
+                                     "u_boot_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" \
+                "u-boot-file = usr/bin/version/MLO\n" \
+                "partition_layout = bootfs_rootfs\n"\
+                "x_loader_package = ~~\n")
+        self.assertValidationError(
+            "Invalid value in x_loader_package in the [hwpack] section: ~~",
+            config)
+
+    def test_validate_invalid_x_loader_file(self):
+        config = self.get_config(self.valid_start_v2 + 
                                  "u-boot-package = u-boot-linaro-s5pv310\n" \
-                                     "u-boot-file = ~~\n")
+                                     "u-boot-file = usr/bin/version/MLO\n" \
+                                     "partition_layout = bootfs_rootfs\n" \
+                                     "x_loader_package = x-loader--linaro-s5pv310\n" \
+                                     "x_loader_file = ~~\n")
         self.assertValidationError("Invalid path: ~~", config)
 
     def test_validate_partition_layout(self):
         partition_layout = 'apafs_bananfs'
-        config = self.get_config(self.valid_start_v2 + "u-boot-package = " \
-                                     "u-boot-linaro-s5pv310\nu-boot-file = " \
+        config = self.get_config(self.valid_start_v2 + "u_boot_package = " \
+                                     "u-boot-linaro-s5pv310\nu_boot_file = " \
                                      "u-boot.bin\npartition_layout = %s\n" % \
                                      partition_layout)
         self.assertValidationError(
@@ -235,12 +238,12 @@
 
     def test_validate_serial_tty(self):
         config = self.get_config(self.valid_start_v2 +
-                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
-                                     "u-boot-file = u-boot.bin\nserial_tty=tty\n")
+                                 "u_boot_package = u-boot-linaro-s5pv310\n" \
+                                     "u_boot_file = u-boot.bin\nserial_tty=tty\n")
         self.assertValidationError("Invalid serial tty: tty", config)
         config = self.get_config(self.valid_start_v2 +
-                                 "u-boot-package = u-boot-linaro-s5pv310\n" \
-                                     "u-boot-file = u-boot.bin\n" \
+                                 "u_boot_package = u-boot-linaro-s5pv310\n" \
+                                     "u_boot_file = u-boot.bin\n" \
                                      "serial_tty=ttxSAC1\n")
         self.assertValidationError("Invalid serial tty: ttxSAC1", config)
 
@@ -333,6 +336,24 @@
         self.assertEqual("usr/lib/u-boot/smdkv310/u-boot.bin",
                          config.u_boot_file)
 
+    def test_u_boot_package(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("u-boot-linaro-s5pv310",
+                         config.u_boot_package)
+
+    def test_x_loader_file(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("usr/lib/x-loader/omap4430panda/MLO",
+                         config.x_loader_file)
+
+    def test_x_loader_package(self):
+        config = self.get_config(self.valid_complete_v2 + self.valid_end)
+        config.validate()
+        self.assertEqual("x-loader-omap4-panda",
+                         config.x_loader_package)
+
     def test_serial_tty(self):
         config = self.get_config(self.valid_complete_v2 + self.valid_end)
         config.validate()

=== modified file 'linaro_image_tools/media_create/boards.py'
--- linaro_image_tools/media_create/boards.py	2011-08-23 08:34:24 +0000
+++ linaro_image_tools/media_create/boards.py	2011-08-24 14:04:45 +0000
@@ -276,9 +276,6 @@
                 cls.load_addr = None
                 cls.serial_tty = None
                 cls.fat_size = None
-                cls.BOOT_MIN_SIZE_S = None
-                cls.ROOT_MIN_SIZE_S = None
-                cls.LOADER_MIN_SIZE_S = None
 
             # Set new values from metadata.
             cls.kernel_addr = cls.get_metadata_field(
@@ -578,7 +575,7 @@
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
                          boot_device_or_file, k_img_data, i_img_data,
                          d_img_data):
-        install_omap_boot_loader(chroot_dir, boot_dir)
+        install_omap_boot_loader(chroot_dir, boot_dir, cls)
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
         make_dtb(d_img_data, boot_dir)
@@ -1294,11 +1291,16 @@
         raise AssertionError("No MLO files found on %s" % chroot_dir)
 
 
-def install_omap_boot_loader(chroot_dir, boot_disk):
-    mlo_file = _get_mlo_file(chroot_dir)
-    cmd_runner.run(["cp", "-v", mlo_file, boot_disk], as_root=True).wait()
-    # XXX: Is this really needed?
-    cmd_runner.run(["sync"]).wait()
+def install_omap_boot_loader(chroot_dir, boot_disk, cls):
+    with cls.hardwarepack_handler:
+        try:
+            default = _get_mlo_file(chroot_dir)
+        except AssertionError:
+            default = None
+        mlo_file = cls.get_file('x_loader', default=default)
+        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_path, boot_disk):

=== modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
--- linaro_image_tools/media_create/tests/test_media_create.py	2011-08-23 08:34:24 +0000
+++ linaro_image_tools/media_create/tests/test_media_create.py	2011-08-24 14:04:45 +0000
@@ -1458,7 +1458,10 @@
         self.useFixture(MockSomethingFixture(
             boards, '_get_mlo_file',
             lambda chroot_dir: "%s/MLO" % chroot_dir))
-        install_omap_boot_loader("chroot_dir", "boot_disk")
+        class config(BoardConfig):
+            pass
+        config.set_metadata([])
+        install_omap_boot_loader("chroot_dir", "boot_disk", config)
         expected = [
             '%s cp -v chroot_dir/MLO boot_disk' % sudo_args, 'sync']
         self.assertEqual(expected, fixture.mock.commands_executed)

