From patchwork Wed Jun 6 00:47:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 925693 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="ahLk1PsH"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 410r4z5LdRz9s02 for ; Wed, 6 Jun 2018 11:02:59 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 67AD5C21EBA; Wed, 6 Jun 2018 00:56:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id BEF92C21F2A; Wed, 6 Jun 2018 00:51:46 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 26491C21F27; Wed, 6 Jun 2018 00:48:33 +0000 (UTC) Received: from mail-it0-f68.google.com (mail-it0-f68.google.com [209.85.214.68]) by lists.denx.de (Postfix) with ESMTPS id 38994C21F52 for ; Wed, 6 Jun 2018 00:48:28 +0000 (UTC) Received: by mail-it0-f68.google.com with SMTP id u4-v6so5931061itg.0 for ; Tue, 05 Jun 2018 17:48:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=9Ng9azKyqh4Ma8o7xtXL2WZ7HBqzwz5izZtPmEfECWc=; b=ahLk1PsHApQfegr6tQRQdny3LTIwNzn40pCHyp7EWbeP7YFfrkS0qp6rZfUzJuQaUG DLnhQkJQtEFqNsDnSVQ4w3t0jNsT2nz2k3DDwDy6OVQMCyoTR+0+SYCBPrhl9uyp4KDU 1PoRMXxPXoSlB/EwDfh+6dApAQm7Lqv3aNlQ5qa5wU5jIS63ljH1wzBV67pIs/6LQmvO C5i8UUrYCQJeUPIomAruGT34iQI09sBfFAdxOmnL7dIqKbdUOcaswLxH40Gcb4jyhh7s zMM9FxD1NgraJhJTf4UWoigc2uYQukjvwHyOkDO/cIU0IIQUDHinNPRlgMXdBVeH21/A Pgfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=9Ng9azKyqh4Ma8o7xtXL2WZ7HBqzwz5izZtPmEfECWc=; b=qE2n0Y2oybT9++Xa1Eb8f+hC9YSPiw3hUIp1Fa/iPa9nNYAos936PcSmsZJM8+CTAJ LkBRNheIjLe4aL2q3mcA9aQGuxo099/1nDTKoFfdv8zAaAvVKrW+4EmYbF0VT/wvHtt5 yBuE6H6NlThMCPWXL5WdwwAhrfRMO2keFrPIHTrPJXtD1rrV7Zr/RjWmBNpdLRDSydVh mdEklIpyZ3/FUeSTM6q2qQZL69LP84+VRVKNVH3ypTeMnJdLsOAWs8Myz5ivsIl/WgIY gdXezOhWCbK3nafUF3tt4GgypGAQskJbeVJrrKfbH7efoNYWwxJILHqZsSZDNpu9v4zm H90w== X-Gm-Message-State: APt69E1Zuc5rle/FkiVkoUQ80sAONYA5lHcDR0kivcQyDgByTXuBUybU dT1lww/5YUdVBlgYp8KUyGZBJw== X-Google-Smtp-Source: ADUXVKIBBU59NkDP8OWRSYmy39mFOe47XAFwNU0COAG7kDfzs4ZN5wr5MEpIKGnlSMw16U2urx0xdQ== X-Received: by 2002:a24:b914:: with SMTP id w20-v6mr496207ite.35.1528246106622; Tue, 05 Jun 2018 17:48:26 -0700 (PDT) Received: from kiwi.bld.corp.google.com ([2620:15c:183:0:8223:87c:a681:66aa]) by smtp.gmail.com with ESMTPSA id y33-v6sm1321420ita.24.2018.06.05.17.48.25 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 05 Jun 2018 17:48:25 -0700 (PDT) Received: by kiwi.bld.corp.google.com (Postfix, from userid 121222) id 99689140700; Tue, 5 Jun 2018 18:48:25 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Tue, 5 Jun 2018 18:47:05 -0600 Message-Id: <20180606004705.79641-30-sjg@chromium.org> X-Mailer: git-send-email 2.17.1.1185.g55be947832-goog In-Reply-To: <20180606004705.79641-1-sjg@chromium.org> References: <20180606004705.79641-1-sjg@chromium.org> Cc: Tom Rini Subject: [U-Boot] [PATCH 29/29] binman: Support updating the device tree with calc'd info X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" It is useful to write the position and size of each entry back to the device tree so that U-Boot can access this at runtime. Add a feature to support this, along with associated tests. Signed-off-by: Simon Glass --- tools/binman/README | 6 +-- tools/binman/control.py | 2 + tools/binman/ftest.py | 69 ++++++++++++++++++++++++----- tools/binman/test/60_fdt_update.dts | 28 ++++++++++++ 4 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 tools/binman/test/60_fdt_update.dts diff --git a/tools/binman/README b/tools/binman/README index 8b598a75c80..207928aa955 100644 --- a/tools/binman/README +++ b/tools/binman/README @@ -669,13 +669,11 @@ To do ----- Some ideas: -- Fill out the device tree to include the final position and size of each - entry (since the input file may not always specify these). See also - 'Access to binman entry positions at run time' above - Use of-platdata to make the information available to code that is unable to use device tree (such as a very small SPL image) - Allow easy building of images by specifying just the board name -- Produce a full Python binding for libfdt (for upstream) +- Produce a full Python binding for libfdt (for upstream). This is nearing + completion but some work remains - Add an option to decode an image into the constituent binaries - Support building an image for a board (-b) more completely, with a configurable build directory diff --git a/tools/binman/control.py b/tools/binman/control.py index eafabf05c7c..a40b300fdac 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -168,6 +168,8 @@ def Binman(options, args): image.BuildImage() if options.map: image.WriteMap() + with open(fname, 'wb') as outfd: + outfd.write(dtb.GetContents()) finally: tools.FinaliseOutputDir() finally: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index af3b4dc3e56..b49b1b9b734 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -146,19 +146,23 @@ class TestFunctional(unittest.TestCase): # options.verbosity = tout.DEBUG return control.Binman(options, args) - def _DoTestFile(self, fname, debug=False, map=False): + def _DoTestFile(self, fname, debug=False, map=False, update_dtb=False): """Run binman with a given test file Args: fname: Device-tree source filename to use (e.g. 05_simple.dts) debug: True to enable debugging output map: True to output map files for the images + update_dtb: Update the position and size of each entry in the device + tree before packing it into the image """ args = ['-p', '-I', self._indir, '-d', self.TestFile(fname)] if debug: args.append('-D') if map: args.append('-m') + if update_dtb: + args.append('-up') return self._DoBinman(*args) def _SetupDtb(self, fname, outfile='u-boot.dtb'): @@ -183,7 +187,8 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile(outfile, data) return data - def _DoReadFileDtb(self, fname, use_real_dtb=False, map=False): + def _DoReadFileDtb(self, fname, use_real_dtb=False, map=False, + update_dtb=False): """Run binman and return the resulting image This runs binman with a given test file and then reads the resulting @@ -199,6 +204,8 @@ class TestFunctional(unittest.TestCase): test contents (the U_BOOT_DTB_DATA string) can be used. But in some test we need the real contents. map: True to output map files for the images + update_dtb: Update the position and size of each entry in the device + tree before packing it into the image Returns: Tuple: @@ -212,21 +219,22 @@ class TestFunctional(unittest.TestCase): dtb_data = self._SetupDtb(fname) try: - retcode = self._DoTestFile(fname, map=map) + retcode = self._DoTestFile(fname, map=map, update_dtb=update_dtb) self.assertEqual(0, retcode) + out_dtb_fname = control.GetFdtPath('u-boot.dtb') # Find the (only) image, read it and return its contents image = control.images['image'] - fname = tools.GetOutputFilename('image.bin') - self.assertTrue(os.path.exists(fname)) + image_fname = tools.GetOutputFilename('image.bin') + self.assertTrue(os.path.exists(image_fname)) if map: map_fname = tools.GetOutputFilename('image.map') with open(map_fname) as fd: map_data = fd.read() else: map_data = None - with open(fname) as fd: - return fd.read(), dtb_data, map_data + with open(image_fname) as fd: + return fd.read(), dtb_data, map_data, out_dtb_fname finally: # Put the test file back if use_real_dtb: @@ -300,6 +308,26 @@ class TestFunctional(unittest.TestCase): """ return struct.unpack('>L', dtb[4:8])[0] + def _GetPropTree(self, dtb_data, node_names): + def AddNode(node, path): + if node.name != '/': + path += '/' + node.name + #print 'path', path + for subnode in node.subnodes: + for prop in subnode.props.values(): + if prop.name in node_names: + prop_path = path + '/' + subnode.name + ':' + prop.name + tree[prop_path[len('/binman/'):]] = fdt_util.fdt32_to_cpu( + prop.value) + #print ' ', prop.name + AddNode(subnode, path) + + tree = {} + dtb = fdt.Fdt(dtb_data) + dtb.Scan() + AddNode(dtb.GetRoot(), '') + return tree + def testRun(self): """Test a basic run with valid args""" result = self._RunBinman('-h') @@ -845,7 +873,7 @@ class TestFunctional(unittest.TestCase): """Test that we can cope with an image without microcode (e.g. qemu)""" with open(self.TestFile('u_boot_no_ucode_ptr')) as fd: TestFunctional._MakeInputFile('u-boot', fd.read()) - data, dtb, _ = self._DoReadFileDtb('44_x86_optional_ucode.dts', True) + data, dtb, _, _ = self._DoReadFileDtb('44_x86_optional_ucode.dts', True) # Now check the device tree has no microcode self.assertEqual(U_BOOT_NODTB_DATA, data[:len(U_BOOT_NODTB_DATA)]) @@ -980,7 +1008,7 @@ class TestFunctional(unittest.TestCase): def testMap(self): """Tests outputting a map of the images""" - _, _, map_data = self._DoReadFileDtb('55_sections.dts', map=True) + _, _, map_data, _ = self._DoReadFileDtb('55_sections.dts', map=True) self.assertEqual('''Position Size Name 00000000 00000010 section@0 00000000 00000004 u-boot @@ -990,7 +1018,7 @@ class TestFunctional(unittest.TestCase): def testNamePrefix(self): """Tests that name prefixes are used""" - _, _, map_data = self._DoReadFileDtb('56_name_prefix.dts', map=True) + _, _, map_data, _ = self._DoReadFileDtb('56_name_prefix.dts', map=True) self.assertEqual('''Position Size Name 00000000 00000010 section@0 00000000 00000004 ro-u-boot @@ -1013,6 +1041,27 @@ class TestFunctional(unittest.TestCase): self.assertIn("Node '/binman/_testing': Cannot update entry size from " '2 to 1', str(e.exception)) + def testUpdateFdt(self): + """Test that we can update the device tree with pos/size info""" + _, _, _, out_dtb_fname = self._DoReadFileDtb('60_fdt_update.dts', + update_dtb=True) + props = self._GetPropTree(out_dtb_fname, ['pos', 'size']) + with open('/tmp/x.dtb', 'wb') as outf: + with open(out_dtb_fname) as inf: + outf.write(inf.read()) + self.assertEqual({ + 'section@0/u-boot:pos': 0, + 'section@0/u-boot:size': len(U_BOOT_DATA), + 'section@0:pos': 0, + 'section@0:size': 16, + + 'section@1/u-boot:pos': 0, + 'section@1/u-boot:size': len(U_BOOT_DATA), + 'section@1:pos': 16, + 'section@1:size': 16, + 'size': 40 + }, props) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/60_fdt_update.dts b/tools/binman/test/60_fdt_update.dts new file mode 100644 index 00000000000..28e483fd7b5 --- /dev/null +++ b/tools/binman/test/60_fdt_update.dts @@ -0,0 +1,28 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + pad-byte = <0x26>; + size = <0x28>; + section@0 { + read-only; + name-prefix = "ro-"; + size = <0x10>; + pad-byte = <0x21>; + + u-boot { + }; + }; + section@1 { + name-prefix = "rw-"; + size = <0x10>; + pad-byte = <0x61>; + + u-boot { + }; + }; + }; +};