binman: Avoid needing the section size in advance
[oweals/u-boot.git] / tools / binman / ftest.py
index c0842c4386b72afd7d0cdc1a9630920464a52090..6b0ab7fdc2a830a91ef8697265a2f5c35bcce731 100644 (file)
@@ -23,6 +23,7 @@ import cmdline
 import command
 import control
 import elf
+import elf_test
 import fdt
 from etype import fdtmap
 from etype import image_header
@@ -39,7 +40,7 @@ import tout
 U_BOOT_DATA           = b'1234'
 U_BOOT_IMG_DATA       = b'img'
 U_BOOT_SPL_DATA       = b'56780123456789abcde'
-U_BOOT_TPL_DATA       = b'tpl'
+U_BOOT_TPL_DATA       = b'tpl9876543210fedcb'
 BLOB_DATA             = b'89'
 ME_DATA               = b'0abcd'
 VGA_DATA              = b'vga'
@@ -49,6 +50,9 @@ U_BOOT_TPL_DTB_DATA   = b'tpldtb'
 X86_START16_DATA      = b'start16'
 X86_START16_SPL_DATA  = b'start16spl'
 X86_START16_TPL_DATA  = b'start16tpl'
+X86_RESET16_DATA      = b'reset16'
+X86_RESET16_SPL_DATA  = b'reset16spl'
+X86_RESET16_TPL_DATA  = b'reset16tpl'
 PPC_MPC85XX_BR_DATA   = b'ppcmpc85xxbr'
 U_BOOT_NODTB_DATA     = b'nodtb with microcode pointer somewhere in here'
 U_BOOT_SPL_NODTB_DATA = b'splnodtb with microcode pointer somewhere in here'
@@ -94,16 +98,16 @@ class TestFunctional(unittest.TestCase):
     the test/ diurectory.
     """
     @classmethod
-    def setUpClass(self):
+    def setUpClass(cls):
         global entry
         import entry
 
         # Handle the case where argv[0] is 'python'
-        self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
-        self._binman_pathname = os.path.join(self._binman_dir, 'binman')
+        cls._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
+        cls._binman_pathname = os.path.join(cls._binman_dir, 'binman')
 
         # Create a temporary directory for input files
-        self._indir = tempfile.mkdtemp(prefix='binmant.')
+        cls._indir = tempfile.mkdtemp(prefix='binmant.')
 
         # Create some test files
         TestFunctional._MakeInputFile('u-boot.bin', U_BOOT_DATA)
@@ -113,13 +117,23 @@ class TestFunctional(unittest.TestCase):
         TestFunctional._MakeInputFile('blobfile', BLOB_DATA)
         TestFunctional._MakeInputFile('me.bin', ME_DATA)
         TestFunctional._MakeInputFile('vga.bin', VGA_DATA)
-        self._ResetDtbs()
-        TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA)
+        cls._ResetDtbs()
+
         TestFunctional._MakeInputFile('u-boot-br.bin', PPC_MPC85XX_BR_DATA)
-        TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin',
+
+        TestFunctional._MakeInputFile('u-boot-x86-start16.bin', X86_START16_DATA)
+        TestFunctional._MakeInputFile('spl/u-boot-x86-start16-spl.bin',
                                       X86_START16_SPL_DATA)
-        TestFunctional._MakeInputFile('tpl/u-boot-x86-16bit-tpl.bin',
+        TestFunctional._MakeInputFile('tpl/u-boot-x86-start16-tpl.bin',
                                       X86_START16_TPL_DATA)
+
+        TestFunctional._MakeInputFile('u-boot-x86-reset16.bin',
+                                      X86_RESET16_DATA)
+        TestFunctional._MakeInputFile('spl/u-boot-x86-reset16-spl.bin',
+                                      X86_RESET16_SPL_DATA)
+        TestFunctional._MakeInputFile('tpl/u-boot-x86-reset16-tpl.bin',
+                                      X86_RESET16_TPL_DATA)
+
         TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA)
         TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin',
                                       U_BOOT_SPL_NODTB_DATA)
@@ -134,36 +148,39 @@ class TestFunctional(unittest.TestCase):
         TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA)
         TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA)
 
+        cls._elf_testdir = os.path.join(cls._indir, 'elftest')
+        elf_test.BuildElfTestFiles(cls._elf_testdir)
+
         # ELF file with a '_dt_ucode_base_size' symbol
-        with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
-            TestFunctional._MakeInputFile('u-boot', fd.read())
+        TestFunctional._MakeInputFile('u-boot',
+            tools.ReadFile(cls.ElfTestFile('u_boot_ucode_ptr')))
 
         # Intel flash descriptor file
-        with open(self.TestFile('descriptor.bin'), 'rb') as fd:
+        with open(cls.TestFile('descriptor.bin'), 'rb') as fd:
             TestFunctional._MakeInputFile('descriptor.bin', fd.read())
 
-        shutil.copytree(self.TestFile('files'),
-                        os.path.join(self._indir, 'files'))
+        shutil.copytree(cls.TestFile('files'),
+                        os.path.join(cls._indir, 'files'))
 
         TestFunctional._MakeInputFile('compress', COMPRESS_DATA)
 
         # Travis-CI may have an old lz4
-        self.have_lz4 = True
+        cls.have_lz4 = True
         try:
             tools.Run('lz4', '--no-frame-crc', '-c',
-                      os.path.join(self._indir, 'u-boot.bin'))
+                      os.path.join(cls._indir, 'u-boot.bin'))
         except:
-            self.have_lz4 = False
+            cls.have_lz4 = False
 
     @classmethod
-    def tearDownClass(self):
+    def tearDownClass(cls):
         """Remove the temporary input directory and its contents"""
-        if self.preserve_indir:
-            print('Preserving input dir: %s' % self._indir)
+        if cls.preserve_indir:
+            print('Preserving input dir: %s' % cls._indir)
         else:
-            if self._indir:
-                shutil.rmtree(self._indir)
-        self._indir = None
+            if cls._indir:
+                shutil.rmtree(cls._indir)
+        cls._indir = None
 
     @classmethod
     def setup_test_args(cls, preserve_indir=False, preserve_outdirs=False,
@@ -226,7 +243,7 @@ class TestFunctional(unittest.TestCase):
         return tmpdir, updated_fname
 
     @classmethod
-    def _ResetDtbs(self):
+    def _ResetDtbs(cls):
         TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA)
         TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA)
         TestFunctional._MakeInputFile('tpl/u-boot-tpl.dtb', U_BOOT_TPL_DTB_DATA)
@@ -432,7 +449,7 @@ class TestFunctional(unittest.TestCase):
         return self._DoReadFileDtb(fname, use_real_dtb)[0]
 
     @classmethod
-    def _MakeInputFile(self, fname, contents):
+    def _MakeInputFile(cls, fname, contents):
         """Create a new test input file, creating directories as needed
 
         Args:
@@ -441,7 +458,7 @@ class TestFunctional(unittest.TestCase):
         Returns:
             Full pathname of file created
         """
-        pathname = os.path.join(self._indir, fname)
+        pathname = os.path.join(cls._indir, fname)
         dirname = os.path.dirname(pathname)
         if dirname and not os.path.exists(dirname):
             os.makedirs(dirname)
@@ -450,7 +467,7 @@ class TestFunctional(unittest.TestCase):
         return pathname
 
     @classmethod
-    def _MakeInputDir(self, dirname):
+    def _MakeInputDir(cls, dirname):
         """Create a new test input directory, creating directories as needed
 
         Args:
@@ -459,24 +476,38 @@ class TestFunctional(unittest.TestCase):
         Returns:
             Full pathname of directory created
         """
-        pathname = os.path.join(self._indir, dirname)
+        pathname = os.path.join(cls._indir, dirname)
         if not os.path.exists(pathname):
             os.makedirs(pathname)
         return pathname
 
     @classmethod
-    def _SetupSplElf(self, src_fname='bss_data'):
+    def _SetupSplElf(cls, src_fname='bss_data'):
         """Set up an ELF file with a '_dt_ucode_base_size' symbol
 
         Args:
             Filename of ELF file to use as SPL
         """
-        with open(self.TestFile(src_fname), 'rb') as fd:
-            TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read())
+        TestFunctional._MakeInputFile('spl/u-boot-spl',
+            tools.ReadFile(cls.ElfTestFile(src_fname)))
+
+    @classmethod
+    def _SetupTplElf(cls, src_fname='bss_data'):
+        """Set up an ELF file with a '_dt_ucode_base_size' symbol
+
+        Args:
+            Filename of ELF file to use as TPL
+        """
+        TestFunctional._MakeInputFile('tpl/u-boot-tpl',
+            tools.ReadFile(cls.ElfTestFile(src_fname)))
+
+    @classmethod
+    def TestFile(cls, fname):
+        return os.path.join(cls._binman_dir, 'test', fname)
 
     @classmethod
-    def TestFile(self, fname):
-        return os.path.join(self._binman_dir, 'test', fname)
+    def ElfTestFile(cls, fname):
+        return os.path.join(cls._elf_testdir, fname)
 
     def AssertInList(self, grep_list, target):
         """Assert that at least one of a list of things is in a target
@@ -875,7 +906,7 @@ class TestFunctional(unittest.TestCase):
         """Test that the end-at-4gb and skip-at-size property can't be used
         together"""
         with self.assertRaises(ValueError) as e:
-            self._DoTestFile('80_4gb_and_skip_at_start_together.dts')
+            self._DoTestFile('098_4gb_and_skip_at_start_together.dts')
         self.assertIn("Image '/binman': Provide either 'end-at-4gb' or "
                       "'skip-at-start'", str(e.exception))
 
@@ -890,7 +921,7 @@ class TestFunctional(unittest.TestCase):
     def testPackX86Rom(self):
         """Test that a basic x86 ROM can be created"""
         self._SetupSplElf()
-        data = self._DoReadFile('029_x86-rom.dts')
+        data = self._DoReadFile('029_x86_rom.dts')
         self.assertEqual(U_BOOT_DATA + tools.GetBytes(0, 7) + U_BOOT_SPL_DATA +
                          tools.GetBytes(0, 2), data)
 
@@ -898,21 +929,21 @@ class TestFunctional(unittest.TestCase):
         """Test that an invalid Intel descriptor entry is detected"""
         TestFunctional._MakeInputFile('descriptor.bin', b'')
         with self.assertRaises(ValueError) as e:
-            self._DoTestFile('031_x86-rom-me.dts')
+            self._DoTestFile('031_x86_rom_me.dts')
         self.assertIn("Node '/binman/intel-descriptor': Cannot find Intel Flash Descriptor (FD) signature",
                       str(e.exception))
 
     def testPackX86RomBadDesc(self):
         """Test that the Intel requires a descriptor entry"""
         with self.assertRaises(ValueError) as e:
-            self._DoTestFile('030_x86-rom-me-no-desc.dts')
+            self._DoTestFile('030_x86_rom_me_no_desc.dts')
         self.assertIn("Node '/binman/intel-me': No offset set with "
                       "offset-unset: should another entry provide this correct "
                       "offset?", str(e.exception))
 
     def testPackX86RomMe(self):
         """Test that an x86 ROM with an ME region can be created"""
-        data = self._DoReadFile('031_x86-rom-me.dts')
+        data = self._DoReadFile('031_x86_rom_me.dts')
         expected_desc = tools.ReadFile(self.TestFile('descriptor.bin'))
         if data[:0x1000] != expected_desc:
             self.fail('Expected descriptor binary at start of image')
@@ -920,18 +951,18 @@ class TestFunctional(unittest.TestCase):
 
     def testPackVga(self):
         """Test that an image with a VGA binary can be created"""
-        data = self._DoReadFile('032_intel-vga.dts')
+        data = self._DoReadFile('032_intel_vga.dts')
         self.assertEqual(VGA_DATA, data[:len(VGA_DATA)])
 
     def testPackStart16(self):
         """Test that an image with an x86 start16 region can be created"""
-        data = self._DoReadFile('033_x86-start16.dts')
+        data = self._DoReadFile('033_x86_start16.dts')
         self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)])
 
     def testPackPowerpcMpc85xxBootpgResetvec(self):
         """Test that an image with powerpc-mpc85xx-bootpg-resetvec can be
         created"""
-        data = self._DoReadFile('81_powerpc_mpc85xx_bootpg_resetvec.dts')
+        data = self._DoReadFile('150_powerpc_mpc85xx_bootpg_resetvec.dts')
         self.assertEqual(PPC_MPC85XX_BR_DATA, data[:len(PPC_MPC85XX_BR_DATA)])
 
     def _RunMicrocodeTest(self, dts_fname, nodtb_data, ucode_second=False):
@@ -1066,8 +1097,8 @@ class TestFunctional(unittest.TestCase):
         """Test that a U-Boot binary without the microcode symbol is detected"""
         # ELF file without a '_dt_ucode_base_size' symbol
         try:
-            with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
-                TestFunctional._MakeInputFile('u-boot', fd.read())
+            TestFunctional._MakeInputFile('u-boot',
+                tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr')))
 
             with self.assertRaises(ValueError) as e:
                 self._RunPackUbootSingleMicrocode()
@@ -1076,8 +1107,8 @@ class TestFunctional(unittest.TestCase):
 
         finally:
             # Put the original file back
-            with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
-                TestFunctional._MakeInputFile('u-boot', fd.read())
+            TestFunctional._MakeInputFile('u-boot',
+                tools.ReadFile(self.ElfTestFile('u_boot_ucode_ptr')))
 
     def testMicrocodeNotInImage(self):
         """Test that microcode must be placed within the image"""
@@ -1089,8 +1120,8 @@ class TestFunctional(unittest.TestCase):
 
     def testWithoutMicrocode(self):
         """Test that we can cope with an image without microcode (e.g. qemu)"""
-        with open(self.TestFile('u_boot_no_ucode_ptr'), 'rb') as fd:
-            TestFunctional._MakeInputFile('u-boot', fd.read())
+        TestFunctional._MakeInputFile('u-boot',
+            tools.ReadFile(self.ElfTestFile('u_boot_no_ucode_ptr')))
         data, dtb, _, _ = self._DoReadFileDtb('044_x86_optional_ucode.dts', True)
 
         # Now check the device tree has no microcode
@@ -1113,17 +1144,17 @@ class TestFunctional(unittest.TestCase):
 
     def testPackFsp(self):
         """Test that an image with a FSP binary can be created"""
-        data = self._DoReadFile('042_intel-fsp.dts')
+        data = self._DoReadFile('042_intel_fsp.dts')
         self.assertEqual(FSP_DATA, data[:len(FSP_DATA)])
 
     def testPackCmc(self):
         """Test that an image with a CMC binary can be created"""
-        data = self._DoReadFile('043_intel-cmc.dts')
+        data = self._DoReadFile('043_intel_cmc.dts')
         self.assertEqual(CMC_DATA, data[:len(CMC_DATA)])
 
     def testPackVbt(self):
         """Test that an image with a VBT binary can be created"""
-        data = self._DoReadFile('046_intel-vbt.dts')
+        data = self._DoReadFile('046_intel_vbt.dts')
         self.assertEqual(VBT_DATA, data[:len(VBT_DATA)])
 
     def testSplBssPad(self):
@@ -1144,7 +1175,7 @@ class TestFunctional(unittest.TestCase):
 
     def testPackStart16Spl(self):
         """Test that an image with an x86 start16 SPL region can be created"""
-        data = self._DoReadFile('048_x86-start16-spl.dts')
+        data = self._DoReadFile('048_x86_start16_spl.dts')
         self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)])
 
     def _PackUbootSplMicrocode(self, dts, ucode_second=False):
@@ -1198,14 +1229,14 @@ class TestFunctional(unittest.TestCase):
 
     def testSymbols(self):
         """Test binman can assign symbols embedded in U-Boot"""
-        elf_fname = self.TestFile('u_boot_binman_syms')
+        elf_fname = self.ElfTestFile('u_boot_binman_syms')
         syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
         addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start')
         self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr)
 
         self._SetupSplElf('u_boot_binman_syms')
         data = self._DoReadFile('053_symbols.dts')
-        sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20)
+        sym_values = struct.pack('<LQL', 0, 24, 20)
         expected = (sym_values + U_BOOT_SPL_DATA[16:] +
                     tools.GetBytes(0xff, 1) + U_BOOT_DATA + sym_values +
                     U_BOOT_SPL_DATA[16:])
@@ -1536,10 +1567,9 @@ class TestFunctional(unittest.TestCase):
                       "'other'", str(e.exception))
 
     def testTpl(self):
-        """Test that an image with TPL and ots device tree can be created"""
+        """Test that an image with TPL and its device tree can be created"""
         # ELF file with a '__bss_size' symbol
-        with open(self.TestFile('bss_data'), 'rb') as fd:
-            TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
+        self._SetupTplElf()
         data = self._DoReadFile('078_u_boot_tpl.dts')
         self.assertEqual(U_BOOT_TPL_DATA + U_BOOT_TPL_DTB_DATA, data)
 
@@ -1564,7 +1594,7 @@ class TestFunctional(unittest.TestCase):
 
     def testPackStart16Tpl(self):
         """Test that an image with an x86 start16 TPL region can be created"""
-        data = self._DoReadFile('081_x86-start16-tpl.dts')
+        data = self._DoReadFile('081_x86_start16_tpl.dts')
         self.assertEqual(X86_START16_TPL_DATA, data[:len(X86_START16_TPL_DATA)])
 
     def testSelectImage(self):
@@ -1793,8 +1823,7 @@ class TestFunctional(unittest.TestCase):
             u-boot-tpl.dtb with the microcode removed
             the microcode
         """
-        with open(self.TestFile('u_boot_ucode_ptr'), 'rb') as fd:
-            TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
+        self._SetupTplElf('u_boot_ucode_ptr')
         first, pos_and_size = self._RunMicrocodeTest('093_x86_tpl_ucode.dts',
                                                      U_BOOT_TPL_NODTB_DATA)
         self.assertEqual(b'tplnodtb with microc' + pos_and_size +
@@ -1848,16 +1877,15 @@ class TestFunctional(unittest.TestCase):
     def testElf(self):
         """Basic test of ELF entries"""
         self._SetupSplElf()
-        with open(self.TestFile('bss_data'), 'rb') as fd:
-            TestFunctional._MakeInputFile('tpl/u-boot-tpl', fd.read())
-        with open(self.TestFile('bss_data'), 'rb') as fd:
+        self._SetupTplElf()
+        with open(self.ElfTestFile('bss_data'), 'rb') as fd:
             TestFunctional._MakeInputFile('-boot', fd.read())
         data = self._DoReadFile('096_elf.dts')
 
     def testElfStrip(self):
         """Basic test of ELF entries"""
         self._SetupSplElf()
-        with open(self.TestFile('bss_data'), 'rb') as fd:
+        with open(self.ElfTestFile('bss_data'), 'rb') as fd:
             TestFunctional._MakeInputFile('-boot', fd.read())
         data = self._DoReadFile('097_elf_strip.dts')
 
@@ -2008,6 +2036,7 @@ class TestFunctional(unittest.TestCase):
             fname: Filename of input file to provide (fitimage.bin or ifwi.bin)
         """
         self._SetupSplElf()
+        self._SetupTplElf()
 
         # Intel Integrated Firmware Image (IFWI) file
         with gzip.open(self.TestFile('%s.gz' % fname), 'rb') as fd:
@@ -2031,25 +2060,25 @@ class TestFunctional(unittest.TestCase):
                           subpart='IBBP', entry_name='IBBL')
 
         tpl_data = tools.ReadFile(tpl_fname)
-        self.assertEqual(tpl_data[:len(U_BOOT_TPL_DATA)], U_BOOT_TPL_DATA)
+        self.assertEqual(U_BOOT_TPL_DATA, tpl_data[:len(U_BOOT_TPL_DATA)])
 
     def testPackX86RomIfwi(self):
         """Test that an x86 ROM with Integrated Firmware Image can be created"""
         self._SetupIfwi('fitimage.bin')
-        data = self._DoReadFile('111_x86-rom-ifwi.dts')
+        data = self._DoReadFile('111_x86_rom_ifwi.dts')
         self._CheckIfwi(data)
 
     def testPackX86RomIfwiNoDesc(self):
         """Test that an x86 ROM with IFWI can be created from an ifwi.bin file"""
         self._SetupIfwi('ifwi.bin')
-        data = self._DoReadFile('112_x86-rom-ifwi-nodesc.dts')
+        data = self._DoReadFile('112_x86_rom_ifwi_nodesc.dts')
         self._CheckIfwi(data)
 
     def testPackX86RomIfwiNoData(self):
         """Test that an x86 ROM with IFWI handles missing data"""
         self._SetupIfwi('ifwi.bin')
         with self.assertRaises(ValueError) as e:
-            data = self._DoReadFile('113_x86-rom-ifwi-nodata.dts')
+            data = self._DoReadFile('113_x86_rom_ifwi_nodata.dts')
         self.assertIn('Could not complete processing of contents',
                       str(e.exception))
 
@@ -2683,7 +2712,7 @@ class TestFunctional(unittest.TestCase):
         image_fname = tools.GetOutputFilename('image.bin')
         with self.assertRaises(ValueError) as e:
             control.ExtractEntries(image_fname, 'fname', None, [])
-        self.assertIn('Must specify an entry path to write with -o',
+        self.assertIn('Must specify an entry path to write with -f',
                       str(e.exception))
 
     def testExtractTooManyEntryPaths(self):
@@ -2693,7 +2722,7 @@ class TestFunctional(unittest.TestCase):
         image_fname = tools.GetOutputFilename('image.bin')
         with self.assertRaises(ValueError) as e:
             control.ExtractEntries(image_fname, 'fname', None, ['a', 'b'])
-        self.assertIn('Must specify exactly one entry path to write with -o',
+        self.assertIn('Must specify exactly one entry path to write with -f',
                       str(e.exception))
 
     def testPackAlignSection(self):
@@ -3047,6 +3076,257 @@ class TestFunctional(unittest.TestCase):
         data = control.ReadEntry(updated_fname, entry_name)
         self.assertEqual(expected, data)
 
+    def _SetupForReplace(self):
+        """Set up some files to use to replace entries
+
+        This generates an image, copies it to a new file, extracts all the files
+        in it and updates some of them
+
+        Returns:
+            List
+                Image filename
+                Output directory
+                Expected values for updated entries, each a string
+        """
+        data = self._DoReadFileRealDtb('143_replace_all.dts')
+
+        updated_fname = tools.GetOutputFilename('image-updated.bin')
+        tools.WriteFile(updated_fname, data)
+
+        outdir = os.path.join(self._indir, 'extract')
+        einfos = control.ExtractEntries(updated_fname, None, outdir, [])
+
+        expected1 = b'x' + U_BOOT_DATA + b'y'
+        u_boot_fname1 = os.path.join(outdir, 'u-boot')
+        tools.WriteFile(u_boot_fname1, expected1)
+
+        expected2 = b'a' + U_BOOT_DATA + b'b'
+        u_boot_fname2 = os.path.join(outdir, 'u-boot2')
+        tools.WriteFile(u_boot_fname2, expected2)
+
+        expected_text = b'not the same text'
+        text_fname = os.path.join(outdir, 'text')
+        tools.WriteFile(text_fname, expected_text)
+
+        dtb_fname = os.path.join(outdir, 'u-boot-dtb')
+        dtb = fdt.FdtScan(dtb_fname)
+        node = dtb.GetNode('/binman/text')
+        node.AddString('my-property', 'the value')
+        dtb.Sync(auto_resize=True)
+        dtb.Flush()
+
+        return updated_fname, outdir, expected1, expected2, expected_text
+
+    def _CheckReplaceMultiple(self, entry_paths):
+        """Handle replacing the contents of multiple entries
+
+        Args:
+            entry_paths: List of entry paths to replace
+
+        Returns:
+            List
+                Dict of entries in the image:
+                    key: Entry name
+                    Value: Entry object
+            Expected values for updated entries, each a string
+        """
+        updated_fname, outdir, expected1, expected2, expected_text = (
+            self._SetupForReplace())
+        control.ReplaceEntries(updated_fname, None, outdir, entry_paths)
+
+        image = Image.FromFile(updated_fname)
+        image.LoadData()
+        return image.GetEntries(), expected1, expected2, expected_text
+
+    def testReplaceAll(self):
+        """Test replacing the contents of all entries"""
+        entries, expected1, expected2, expected_text = (
+            self._CheckReplaceMultiple([]))
+        data = entries['u-boot'].data
+        self.assertEqual(expected1, data)
+
+        data = entries['u-boot2'].data
+        self.assertEqual(expected2, data)
+
+        data = entries['text'].data
+        self.assertEqual(expected_text, data)
+
+        # Check that the device tree is updated
+        data = entries['u-boot-dtb'].data
+        dtb = fdt.Fdt.FromData(data)
+        dtb.Scan()
+        node = dtb.GetNode('/binman/text')
+        self.assertEqual('the value', node.props['my-property'].value)
+
+    def testReplaceSome(self):
+        """Test replacing the contents of a few entries"""
+        entries, expected1, expected2, expected_text = (
+            self._CheckReplaceMultiple(['u-boot2', 'text']))
+
+        # This one should not change
+        data = entries['u-boot'].data
+        self.assertEqual(U_BOOT_DATA, data)
+
+        data = entries['u-boot2'].data
+        self.assertEqual(expected2, data)
+
+        data = entries['text'].data
+        self.assertEqual(expected_text, data)
+
+    def testReplaceCmd(self):
+        """Test replacing a file fron an image on the command line"""
+        self._DoReadFileRealDtb('143_replace_all.dts')
+
+        try:
+            tmpdir, updated_fname = self._SetupImageInTmpdir()
+
+            fname = os.path.join(tmpdir, 'update-u-boot.bin')
+            expected = b'x' * len(U_BOOT_DATA)
+            tools.WriteFile(fname, expected)
+
+            self._DoBinman('replace', '-i', updated_fname, 'u-boot', '-f', fname)
+            data = tools.ReadFile(updated_fname)
+            self.assertEqual(expected, data[:len(expected)])
+            map_fname = os.path.join(tmpdir, 'image-updated.map')
+            self.assertFalse(os.path.exists(map_fname))
+        finally:
+            shutil.rmtree(tmpdir)
+
+    def testReplaceCmdSome(self):
+        """Test replacing some files fron an image on the command line"""
+        updated_fname, outdir, expected1, expected2, expected_text = (
+            self._SetupForReplace())
+
+        self._DoBinman('replace', '-i', updated_fname, '-I', outdir,
+                       'u-boot2', 'text')
+
+        tools.PrepareOutputDir(None)
+        image = Image.FromFile(updated_fname)
+        image.LoadData()
+        entries = image.GetEntries()
+
+        # This one should not change
+        data = entries['u-boot'].data
+        self.assertEqual(U_BOOT_DATA, data)
+
+        data = entries['u-boot2'].data
+        self.assertEqual(expected2, data)
+
+        data = entries['text'].data
+        self.assertEqual(expected_text, data)
+
+    def testReplaceMissing(self):
+        """Test replacing entries where the file is missing"""
+        updated_fname, outdir, expected1, expected2, expected_text = (
+            self._SetupForReplace())
+
+        # Remove one of the files, to generate a warning
+        u_boot_fname1 = os.path.join(outdir, 'u-boot')
+        os.remove(u_boot_fname1)
+
+        with test_util.capture_sys_output() as (stdout, stderr):
+            control.ReplaceEntries(updated_fname, None, outdir, [])
+        self.assertIn("Skipping entry '/u-boot' from missing file",
+                      stdout.getvalue())
+
+    def testReplaceCmdMap(self):
+        """Test replacing a file fron an image on the command line"""
+        self._DoReadFileRealDtb('143_replace_all.dts')
+
+        try:
+            tmpdir, updated_fname = self._SetupImageInTmpdir()
+
+            fname = os.path.join(self._indir, 'update-u-boot.bin')
+            expected = b'x' * len(U_BOOT_DATA)
+            tools.WriteFile(fname, expected)
+
+            self._DoBinman('replace', '-i', updated_fname, 'u-boot',
+                           '-f', fname, '-m')
+            map_fname = os.path.join(tmpdir, 'image-updated.map')
+            self.assertTrue(os.path.exists(map_fname))
+        finally:
+            shutil.rmtree(tmpdir)
+
+    def testReplaceNoEntryPaths(self):
+        """Test replacing an entry without an entry path"""
+        self._DoReadFileRealDtb('143_replace_all.dts')
+        image_fname = tools.GetOutputFilename('image.bin')
+        with self.assertRaises(ValueError) as e:
+            control.ReplaceEntries(image_fname, 'fname', None, [])
+        self.assertIn('Must specify an entry path to read with -f',
+                      str(e.exception))
+
+    def testReplaceTooManyEntryPaths(self):
+        """Test extracting some entries"""
+        self._DoReadFileRealDtb('143_replace_all.dts')
+        image_fname = tools.GetOutputFilename('image.bin')
+        with self.assertRaises(ValueError) as e:
+            control.ReplaceEntries(image_fname, 'fname', None, ['a', 'b'])
+        self.assertIn('Must specify exactly one entry path to write with -f',
+                      str(e.exception))
+
+    def testPackReset16(self):
+        """Test that an image with an x86 reset16 region can be created"""
+        data = self._DoReadFile('144_x86_reset16.dts')
+        self.assertEqual(X86_RESET16_DATA, data[:len(X86_RESET16_DATA)])
+
+    def testPackReset16Spl(self):
+        """Test that an image with an x86 reset16-spl region can be created"""
+        data = self._DoReadFile('145_x86_reset16_spl.dts')
+        self.assertEqual(X86_RESET16_SPL_DATA, data[:len(X86_RESET16_SPL_DATA)])
+
+    def testPackReset16Tpl(self):
+        """Test that an image with an x86 reset16-tpl region can be created"""
+        data = self._DoReadFile('146_x86_reset16_tpl.dts')
+        self.assertEqual(X86_RESET16_TPL_DATA, data[:len(X86_RESET16_TPL_DATA)])
+
+    def testPackIntelFit(self):
+        """Test that an image with an Intel FIT and pointer can be created"""
+        data = self._DoReadFile('147_intel_fit.dts')
+        self.assertEqual(U_BOOT_DATA, data[:len(U_BOOT_DATA)])
+        fit = data[16:32];
+        self.assertEqual(b'_FIT_   \x01\x00\x00\x00\x00\x01\x80}' , fit)
+        ptr = struct.unpack('<i', data[0x40:0x44])[0]
+
+        image = control.images['image']
+        entries = image.GetEntries()
+        expected_ptr = entries['intel-fit'].image_pos - (1 << 32)
+        self.assertEqual(expected_ptr, ptr)
+
+    def testPackIntelFitMissing(self):
+        """Test detection of a FIT pointer with not FIT region"""
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFile('148_intel_fit_missing.dts')
+        self.assertIn("'intel-fit-ptr' section must have an 'intel-fit' sibling",
+                      str(e.exception))
+
+    def testSymbolsTplSection(self):
+        """Test binman can assign symbols embedded in U-Boot TPL in a section"""
+        self._SetupSplElf('u_boot_binman_syms')
+        self._SetupTplElf('u_boot_binman_syms')
+        data = self._DoReadFile('149_symbols_tpl.dts')
+        sym_values = struct.pack('<LQL', 4, 0x18, 0x30)
+        upto1 = 4 + len(U_BOOT_SPL_DATA)
+        expected1 = tools.GetBytes(0xff, 4) + sym_values + U_BOOT_SPL_DATA[16:]
+        self.assertEqual(expected1, data[:upto1])
+
+        upto2 = upto1 + 1 + len(U_BOOT_SPL_DATA)
+        expected2 = tools.GetBytes(0xff, 1) + sym_values + U_BOOT_SPL_DATA[16:]
+        self.assertEqual(expected2, data[upto1:upto2])
+
+        upto3 = 0x30 + len(U_BOOT_DATA)
+        expected3 = tools.GetBytes(0xff, 5) + U_BOOT_DATA
+        self.assertEqual(expected3, data[upto2:upto3])
+
+        expected4 = sym_values + U_BOOT_TPL_DATA[16:]
+        self.assertEqual(expected4, data[upto3:])
+
+    def testPackX86RomIfwiSectiom(self):
+        """Test that a section can be placed in an IFWI region"""
+        self._SetupIfwi('fitimage.bin')
+        data = self._DoReadFile('151_x86_rom_ifwi_section.dts')
+        self._CheckIfwi(data)
+
 
 if __name__ == "__main__":
     unittest.main()