[source] kernel: backport MTD patch extracing TRX code to separated parser

LEDE Commits lede-commits at lists.infradead.org
Fri Jun 23 02:55:59 PDT 2017


rmilecki pushed a commit to source.git, branch master:
https://git.lede-project.org/f5f1d40b5ec8130afa5440f958713e1d029b0161

commit f5f1d40b5ec8130afa5440f958713e1d029b0161
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Fri Jun 23 10:58:16 2017 +0200

    kernel: backport MTD patch extracing TRX code to separated parser
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 target/linux/bcm53xx/config-4.9                    |   1 +
 ...m47xxpart-add-device-specific-workarounds.patch |   2 +-
 ...-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch | 320 +++++++++++++++++++++
 .../430-mtd-add-myloader-partition-parser.patch    |   8 +-
 ...part-check-for-bad-blocks-when-calculatin.patch |  89 +++---
 ...-mtd-bcm47xxpart-detect-T_Meter-partition.patch |   2 +-
 6 files changed, 362 insertions(+), 60 deletions(-)

diff --git a/target/linux/bcm53xx/config-4.9 b/target/linux/bcm53xx/config-4.9
index 2859f03..c98ba7b 100644
--- a/target/linux/bcm53xx/config-4.9
+++ b/target/linux/bcm53xx/config-4.9
@@ -225,6 +225,7 @@ CONFIG_MTD_M25P80=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_PARSER_TRX=y
 # CONFIG_MTD_PHYSMAP_OF is not set
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_SPLIT_FIRMWARE=y
diff --git a/target/linux/bcm53xx/patches-4.9/900-mtd-bcm47xxpart-add-device-specific-workarounds.patch b/target/linux/bcm53xx/patches-4.9/900-mtd-bcm47xxpart-add-device-specific-workarounds.patch
index 0223ab4..b4a25a3 100644
--- a/target/linux/bcm53xx/patches-4.9/900-mtd-bcm47xxpart-add-device-specific-workarounds.patch
+++ b/target/linux/bcm53xx/patches-4.9/900-mtd-bcm47xxpart-add-device-specific-workarounds.patch
@@ -17,7 +17,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  
  #include <uapi/linux/magic.h>
  
-@@ -249,6 +250,36 @@ static int bcm47xxpart_parse(struct mtd_
+@@ -134,6 +135,36 @@ static int bcm47xxpart_parse(struct mtd_
  			break;
  		}
  
diff --git a/target/linux/generic/patches-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch b/target/linux/generic/patches-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch
new file mode 100644
index 0000000..3761a46
--- /dev/null
+++ b/target/linux/generic/patches-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch
@@ -0,0 +1,320 @@
+From 99352afe8f169c95b294b6b9a8d0e18cd9e3c2a0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal at milecki.pl>
+Date: Wed, 21 Jun 2017 08:26:47 +0200
+Subject: [PATCH] mtd: extract TRX parser out of bcm47xxpart into a separated
+ module
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+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 <rafal at milecki.pl>
+Signed-off-by: Brian Norris <computersforpeace at gmail.com>
+---
+ 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
+
+--- 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"
+ 
+ #
+--- 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
+--- 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
+ 	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_
+ 	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;
+--- /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.
+--- /dev/null
++++ b/drivers/mtd/parsers/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o
+--- /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 <rafal at milecki.pl>
++ *
++ * 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 <linux/module.h>
++#include <linux/slab.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++
++#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");
diff --git a/target/linux/generic/patches-4.9/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/patches-4.9/430-mtd-add-myloader-partition-parser.patch
index a022564..9bf014e 100644
--- a/target/linux/generic/patches-4.9/430-mtd-add-myloader-partition-parser.patch
+++ b/target/linux/generic/patches-4.9/430-mtd-add-myloader-partition-parser.patch
@@ -1,8 +1,8 @@
 --- a/drivers/mtd/Kconfig
 +++ b/drivers/mtd/Kconfig
-@@ -174,6 +174,22 @@ config MTD_BCM47XX_PARTS
- 	  This provides partitions parser for devices based on BCM47xx
- 	  boards.
+@@ -178,6 +178,22 @@ menu "Partition parsers"
+ source "drivers/mtd/parsers/Kconfig"
+ endmenu
  
 +config MTD_MYLOADER_PARTS
 +	tristate "MyLoader partition parsing"
@@ -30,6 +30,6 @@
  obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
  obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
 +obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+ obj-y				+= parsers/
  
  # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
diff --git a/target/linux/generic/patches-4.9/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/patches-4.9/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
index 379e551..2726220 100644
--- a/target/linux/generic/patches-4.9/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
+++ b/target/linux/generic/patches-4.9/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
@@ -8,35 +8,32 @@ Content-Transfer-Encoding: 8bit
 
 Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 ---
- drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 40 insertions(+), 10 deletions(-)
 
---- a/drivers/mtd/bcm47xxpart.c
-+++ b/drivers/mtd/bcm47xxpart.c
-@@ -62,6 +62,34 @@ static void bcm47xxpart_add_part(struct
- 	part->mask_flags = mask_flags;
- }
+--- a/drivers/mtd/parsers/parser_trx.c
++++ b/drivers/mtd/parsers/parser_trx.c
+@@ -29,6 +29,33 @@ struct trx_header {
+ 	uint32_t offset[3];
+ } __packed;
  
 +/*
 + * Calculate real end offset (address) for a given amount of data. It checks
 + * all blocks skipping bad ones.
 + */
-+static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset,
-+				      size_t bytes)
++static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes)
 +{
-+	size_t real_offset = offset;
++	size_t real_offset = 0;
 +
-+	if (mtd_block_isbad(master, real_offset))
++	if (mtd_block_isbad(mtd, real_offset))
 +		pr_warn("Base offset shouldn't be at bad block");
 +
-+	while (bytes >= master->erasesize) {
-+		bytes -= master->erasesize;
-+		real_offset += master->erasesize;
-+		while (mtd_block_isbad(master, real_offset)) {
-+			real_offset += master->erasesize;
++	while (bytes >= mtd->erasesize) {
++		bytes -= mtd->erasesize;
++		real_offset += mtd->erasesize;
++		while (mtd_block_isbad(mtd, real_offset)) {
++			real_offset += mtd->erasesize;
 +
-+			if (real_offset >= master->size)
-+				return real_offset - master->erasesize;
++			if (real_offset >= mtd->size)
++				return real_offset - mtd->erasesize;
 +		}
 +	}
 +
@@ -45,47 +42,31 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 +	return real_offset;
 +}
 +
- static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master,
- 						  size_t offset)
+ static const char *parser_trx_data_part_name(struct mtd_info *master,
+ 					     size_t offset)
  {
-@@ -91,6 +119,7 @@ static int bcm47xxpart_parse_trx(struct
- {
- 	struct trx_header header;
- 	size_t bytes_read;
-+	size_t offset;
- 	int curr_part = 0;
- 	int i, err;
- 
-@@ -110,21 +139,25 @@ static int bcm47xxpart_parse_trx(struct
- 
- 	/* 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);
-+		offset = bcm47xxpart_real_offset(master, trx->offset,
-+						 header.offset[i]);
-+		bcm47xxpart_add_part(&parts[curr_part++], "loader", offset, 0);
+@@ -83,21 +110,21 @@ static int parser_trx_parse(struct mtd_i
+ 	if (trx.offset[2]) {
+ 		part = &parts[curr_part++];
+ 		part->name = "loader";
+-		part->offset = trx.offset[i];
++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
  		i++;
  	}
  
- 	if (header.offset[i]) {
--		bcm47xxpart_add_part(&parts[curr_part++], "linux",
--				     trx->offset + header.offset[i], 0);
-+		offset = bcm47xxpart_real_offset(master, trx->offset,
-+						 header.offset[i]);
-+		bcm47xxpart_add_part(&parts[curr_part++], "linux", offset, 0);
+ 	if (trx.offset[i]) {
+ 		part = &parts[curr_part++];
+ 		part->name = "linux";
+-		part->offset = trx.offset[i];
++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
  		i++;
  	}
  
- 	if (header.offset[i]) {
--		size_t offset = trx->offset + header.offset[i];
--		const char *name = bcm47xxpart_trx_data_part_name(master,
--								  offset);
-+		const char *name;
-+
-+		offset = bcm47xxpart_real_offset(master, trx->offset,
-+						 header.offset[i]);
-+		name = bcm47xxpart_trx_data_part_name(master, offset);
- 
- 		bcm47xxpart_add_part(&parts[curr_part++], name, offset, 0);
+ 	if (trx.offset[i]) {
+ 		part = &parts[curr_part++];
+ 		part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
+-		part->offset = trx.offset[i];
++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
  		i++;
+ 	}
+ 
diff --git a/target/linux/generic/patches-4.9/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/patches-4.9/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
index a19e943..b7b56cb 100644
--- a/target/linux/generic/patches-4.9/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
+++ b/target/linux/generic/patches-4.9/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
@@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
  #define ML_MAGIC1			0x39685a42
  #define ML_MAGIC2			0x26594131
  #define TRX_MAGIC			0x30524448
-@@ -297,6 +298,15 @@ static int bcm47xxpart_parse(struct mtd_
+@@ -182,6 +183,15 @@ static int bcm47xxpart_parse(struct mtd_
  					     MTD_WRITEABLE);
  			continue;
  		}



More information about the lede-commits mailing list