From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2EB67C433EF for ; Mon, 7 Feb 2022 22:09:17 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1D50F83C29; Mon, 7 Feb 2022 23:08:43 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Wn7bvfvO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id EF78A83C1C; Mon, 7 Feb 2022 23:08:41 +0100 (CET) Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4EF2B83BEB for ; Mon, 7 Feb 2022 23:08:36 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=alpernebiyasak@gmail.com Received: by mail-ed1-x529.google.com with SMTP id da4so11222882edb.4 for ; Mon, 07 Feb 2022 14:08:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UWgcv8v/YMtzRTz6B1ZCY66Surr/QbuETe+D5Tq1dW0=; b=Wn7bvfvOaAGMVHhRffnvq5EfLmVaJ633EDe3mAJy1dpaZDL5PwJjQQ3yvcIKqpeL/h tzTl+c0gsUb7/fIC02sbjYsiFCmCpgaHEjdvhd2dMdpG4AdyT6Oe69Is/G4YQzeAaeEd SVUaJO7unup72FX94Px54NWELum6ewlfW3w7Cl74J0v+zkSw0mncE93IgER6krzCZNkq ahfdSnBMV7aARYjwJ+hbM3w70aHJRoSBQcUEfw/dQGjPxE8ybuHThiqX8zfN72Tcp6i1 Bl+BGmIJA4Q13ds3mfxbpndefUW91p1QdJAu/uSJoCYpxDwy7/ANHq58Ahwcv77yNzXk Cdzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UWgcv8v/YMtzRTz6B1ZCY66Surr/QbuETe+D5Tq1dW0=; b=1PWwXuMz8NR09z5D08c1RUnT5OXyua3Xfb29pvu2bQxAbPvmPMEbpHwPU7VKJtp/Hf WhFU2P9ZxrsdQQTqbVPMIXjqwYw/6Icjq36JP1KgFXmVR+DUxAou/ylW3SfEhkKw1bbH kKOXz+ExirPgJMnC6isArAJFSMbq4escl8OxLByfhjSOOuaHbUF1tNBMDLrmDYc4Bpva 98JnIQq3oj3emcbxIFMzssGacJjSVo691vU/ETXeizoRtC0Mu6LSkaiL8a1+GEVvR+Uj +7Blu4AK/TfQYe4Vw4OHo6T2IdcPz8+oXvp49x+sds8gu9V9HLo3LlBHuOlARTcGND0U NEhA== X-Gm-Message-State: AOAM533vw6Wo0cqTSkgFVgiQpPTJkpn94AG+aUhGe4ydB5VlwqybF16F LrlyHdL6wq7XcCcJksZnBvSVP/vbPl8= X-Google-Smtp-Source: ABdhPJyYAuy87tDpFxSmW2O1ocV9ULY1p+3WnRBOkbRxJQs0tollzcRCFZ167LFyVE/cUytu6gOUtQ== X-Received: by 2002:a05:6402:42c6:: with SMTP id i6mr1559451edc.220.1644271715699; Mon, 07 Feb 2022 14:08:35 -0800 (PST) Received: from localhost.localdomain ([178.233.26.119]) by smtp.gmail.com with ESMTPSA id v16sm4081300ejo.156.2022.02.07.14.08.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Feb 2022 14:08:35 -0800 (PST) From: Alper Nebi Yasak To: u-boot@lists.denx.de Cc: Heiko Thiery , Jan Kiszka , Simon Glass , Alper Nebi Yasak Subject: [PATCH v2 5/5] binman: Update image positions of FIT subentries Date: Tue, 8 Feb 2022 01:08:08 +0300 Message-Id: <20220207220809.4497-6-alpernebiyasak@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220207220809.4497-1-alpernebiyasak@gmail.com> References: <20220207220809.4497-1-alpernebiyasak@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Binman keeps track of positions of each entry in the final image, but currently this data is wrong for things included in FIT entries, especially since a previous patch makes FIT a subclass of Section and inherit its implementation. There are three ways to put data into a FIT image. It can be directly included as a "data" property, or it can be external to the FIT image represented by an offset-size pair of properties. This external offset is either "data-position" from the start of the FIT or "data-offset" from the end of the FIT, and the size is "data-size" for both. However, binman doesn't use the "data-offset" method while building FIT entries. According to the Section docstring, its subclasses should calculate and set the correct offsets and sizes in SetImagePos() method. Do this for FIT subentries for the three ways mentioned above, and add tests for the two ways binman can pack them in. Signed-off-by: Alper Nebi Yasak Reviewed-by: Simon Glass --- Changes in v2: - Check missing_bintools list instead of catching Fdt exceptions - Add tag: "Reviewed-by: Simon Glass " tools/binman/etype/fit.py | 51 +++++++++++++++++ tools/binman/ftest.py | 112 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index 0f8c88a9720e..5497f036a26d 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -291,6 +291,57 @@ def _BuildInput(self, fdt): data = fdt.GetContents() return data + def SetImagePos(self, image_pos): + """Set the position in the image + + This sets each subentry's offsets, sizes and positions-in-image + according to where they ended up in the packed FIT file. + + Args: + image_pos: Position of this entry in the image + """ + super().SetImagePos(image_pos) + + # If mkimage is missing we'll have empty data, + # which will cause a FDT_ERR_BADMAGIC error + if self.mkimage in self.missing_bintools: + return + + fdt = Fdt.FromData(self.GetData()) + fdt.Scan() + + for path, section in self._entries.items(): + node = fdt.GetNode(path) + + data_prop = node.props.get("data") + data_pos = fdt_util.GetInt(node, "data-position") + data_offset = fdt_util.GetInt(node, "data-offset") + data_size = fdt_util.GetInt(node, "data-size") + + # Contents are inside the FIT + if data_prop is not None: + # GetOffset() returns offset of a fdt_property struct, + # which has 3 fdt32_t members before the actual data. + offset = data_prop.GetOffset() + 12 + size = len(data_prop.bytes) + + # External offset from the base of the FIT + elif data_pos is not None: + offset = data_pos + size = data_size + + # External offset from the end of the FIT, not used in binman + elif data_offset is not None: # pragma: no cover + offset = fdt.GetFdtObj().totalsize() + data_offset + size = data_size + + # This should never happen + else: # pragma: no cover + self.Raise("%s: missing data properties" % (path)) + + section.SetOffsetSize(offset, size) + section.SetImagePos(self.image_pos) + def AddBintools(self, tools): super().AddBintools(tools) self.mkimage = self.AddBintool(tools, 'mkimage') diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index f16798960b84..ab988565c335 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -3770,6 +3770,62 @@ def testSimpleFitExpandsSubentries(self): self._CheckSimpleFitData(fit_data, U_BOOT_EXP_DATA, U_BOOT_SPL_DTB_DATA) + def testSimpleFitImagePos(self): + """Test that we have correct image-pos for FIT subentries""" + data, _, _, out_dtb_fname = self._DoReadFileDtb('161_fit.dts', + update_dtb=True) + dtb = fdt.Fdt(out_dtb_fname) + dtb.Scan() + props = self._GetPropTree(dtb, BASE_DTB_PROPS + REPACK_DTB_PROPS) + + self.assertEqual({ + 'image-pos': 0, + 'offset': 0, + 'size': 1890, + + 'u-boot:image-pos': 0, + 'u-boot:offset': 0, + 'u-boot:size': 4, + + 'fit:image-pos': 4, + 'fit:offset': 4, + 'fit:size': 1840, + + 'fit/images/kernel:image-pos': 160, + 'fit/images/kernel:offset': 156, + 'fit/images/kernel:size': 4, + + 'fit/images/kernel/u-boot:image-pos': 160, + 'fit/images/kernel/u-boot:offset': 0, + 'fit/images/kernel/u-boot:size': 4, + + 'fit/images/fdt-1:image-pos': 456, + 'fit/images/fdt-1:offset': 452, + 'fit/images/fdt-1:size': 6, + + 'fit/images/fdt-1/u-boot-spl-dtb:image-pos': 456, + 'fit/images/fdt-1/u-boot-spl-dtb:offset': 0, + 'fit/images/fdt-1/u-boot-spl-dtb:size': 6, + + 'u-boot-nodtb:image-pos': 1844, + 'u-boot-nodtb:offset': 1844, + 'u-boot-nodtb:size': 46, + }, props) + + # Actually check the data is where we think it is + for node, expected in [ + ("u-boot", U_BOOT_DATA), + ("fit/images/kernel", U_BOOT_DATA), + ("fit/images/kernel/u-boot", U_BOOT_DATA), + ("fit/images/fdt-1", U_BOOT_SPL_DTB_DATA), + ("fit/images/fdt-1/u-boot-spl-dtb", U_BOOT_SPL_DTB_DATA), + ("u-boot-nodtb", U_BOOT_NODTB_DATA), + ]: + image_pos = props[f"{node}:image-pos"] + size = props[f"{node}:size"] + self.assertEqual(len(expected), size) + self.assertEqual(expected, data[image_pos:image_pos+size]) + def testFitExternal(self): """Test an image with an FIT with external images""" data = self._DoReadFile('162_fit_external.dts') @@ -3798,6 +3854,62 @@ def testFitExternal(self): self.assertEqual(U_BOOT_DATA + b'aa', data[actual_pos:actual_pos + external_data_size]) + def testFitExternalImagePos(self): + """Test that we have correct image-pos for external FIT subentries""" + data, _, _, out_dtb_fname = self._DoReadFileDtb('162_fit_external.dts', + update_dtb=True) + dtb = fdt.Fdt(out_dtb_fname) + dtb.Scan() + props = self._GetPropTree(dtb, BASE_DTB_PROPS + REPACK_DTB_PROPS) + + self.assertEqual({ + 'image-pos': 0, + 'offset': 0, + 'size': 1082, + + 'u-boot:image-pos': 0, + 'u-boot:offset': 0, + 'u-boot:size': 4, + + 'fit:size': 1032, + 'fit:offset': 4, + 'fit:image-pos': 4, + + 'fit/images/kernel:size': 4, + 'fit/images/kernel:offset': 1024, + 'fit/images/kernel:image-pos': 1028, + + 'fit/images/kernel/u-boot:size': 4, + 'fit/images/kernel/u-boot:offset': 0, + 'fit/images/kernel/u-boot:image-pos': 1028, + + 'fit/images/fdt-1:size': 2, + 'fit/images/fdt-1:offset': 1028, + 'fit/images/fdt-1:image-pos': 1032, + + 'fit/images/fdt-1/_testing:size': 2, + 'fit/images/fdt-1/_testing:offset': 0, + 'fit/images/fdt-1/_testing:image-pos': 1032, + + 'u-boot-nodtb:image-pos': 1036, + 'u-boot-nodtb:offset': 1036, + 'u-boot-nodtb:size': 46, + }, props) + + # Actually check the data is where we think it is + for node, expected in [ + ("u-boot", U_BOOT_DATA), + ("fit/images/kernel", U_BOOT_DATA), + ("fit/images/kernel/u-boot", U_BOOT_DATA), + ("fit/images/fdt-1", b'aa'), + ("fit/images/fdt-1/_testing", b'aa'), + ("u-boot-nodtb", U_BOOT_NODTB_DATA), + ]: + image_pos = props[f"{node}:image-pos"] + size = props[f"{node}:size"] + self.assertEqual(len(expected), size) + self.assertEqual(expected, data[image_pos:image_pos+size]) + def testFitMissing(self): """Test that binman still produces a FIT image if mkimage is missing""" with test_util.capture_sys_output() as (_, stderr): -- 2.34.1