From patchwork Wed Jun 21 06:26:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= X-Patchwork-Id: 778661 X-Patchwork-Delegate: computersforpeace@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wsvtf6Hxmz9s2s for ; Wed, 21 Jun 2017 16:28:58 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="m08BaGDq"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="MbheJeSO"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TxLvX+xw"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=LnNNKzr0Mh0k0wu1nv921Hmn89jEPw+FXxUtbjMrgX0=; b=m08BaGDqKhg76/ blcKaHzhfsweT9gu9hab5XM2jtPa2NZmMStOhS9veH3cE25Jh04ikUIrB0h8QpaCEuyeJLWVMenWA 7hYaqqVzdHGAphgwNqZHTTqrimgN/eQwGpO69EGv34uzYWEHb7At+kbpi+j2Di2Qc4rpDcQXLfH4Z rwFklOLlbZwm+stHCfRO5NmiJaOcjQNQHIgIXAxml8r0j6nEB3oLQ2xIO/T6ELB8PCXqgFYgKwD9N lH246bz1vVaC+l4VivZ4UeZ+0qpK6LGX8Aqcs9qIRRicmRGI4tIbIEWTsHvLs1BlB/aVy7szNglj5 ICB4eLesJSCqLoHNPc+A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dNZ8E-0005AH-9q; Wed, 21 Jun 2017 06:28:50 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dNZ7N-00043T-NK for linux-mtd@bombadil.infradead.org; Wed, 21 Jun 2017 06:27:58 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=Content-Transfer-Encoding:Content-Type: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=DeaGlZjljJDnH21+30d9oPDFhsJJHso5GrR+UIes6rc=; b=MbheJeSOjPKYOPjs6cQztsNZ/y CjNGvI54BF6Ma0NTgqX9Y6EKl/AdnDlpIFAGFJkDKM6XULS3JD6M0gKDaW5AOud4CJz1Sxa/NnqDH hKt+OjBbWpS+jy5EuyvP2UtrTHSNROclp/7iWh45fqNLPArqR+R4h+B1VoeaRW8/EfW98zb9A5fsC VRJfamxa89FIPBN2afNUSSAY8moLp13YJnzQh/jkfiodxYuzcdCjq54aKBsLO5kiL28DcNvYJmpx7 OYGef788iziUIOZGyp7Us85r83ieU0/AE5w4KNI6ggsUPZabNZy2wAA2+9iC7JBOrTRK+DbC6NsTj 65mCgIMQ==; Received: from mail-lf0-x242.google.com ([2a00:1450:4010:c07::242]) by merlin.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dNZ7K-0003fI-9L for linux-mtd@lists.infradead.org; Wed, 21 Jun 2017 06:27:55 +0000 Received: by mail-lf0-x242.google.com with SMTP id u62so18684302lfg.0 for ; Tue, 20 Jun 2017 23:27:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DeaGlZjljJDnH21+30d9oPDFhsJJHso5GrR+UIes6rc=; b=TxLvX+xweZ/4ILGY+uYGOvObRVsxwuZXvmgo0k1D9VSZW7WLRVG1UlCL6+5dot3w6j MM50QM4cjkWPLM0xYFMwiM6vviTpbqPhQkLyMjG62vf6QbZHERcrxEvDErzlsQl6k84e 3raapIVYTKRqB7GpU41BNDa/OumICbpnlCWUALbswVKGkIud4m4Ez/jKm6t+Q6RIDNdl 3EB2cNw7vPmwrBRAu4UfHp8/uwkyjibn4EDaHuVCflBNgW9oufroA5O8aZfi1RQEem2/ O9NldA3Bce9132Hme6DDdU4lYkAOK/tElkiDrtyWyeP0Y9+rsbyJpmlnBGk1tza4pMyG Bacw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DeaGlZjljJDnH21+30d9oPDFhsJJHso5GrR+UIes6rc=; b=egTPIEHeyLnf0GMfRpTmcz+XMPIeih8YxJivHZTFoS7ccDi2APWr02x65mosekoQ5J MGDqIwcrEDihd0tu9I+Tcfk6Wbp026rJMtd0KMVkuz6BwF8zpZrhb7BrIVYbzCaB16sZ hjHR55DpG08lp6z4iijrV2kPHQBDLnLPoEajxlJcxH9r5r8/J2pPxlJupcEz8fIUeVN5 JQ7SakhdhG4dlzcH0L8XsZMtcTqJht0wSmeiXrAWIZgGbOewrsKt1SXRi1npR9gJUDUx c3P9EOCl/hYqVk82Binu9Q4uDei+gkhfCwWX26Jp/RgXm1m9Ni97PIcA7Tv1R0hH2+cZ KjKg== X-Gm-Message-State: AKS2vOwpCyIm7pkOM24n/Gu6nwFyVYG4EF0loGofFiDQ6VzXcrE8GLQl YYChNd/RLltTjA== X-Received: by 10.25.156.82 with SMTP id f79mr8227614lfe.4.1498026449005; Tue, 20 Jun 2017 23:27:29 -0700 (PDT) Received: from linux-samsung.lan (ip-194-187-74-233.konfederacka.maverick.com.pl. [194.187.74.233]) by smtp.gmail.com with ESMTPSA id x13sm3444596ljd.64.2017.06.20.23.27.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Jun 2017 23:27:28 -0700 (PDT) From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= To: David Woodhouse , Brian Norris , Boris Brezillon , Marek Vasut , Richard Weinberger Subject: [PATCH V7 6/6] mtd: extract TRX parser out of bcm47xxpart into a separated module Date: Wed, 21 Jun 2017 08:26:47 +0200 Message-Id: <20170621062647.6072-7-zajec5@gmail.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170621062647.6072-1-zajec5@gmail.com> References: <20170526131415.27186-1-zajec5@gmail.com> <20170621062647.6072-1-zajec5@gmail.com> MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.1 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (zajec5[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (zajec5[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [2a00:1450:4010:c07:0:0:0:242 listed in] [list.dnswl.org] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= , devicetree@vger.kernel.org, linux-mtd@lists.infradead.org, Cyrille Pitchen Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Rafał Miłecki This makes TRX parsing code reusable with other platforms and parsers. Please note this patch doesn't really change anything in the existing code, just moves it. There is still some place for improvement (e.g. working on non-hacky method of checking rootfs format) but it's not really a subject of this change. Signed-off-by: Rafał Miłecki --- V2: A totally rebased & refreshed version. V5: Add TRX format verification, improve comment, fix memory leak Thanks Brian V6: Add COMPILE_TEST to Kconfig's depends --- drivers/mtd/Kconfig | 4 ++ drivers/mtd/Makefile | 1 + drivers/mtd/bcm47xxpart.c | 99 ++---------------------------- drivers/mtd/parsers/Kconfig | 8 +++ drivers/mtd/parsers/Makefile | 1 + drivers/mtd/parsers/parser_trx.c | 126 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 94 deletions(-) create mode 100644 drivers/mtd/parsers/Kconfig create mode 100644 drivers/mtd/parsers/Makefile create mode 100644 drivers/mtd/parsers/parser_trx.c diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index e83a279f1217..5a2d71729b9a 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -155,6 +155,10 @@ config MTD_BCM47XX_PARTS This provides partitions parser for devices based on BCM47xx boards. +menu "Partition parsers" +source "drivers/mtd/parsers/Kconfig" +endmenu + comment "User Modules And Translation Layers" # diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 99bb9a1f6e16..151d60df303a 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o +obj-y += parsers/ # 'Users' - code which presents functionality to userspace. obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index d10fa6c8f074..fe2581d9d882 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -43,7 +43,8 @@ #define ML_MAGIC2 0x26594131 #define TRX_MAGIC 0x30524448 #define SHSQ_MAGIC 0x71736873 /* shsq (weird ZTE H218N endianness) */ -#define UBI_EC_MAGIC 0x23494255 /* UBI# */ + +static const char * const trx_types[] = { "trx", NULL }; struct trx_header { uint32_t magic; @@ -62,89 +63,6 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, part->mask_flags = mask_flags; } -static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, - size_t offset) -{ - uint32_t buf; - size_t bytes_read; - int err; - - err = mtd_read(master, offset, sizeof(buf), &bytes_read, - (uint8_t *)&buf); - if (err && !mtd_is_bitflip(err)) { - pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", - offset, err); - goto out_default; - } - - if (buf == UBI_EC_MAGIC) - return "ubi"; - -out_default: - return "rootfs"; -} - -static int bcm47xxpart_parse_trx(struct mtd_info *master, - struct mtd_partition *trx, - struct mtd_partition *parts, - size_t parts_len) -{ - struct trx_header header; - size_t bytes_read; - int curr_part = 0; - int i, err; - - if (parts_len < 3) { - pr_warn("No enough space to add TRX partitions!\n"); - return -ENOMEM; - } - - err = mtd_read(master, trx->offset, sizeof(header), &bytes_read, - (uint8_t *)&header); - if (err && !mtd_is_bitflip(err)) { - pr_err("mtd_read error while reading TRX header: %d\n", err); - return err; - } - - i = 0; - - /* We have LZMA loader if offset[2] points to sth */ - if (header.offset[2]) { - bcm47xxpart_add_part(&parts[curr_part++], "loader", - trx->offset + header.offset[i], 0); - i++; - } - - if (header.offset[i]) { - bcm47xxpart_add_part(&parts[curr_part++], "linux", - trx->offset + header.offset[i], 0); - i++; - } - - if (header.offset[i]) { - size_t offset = trx->offset + header.offset[i]; - const char *name = bcm47xxpart_trx_data_part_name(master, - offset); - - bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0); - i++; - } - - /* - * Assume that every partition ends at the beginning of the one it is - * followed by. - */ - for (i = 0; i < curr_part; i++) { - u64 next_part_offset = (i < curr_part - 1) ? - parts[i + 1].offset : - trx->offset + trx->size; - - parts[i].size = next_part_offset - parts[i].offset; - } - - return curr_part; -} - /** * bcm47xxpart_bootpartition - gets index of TRX partition used by bootloader * @@ -362,17 +280,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, for (i = 0; i < trx_num; i++) { struct mtd_partition *trx = &parts[trx_parts[i]]; - if (i == bcm47xxpart_bootpartition()) { - int num_parts; - - num_parts = bcm47xxpart_parse_trx(master, trx, - parts + curr_part, - BCM47XXPART_MAX_PARTS - curr_part); - if (num_parts > 0) - curr_part += num_parts; - } else { + if (i == bcm47xxpart_bootpartition()) + trx->types = trx_types; + else trx->name = "failsafe"; - } } *pparts = parts; diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig new file mode 100644 index 000000000000..d206b3c533bc --- /dev/null +++ b/drivers/mtd/parsers/Kconfig @@ -0,0 +1,8 @@ +config MTD_PARSER_TRX + tristate "Parser for TRX format partitions" + depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST) + help + TRX is a firmware format used by Broadcom on their devices. It + may contain up to 3/4 partitions (depending on the version). + This driver will parse TRX header and report at least two partitions: + kernel and rootfs. diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile new file mode 100644 index 000000000000..4d9024e0be3b --- /dev/null +++ b/drivers/mtd/parsers/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o diff --git a/drivers/mtd/parsers/parser_trx.c b/drivers/mtd/parsers/parser_trx.c new file mode 100644 index 000000000000..e805108afd31 --- /dev/null +++ b/drivers/mtd/parsers/parser_trx.c @@ -0,0 +1,126 @@ +/* + * Parser for TRX format partitions + * + * Copyright (C) 2012 - 2017 Rafał Miłecki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include + +#define TRX_PARSER_MAX_PARTS 4 + +/* Magics */ +#define TRX_MAGIC 0x30524448 +#define UBI_EC_MAGIC 0x23494255 /* UBI# */ + +struct trx_header { + uint32_t magic; + uint32_t length; + uint32_t crc32; + uint16_t flags; + uint16_t version; + uint32_t offset[3]; +} __packed; + +static const char *parser_trx_data_part_name(struct mtd_info *master, + size_t offset) +{ + uint32_t buf; + size_t bytes_read; + int err; + + err = mtd_read(master, offset, sizeof(buf), &bytes_read, + (uint8_t *)&buf); + if (err && !mtd_is_bitflip(err)) { + pr_err("mtd_read error while parsing (offset: 0x%X): %d\n", + offset, err); + goto out_default; + } + + if (buf == UBI_EC_MAGIC) + return "ubi"; + +out_default: + return "rootfs"; +} + +static int parser_trx_parse(struct mtd_info *mtd, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct mtd_partition *parts; + struct mtd_partition *part; + struct trx_header trx; + size_t bytes_read; + uint8_t curr_part = 0, i = 0; + int err; + + parts = kzalloc(sizeof(struct mtd_partition) * TRX_PARSER_MAX_PARTS, + GFP_KERNEL); + if (!parts) + return -ENOMEM; + + err = mtd_read(mtd, 0, sizeof(trx), &bytes_read, (uint8_t *)&trx); + if (err) { + pr_err("MTD reading error: %d\n", err); + kfree(parts); + return err; + } + + if (trx.magic != TRX_MAGIC) { + kfree(parts); + return -ENOENT; + } + + /* We have LZMA loader if there is address in offset[2] */ + if (trx.offset[2]) { + part = &parts[curr_part++]; + part->name = "loader"; + part->offset = trx.offset[i]; + i++; + } + + if (trx.offset[i]) { + part = &parts[curr_part++]; + part->name = "linux"; + part->offset = trx.offset[i]; + i++; + } + + if (trx.offset[i]) { + part = &parts[curr_part++]; + part->name = parser_trx_data_part_name(mtd, trx.offset[i]); + part->offset = trx.offset[i]; + i++; + } + + /* + * Assume that every partition ends at the beginning of the one it is + * followed by. + */ + for (i = 0; i < curr_part; i++) { + u64 next_part_offset = (i < curr_part - 1) ? + parts[i + 1].offset : mtd->size; + + parts[i].size = next_part_offset - parts[i].offset; + } + + *pparts = parts; + return i; +}; + +static struct mtd_part_parser mtd_parser_trx = { + .parse_fn = parser_trx_parse, + .name = "trx", +}; +module_mtd_part_parser(mtd_parser_trx); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Parser for TRX format partitions");