diff mbox

[Branch,~linaro-maintainers/linaro-image-tools/trunk] Rev 319: Merge lp:~shawnguo/linaro-image-tools/add-dtb; adds support for device tree

Message ID 20110418212116.6011.31220.launchpad@loganberry.canonical.com
State Accepted
Headers show

Commit Message

Loïc Minier April 18, 2011, 9:21 p.m. UTC
Merge authors:
  Shawn Guo (shawnguo)
Related merge proposals:
  https://code.launchpad.net/~shawnguo/linaro-image-tools/add-dtb/+merge/57127
  proposed by: Shawn Guo (shawnguo)
  review: Approve - Loïc Minier (lool)
------------------------------------------------------------
revno: 319 [merge]
committer: Loïc Minier <lool@dooz.org>
branch nick: linaro-image-tools
timestamp: Mon 2011-04-18 23:18:06 +0200
message:
  Merge lp:~shawnguo/linaro-image-tools/add-dtb; adds support for device tree
  binaries.
modified:
  linaro_image_tools/media_create/boards.py
  linaro_image_tools/media_create/tests/test_media_create.py


--
lp:linaro-image-tools
https://code.launchpad.net/~linaro-maintainers/linaro-image-tools/trunk

You are subscribed to branch lp:linaro-image-tools.
To unsubscribe from this branch go to https://code.launchpad.net/~linaro-maintainers/linaro-image-tools/trunk/+edit-subscription
diff mbox

Patch

=== modified file 'linaro_image_tools/media_create/boards.py'
--- linaro_image_tools/media_create/boards.py	2011-04-11 10:43:43 +0000
+++ linaro_image_tools/media_create/boards.py	2011-04-18 21:18:06 +0000
@@ -38,6 +38,7 @@ 
 
 KERNEL_GLOB = 'vmlinuz-*-%(kernel_flavor)s'
 INITRD_GLOB = 'initrd.img-*-%(kernel_flavor)s'
+DTB_GLOB = 'dt-*-%(kernel_flavor)s/%(dtb_name)s'
 
 # Notes:
 # * since we align partitions on 4 MiB by default, geometry is currently 128
@@ -153,6 +154,8 @@ 
     kernel_addr = None
     initrd_addr = None
     load_addr = None
+    dtb_addr = None
+    dtb_name = None
     kernel_flavors = None
     boot_script = None
     serial_tty = None
@@ -246,20 +249,28 @@ 
             system_start, _system_len, cache_start, cache_start, _cache_len,
             userdata_start, _userdata_len, sdcard_start)
 
-    @classproperty
-    def bootcmd(cls):
+    @classmethod
+    def _get_bootcmd(cls, d_img_data):
         """Get the bootcmd for this board.
 
         In general subclasses should not have to override this.
         """
         replacements = dict(
             mmc_option=cls.mmc_option, kernel_addr=cls.kernel_addr,
-            initrd_addr=cls.initrd_addr)
-        return (
-            "fatload mmc %(mmc_option)s %(kernel_addr)s "
-                "uImage; fatload mmc %(mmc_option)s %(initrd_addr)s uInitrd; "
-                "bootm %(kernel_addr)s %(initrd_addr)s"
+            initrd_addr=cls.initrd_addr, dtb_addr=cls.dtb_addr)
+        boot_script = (
+            "fatload mmc %(mmc_option)s %(kernel_addr)s uImage; "
+            "fatload mmc %(mmc_option)s %(initrd_addr)s uInitrd; "
+            % replacements)
+        if d_img_data is not None:
+            boot_script += (
+                "fatload mmc %(mmc_option)s %(dtb_addr)s board.dtb; "
+                "bootm %(kernel_addr)s %(initrd_addr)s %(dtb_addr)s"
                 % replacements)
+        else:
+            boot_script += (
+                "bootm %(kernel_addr)s %(initrd_addr)s" % replacements)
+        return boot_script
 
     @classmethod
     def _get_bootargs(cls, is_live, is_lowmem, consoles, rootfs_uuid):
@@ -292,7 +303,8 @@ 
              % replacements)
 
     @classmethod
-    def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid):
+    def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid,
+                      d_img_data):
         """Get the boot environment for this board.
 
         In general subclasses should not have to override this.
@@ -300,21 +312,24 @@ 
         boot_env = {}
         boot_env["bootargs"] = cls._get_bootargs(
             is_live, is_lowmem, consoles, rootfs_uuid)
-        boot_env["bootcmd"] = cls.bootcmd
+        boot_env["bootcmd"] = cls._get_bootcmd(d_img_data)
         return boot_env
 
     @classmethod
     def make_boot_files(cls, uboot_parts_dir, is_live, is_lowmem, consoles,
                         chroot_dir, rootfs_uuid, boot_dir, boot_device_or_file):
-        boot_env = cls._get_boot_env(is_live, is_lowmem, consoles, rootfs_uuid)
-        (k_img_data, i_img_data) = cls._get_kflavor_files(uboot_parts_dir)
+        (k_img_data, i_img_data, d_img_data) = cls._get_kflavor_files(
+                                                   uboot_parts_dir)
+        boot_env = cls._get_boot_env(is_live, is_lowmem, consoles, rootfs_uuid,
+                                     d_img_data)
         cls._make_boot_files(
             boot_env, chroot_dir, boot_dir, 
-            boot_device_or_file, k_img_data, i_img_data)
+            boot_device_or_file, k_img_data, i_img_data, d_img_data)
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         """Make the necessary boot files for this board.
 
         This is usually board-specific so ought to be defined in every
@@ -354,15 +369,20 @@ 
 
     @classmethod
     def _get_kflavor_files(cls, path):
-        """Search for kernel and initrd in path."""
+        """Search for kernel, initrd and optional dtb in path."""
         for flavor in cls.kernel_flavors:
             kregex = KERNEL_GLOB % {'kernel_flavor' : flavor}
             iregex = INITRD_GLOB % {'kernel_flavor' : flavor}
+            dregex = DTB_GLOB % {'kernel_flavor' : flavor,
+                                 'dtb_name' : cls.dtb_name}
             kernel = _get_file_matching(os.path.join(path, kregex))
             if kernel is not None:
                 initrd = _get_file_matching(os.path.join(path, iregex))
                 if initrd is not None:
-                    return (kernel, initrd)
+                    dtb = None
+                    if cls.dtb_name is not None:
+                        dtb = _get_file_matching(os.path.join(path, dregex))
+                    return (kernel, initrd, dtb)
                 raise ValueError(
                     "Found kernel for flavor %s but no initrd matching %s" % (
                         flavor, iregex))
@@ -428,10 +448,12 @@ 
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         install_omap_boot_loader(chroot_dir, boot_dir)
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
+        make_dtb(d_img_data, boot_dir)
         boot_script_path = os.path.join(boot_dir, cls.boot_script)
         make_boot_script(boot_env, boot_script_path)
         make_boot_ini(boot_script_path, boot_dir)
@@ -439,10 +461,12 @@ 
 
 class BeagleConfig(OmapConfig):
     uboot_flavor = 'omap3_beagle'
+    dtb_name = 'omap3-beagle.dtb'
     _serial_tty = 'ttyO2'
     _extra_serial_opts = 'console=tty0 console=%s,115200n8'
     _live_serial_opts = 'serialtty=%s'
     kernel_addr = '0x80000000'
+    dtb_addr = '0x815f0000'
     initrd_addr = '0x81600000'
     load_addr = '0x80008000'
     boot_script = 'boot.scr'
@@ -453,9 +477,11 @@ 
 
 class OveroConfig(OmapConfig):
     uboot_flavor = 'omap3_overo'
+    dtb_name = 'omap3-overo.dtb'
     _serial_tty = 'ttyO2'
     _extra_serial_opts = 'console=tty0 console=%s,115200n8'
     kernel_addr = '0x80000000'
+    dtb_addr = '0x815f0000'
     initrd_addr = '0x81600000'
     load_addr = '0x80008000'
     boot_script = 'boot.scr'
@@ -466,10 +492,12 @@ 
 
 class PandaConfig(OmapConfig):
     uboot_flavor = 'omap4_panda'
+    dtb_name = 'omap4-panda.dtb'
     _serial_tty = 'ttyO2'
     _extra_serial_opts = 'console=tty0 console=%s,115200n8'
     _live_serial_opts = 'serialtty=%s'
     kernel_addr = '0x80200000'
+    dtb_addr = '0x815f0000'
     initrd_addr = '0x81600000'
     load_addr = '0x80008000'
     boot_script = 'boot.scr'
@@ -481,12 +509,15 @@ 
 class IgepConfig(BeagleConfig):
     uboot_in_boot_part = False
     uboot_flavor = None
+    dtb_name = 'isee-igep-v2.dtb'
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
+        make_dtb(d_img_data, boot_dir)
         boot_script_path = os.path.join(boot_dir, cls.boot_script)
         make_boot_script(boot_env, boot_script_path)
         make_boot_ini(boot_script_path, boot_dir)
@@ -510,7 +541,8 @@ 
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
         boot_script_path = os.path.join(boot_dir, cls.boot_script)
@@ -555,44 +587,52 @@ 
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         uboot_file = os.path.join(
             chroot_dir, 'usr', 'lib', 'u-boot', cls.uboot_flavor, 'u-boot.imx')
         install_mx5_boot_loader(uboot_file, boot_device_or_file)
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
+        make_dtb(d_img_data, boot_dir)
         boot_script_path = os.path.join(boot_dir, cls.boot_script)
         make_boot_script(boot_env, boot_script_path)
 
 
 class Mx51Config(Mx5Config):
     kernel_addr = '0x90000000'
+    dtb_addr = '0x91ff0000'
     initrd_addr = '0x92000000'
     load_addr = '0x90008000'
     kernel_flavors = ['linaro-mx51', 'linaro-lt-mx5']
 
 
 class Mx53Config(Mx5Config):
-    kernel_addr = '0x70800000'
-    initrd_addr = '0x71800000'
+    kernel_addr = '0x70000000'
+    dtb_addr = '0x71ff0000'
+    initrd_addr = '0x72000000'
     load_addr = '0x70008000'
     kernel_flavors = ['linaro-lt-mx53', 'linaro-lt-mx5']
 
 
 class EfikamxConfig(Mx51Config):
     uboot_flavor = 'efikamx'
+    dtb_name = 'genesi-efikamx.dtb'
 
 
 class EfikasbConfig(Mx51Config):
     uboot_flavor = 'efikasb'
+    dtb_name = 'genesi-efikasb.dtb'
 
 
 class Mx51evkConfig(Mx51Config):
     uboot_flavor = 'mx51evk'
+    dtb_name = 'mx51-babbage.dtb'
 
 
 class Mx53LoCoConfig(Mx53Config):
     uboot_flavor = 'mx53loco'
+    dtb_name = 'mx53-loco.dtb'
 
 
 class VexpressConfig(BoardConfig):
@@ -612,7 +652,8 @@ 
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         make_uImage(cls.load_addr, k_img_data, boot_dir)
         make_uInitrd(i_img_data, boot_dir)
 
@@ -654,9 +695,10 @@ 
             loader_start, loader_len, boot_start, boot_len, root_start)
 
     @classmethod
-    def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid):
+    def _get_boot_env(cls, is_live, is_lowmem, consoles, rootfs_uuid,
+                      d_img_data):
         boot_env = super(SMDKV310Config, cls)._get_boot_env(
-            is_live, is_lowmem, consoles, rootfs_uuid)
+            is_live, is_lowmem, consoles, rootfs_uuid, d_img_data)
 
         boot_env["ethact"] = "smc911x-0"
         boot_env["ethaddr"] = "00:40:5c:26:0a:5b"
@@ -673,7 +715,8 @@ 
 
     @classmethod
     def _make_boot_files(cls, boot_env, chroot_dir, boot_dir,
-                         boot_device_or_file, k_img_data, i_img_data):
+                         boot_device_or_file, k_img_data, i_img_data,
+                         d_img_data):
         uboot_file = os.path.join(
             chroot_dir, 'usr', 'lib', 'u-boot', 'smdkv310', 'u-boot.v310')
         install_smdkv310_boot_loader(uboot_file, boot_device_or_file)
@@ -775,6 +818,14 @@ 
     return img
 
 
+def make_dtb(img_data, boot_disk):
+    img = None
+    if img_data is not None:
+        img = '%s/board.dtb' % boot_disk
+        cmd_runner.run(['cp', img_data, img], as_root=True).wait()
+    return img
+
+
 def make_boot_script(boot_env, boot_script_path):
     boot_script_data = (
         "setenv bootcmd '%(bootcmd)s'\n"

=== modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
--- linaro_image_tools/media_create/tests/test_media_create.py	2011-04-11 10:43:43 +0000
+++ linaro_image_tools/media_create/tests/test_media_create.py	2011-04-18 21:18:06 +0000
@@ -50,6 +50,7 @@ 
     make_boot_script,
     make_uImage,
     make_uInitrd,
+    make_dtb,
     _get_file_matching,
     _get_mlo_file,
     _run_mkimage,
@@ -176,7 +177,7 @@ 
 
     def make_boot_files(self, config):
         def _get_kflavor_files_mock(cls, path):
-            return (path, path)
+            return (path, path, path)
 
         self.useFixture(MockSomethingFixture(
             config, '_get_kflavor_files',
@@ -195,7 +196,7 @@ 
         self.make_boot_files(SomeMx5Config)
         expected = [
             'install_mx5_boot_loader', 'make_uImage', 'make_uInitrd',
-            'make_boot_script']
+            'make_dtb', 'make_boot_script']
         self.assertEqual(expected, self.funcs_calls)
 
     def test_smdkv310_steps(self):
@@ -217,7 +218,7 @@ 
         self.make_boot_files(boards.PandaConfig)
         expected = [
             'install_omap_boot_loader', 'make_uImage', 'make_uInitrd',
-            'make_boot_script', 'make_boot_ini']
+            'make_dtb', 'make_boot_script', 'make_boot_ini']
         self.assertEqual(expected, self.funcs_calls)
 
     def test_beagle_steps(self):
@@ -225,14 +226,14 @@ 
         self.make_boot_files(boards.BeagleConfig)
         expected = [
             'install_omap_boot_loader', 'make_uImage', 'make_uInitrd',
-            'make_boot_script', 'make_boot_ini']
+            'make_dtb', 'make_boot_script', 'make_boot_ini']
         self.assertEqual(expected, self.funcs_calls)
 
     def test_igep_steps(self):
         self.mock_set_appropriate_serial_tty(boards.IgepConfig)
         self.make_boot_files(boards.IgepConfig)
         expected = [
-            'make_uImage', 'make_uInitrd', 'make_boot_script',
+            'make_uImage', 'make_uInitrd', 'make_dtb', 'make_boot_script',
             'make_boot_ini']
         self.assertEqual(expected, self.funcs_calls)
 
@@ -241,7 +242,7 @@ 
         self.make_boot_files(boards.OveroConfig)
         expected = [
             'install_omap_boot_loader', 'make_uImage', 'make_uInitrd',
-            'make_boot_script', 'make_boot_ini']
+            'make_dtb', 'make_boot_script', 'make_boot_ini']
         self.assertEqual(expected, self.funcs_calls)
 
 
@@ -340,7 +341,7 @@ 
     def test_vexpress(self):
         boot_commands = board_configs['vexpress']._get_boot_env(
             is_live=False, is_lowmem=False, consoles=['ttyXXX'],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data=None)
         expected = {
             'bootargs': 'console=tty0 console=ttyAMA0,38400n8 '
                         'console=ttyXXX  root=UUID=deadbeef rootwait ro',
@@ -352,19 +353,20 @@ 
     def test_mx51(self):
         boot_commands = boards.Mx51Config._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="mx51.dtb")
         expected = {
             'bootargs': 'console=tty0 console=ttymxc0,115200n8  '
                         'root=UUID=deadbeef rootwait ro',
             'bootcmd': 'fatload mmc 0:2 0x90000000 uImage; '
                        'fatload mmc 0:2 0x92000000 uInitrd; '
-                       'bootm 0x90000000 0x92000000'}
+                       'fatload mmc 0:2 0x91ff0000 board.dtb; '
+                       'bootm 0x90000000 0x92000000 0x91ff0000'}
         self.assertEqual(expected, boot_commands)
 
     def test_smdkv310(self):
         boot_commands = board_configs['smdkv310']._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="smdkv310.dtb")
         expected = {
             'bootargs': 'console=ttySAC1,115200n8  root=UUID=deadbeef '
                         'rootwait ro',
@@ -378,7 +380,7 @@ 
     def test_ux500(self):
         boot_commands = board_configs['ux500']._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data=None)
         expected = {
             'bootargs': 'console=tty0 console=ttyAMA2,115200n8  '
                         'root=UUID=deadbeef rootwait ro earlyprintk '
@@ -399,7 +401,7 @@ 
         config.serial_tty = config._serial_tty
         boot_commands = config._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="panda.dtb")
         expected = {
             'bootargs': 'console=tty0 console=ttyO2,115200n8  '
                         'root=UUID=deadbeef rootwait ro earlyprintk fixrtc '
@@ -407,7 +409,8 @@ 
                         'mem=456M@0x80000000 mem=512M@0xA0000000',
             'bootcmd': 'fatload mmc 0:1 0x80200000 uImage; '
                        'fatload mmc 0:1 0x81600000 uInitrd; '
-                       'bootm 0x80200000 0x81600000'}
+                       'fatload mmc 0:1 0x815f0000 board.dtb; '
+                       'bootm 0x80200000 0x81600000 0x815f0000'}
         self.assertEqual(expected, boot_commands)
 
     def test_beagle(self):
@@ -418,7 +421,7 @@ 
         config.serial_tty = config._serial_tty
         boot_commands = config._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="beagle.dtb")
         expected = {
             'bootargs': 'console=tty0 console=ttyO2,115200n8  '
                         'root=UUID=deadbeef rootwait ro earlyprintk fixrtc '
@@ -426,18 +429,19 @@ 
                         'omapfb.mode=dvi:1280x720MR-16@60',
             'bootcmd': 'fatload mmc 0:1 0x80000000 uImage; '
                        'fatload mmc 0:1 0x81600000 uInitrd; '
-                       'bootm 0x80000000 0x81600000'}
+                       'fatload mmc 0:1 0x815f0000 board.dtb; '
+                       'bootm 0x80000000 0x81600000 0x815f0000'}
         self.assertEqual(expected, boot_commands)
 
     def test_igep(self):
         # XXX: To fix bug 697824 we have to change class attributes of our
         # OMAP board configs, and some tests do that so to make sure they
         # don't interfere with us we'll reset that before doing anything.
-        config = board_configs['igep']
+        config = boards.IgepConfig
         config.serial_tty = config._serial_tty
         boot_cmd = config._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="igep.dtb")
         expected = {
             'bootargs': 'console=tty0 console=ttyO2,115200n8  '
                         'root=UUID=deadbeef rootwait ro earlyprintk fixrtc '
@@ -445,7 +449,8 @@ 
                         'omapfb.mode=dvi:1280x720MR-16@60',
             'bootcmd': 'fatload mmc 0:1 0x80000000 uImage; '
                        'fatload mmc 0:1 0x81600000 uInitrd; '
-                       'bootm 0x80000000 0x81600000'}
+                       'fatload mmc 0:1 0x815f0000 board.dtb; '
+                       'bootm 0x80000000 0x81600000 0x815f0000'}
         self.assertEqual(expected, boot_cmd)
 
     def test_overo(self):
@@ -456,7 +461,7 @@ 
         config.serial_tty = config._serial_tty
         boot_commands = config._get_boot_env(
             is_live=False, is_lowmem=False, consoles=[],
-            rootfs_uuid="deadbeef")
+            rootfs_uuid="deadbeef", d_img_data="overo.dtb")
         expected = {
             'bootargs': 'console=tty0 console=ttyO2,115200n8  '
                         'root=UUID=deadbeef rootwait ro earlyprintk '
@@ -465,7 +470,8 @@ 
                         'omapdss.def_disp=dvi',
             'bootcmd': 'fatload mmc 0:1 0x80000000 uImage; '
                        'fatload mmc 0:1 0x81600000 uInitrd; '
-                       'bootm 0x80000000 0x81600000'}
+                       'fatload mmc 0:1 0x815f0000 board.dtb; '
+                       'bootm 0x80000000 0x81600000 0x815f0000'}
         self.assertEqual(expected, boot_commands)
 
 
@@ -542,6 +548,15 @@ 
             'boot_disk/uInitrd' % sudo_args]
         self.assertEqual(expected, fixture.mock.commands_executed)
 
+    def test_make_dtb(self):
+        self._mock_get_file_matching()
+        fixture = self._mock_Popen()
+        make_dtb('parts_dir/dt-*-sub_arch/board_name.dtb', 'boot_disk')
+        expected = [
+            '%s cp parts_dir/dt-*-sub_arch/board_name.dtb '
+            'boot_disk/board.dtb' % sudo_args]
+        self.assertEqual(expected, fixture.mock.commands_executed)
+
     def test_make_flashable_env_too_small_env(self):
         env = {'verylong': 'evenlonger'}
         self.assertRaises(AssertionError, make_flashable_env, env, 8)
@@ -627,7 +642,27 @@ 
             ifile = os.path.join(tempdir, 'initrd.img-1-%s' % f)
             open(kfile, "w").close()
             open(ifile, "w").close()
-        self.assertEqual((kfile, ifile), config._get_kflavor_files(tempdir))
+        self.assertEqual(
+            (kfile, ifile, None), config._get_kflavor_files(tempdir))
+
+    def test_get_dt_kflavor_files_more_specific(self):
+        tempdir = self.useFixture(CreateTempDirFixture()).tempdir
+        flavorx = 'flavorX'
+        flavorxy = 'flavorXY'
+        class config(boards.BoardConfig):
+            kernel_flavors = [flavorx, flavorxy]
+            dtb_name = 'board_name.dtb'
+        for f in reversed(config.kernel_flavors):
+            kfile = os.path.join(tempdir, 'vmlinuz-1-%s' % f)
+            ifile = os.path.join(tempdir, 'initrd.img-1-%s' % f)
+            dt = os.path.join(tempdir, 'dt-1-%s' % f)
+            os.mkdir(dt)
+            dfile = os.path.join(dt, config.dtb_name)
+            open(kfile, "w").close()
+            open(ifile, "w").close()
+            open(dfile, "w").close()
+        self.assertEqual(
+            (kfile, ifile, dfile), config._get_kflavor_files(tempdir))
 
     def test_get_kflavor_files_later_in_flavors(self):
         tempdir = self.useFixture(CreateTempDirFixture()).tempdir
@@ -639,7 +674,26 @@ 
         ifile = os.path.join(tempdir, 'initrd.img-1-%s' % flavor1)
         open(kfile, "w").close()
         open(ifile, "w").close()
-        self.assertEqual((kfile, ifile), config._get_kflavor_files(tempdir))
+        self.assertEqual(
+            (kfile, ifile, None), config._get_kflavor_files(tempdir))
+
+    def test_get_dt_kflavor_files_later_in_flavors(self):
+        tempdir = self.useFixture(CreateTempDirFixture()).tempdir
+        flavor1 = 'flavorXY'
+        flavor2 = 'flavorAA'
+        class config(boards.BoardConfig):
+            kernel_flavors = [flavor1, flavor2]
+            dtb_name = 'board_name.dtb'
+        kfile = os.path.join(tempdir, 'vmlinuz-1-%s' % flavor1)
+        ifile = os.path.join(tempdir, 'initrd.img-1-%s' % flavor1)
+        dt = os.path.join(tempdir, 'dt-1-%s' % flavor1)
+        os.mkdir(dt)
+        dfile = os.path.join(dt, config.dtb_name)
+        open(kfile, "w").close()
+        open(ifile, "w").close()
+        open(dfile, "w").close()
+        self.assertEqual(
+            (kfile, ifile, dfile), config._get_kflavor_files(tempdir))
 
     def test_get_kflavor_files_raises_when_no_match(self):
         tempdir = self.useFixture(CreateTempDirFixture()).tempdir