diff options
Diffstat (limited to 'target/linux/generic/patches-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch')
-rw-r--r-- | target/linux/generic/patches-4.9/065-v4.13-0008-mtd-extract-TRX-parser-out-of-bcm47xxpart-into-a-sep.patch | 320 |
1 files changed, 320 insertions, 0 deletions
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 0000000000..3761a46610 --- /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@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@milecki.pl> +Signed-off-by: Brian Norris <computersforpeace@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@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"); |