* [PATCH V3 2/2] mtd: parsers: add TP-Link SafeLoader partitions table parser
2022-10-15 9:29 [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout Rafał Miłecki
@ 2022-10-15 9:29 ` Rafał Miłecki
2022-10-18 9:55 ` Miquel Raynal
2022-10-17 18:32 ` [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout Rob Herring
2022-10-18 9:56 ` Miquel Raynal
2 siblings, 1 reply; 5+ messages in thread
From: Rafał Miłecki @ 2022-10-15 9:29 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Rob Herring, Krzysztof Kozlowski
Cc: linux-mtd, devicetree, Florian Fainelli, Hauke Mehrtens,
bcm-kernel-feedback-list, John Crispin,
Arınç ÜNAL, Sergio Paracuellos, linux-arm-kernel,
linux-mips, Rafał Miłecki
From: Rafał Miłecki <rafal@milecki.pl>
This parser deals with most TP-Link home routers. It reads info about
partitions and registers them in the MTD subsystem.
Example from TP-Link Archer C5 V2:
spi-nor spi0.0: s25fl128s1 (16384 Kbytes)
15 tplink-safeloader partitions found on MTD device spi0.0
Creating 15 MTD partitions on "spi0.0":
0x000000000000-0x000000040000 : "fs-uboot"
0x000000040000-0x000000440000 : "os-image"
0x000000440000-0x000000e40000 : "rootfs"
0x000000e40000-0x000000e40200 : "default-mac"
0x000000e40200-0x000000e40400 : "pin"
0x000000e40400-0x000000e40600 : "product-info"
0x000000e50000-0x000000e60000 : "partition-table"
0x000000e60000-0x000000e60200 : "soft-version"
0x000000e61000-0x000000e70000 : "support-list"
0x000000e70000-0x000000e80000 : "profile"
0x000000e80000-0x000000e90000 : "default-config"
0x000000e90000-0x000000ee0000 : "user-config"
0x000000ee0000-0x000000fe0000 : "log"
0x000000fe0000-0x000000ff0000 : "radio_bk"
0x000000ff0000-0x000001000000 : "radio"
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
V2: Fix types (thanks kernel test robot)
Fix off-by-one when setting '\0'
V3: Include parsing example in commit body
---
drivers/mtd/parsers/Kconfig | 15 +++
drivers/mtd/parsers/Makefile | 1 +
drivers/mtd/parsers/tplink_safeloader.c | 150 ++++++++++++++++++++++++
3 files changed, 166 insertions(+)
create mode 100644 drivers/mtd/parsers/tplink_safeloader.c
diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig
index aaa06050c9bc..c258ba2a3a6f 100644
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -123,6 +123,21 @@ config MTD_AFS_PARTS
for your particular device. It won't happen automatically. The
'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
+config MTD_PARSER_TPLINK_SAFELOADER
+ tristate "TP-Link Safeloader partitions parser"
+ depends on MTD && (ARCH_BCM_5301X || ATH79 || SOC_MT7620 || SOC_MT7621 || COMPILE_TEST)
+ help
+ TP-Link home routers use flash partitions to store various data. Info
+ about flash space layout is stored in a partitions table using a
+ custom ASCII-based format.
+
+ That format was first found in devices with SafeLoader bootloader and
+ was named after it. Later it was adapted to CFE and U-Boot
+ bootloaders.
+
+ This driver reads partitions table, parses it and creates MTD
+ partitions.
+
config MTD_PARSER_TRX
tristate "Parser for TRX format partitions"
depends on MTD && (BCM47XX || ARCH_BCM_5301X || ARCH_MEDIATEK || RALINK || COMPILE_TEST)
diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile
index 23fa4de4016f..0e70b621a1d8 100644
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -10,6 +10,7 @@ ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908) += ofpart_bcm4908.o
ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
+obj-$(CONFIG_MTD_PARSER_TPLINK_SAFELOADER) += tplink_safeloader.o
obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o
obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
diff --git a/drivers/mtd/parsers/tplink_safeloader.c b/drivers/mtd/parsers/tplink_safeloader.c
new file mode 100644
index 000000000000..23584a477391
--- /dev/null
+++ b/drivers/mtd/parsers/tplink_safeloader.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright © 2022 Rafał Miłecki <rafal@milecki.pl>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#define TPLINK_SAFELOADER_DATA_OFFSET 4
+#define TPLINK_SAFELOADER_MAX_PARTS 32
+
+struct safeloader_cmn_header {
+ __be32 size;
+ uint32_t unused;
+} __packed;
+
+static void *mtd_parser_tplink_safeloader_read_table(struct mtd_info *mtd)
+{
+ struct safeloader_cmn_header hdr;
+ struct device_node *np;
+ size_t bytes_read;
+ size_t offset;
+ size_t size;
+ char *buf;
+ int err;
+
+ np = mtd_get_of_node(mtd);
+ if (mtd_is_partition(mtd))
+ of_node_get(np);
+ else
+ np = of_get_child_by_name(np, "partitions");
+
+ if (of_property_read_u32(np, "partitions-table-offset", (u32 *)&offset)) {
+ pr_err("Failed to get partitions table offset\n");
+ goto err_put;
+ }
+
+ err = mtd_read(mtd, offset, sizeof(hdr), &bytes_read, (uint8_t *)&hdr);
+ if (err && !mtd_is_bitflip(err)) {
+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset);
+ goto err_put;
+ }
+
+ size = be32_to_cpu(hdr.size);
+
+ buf = kmalloc(size + 1, GFP_KERNEL);
+ if (!buf)
+ goto err_put;
+
+ err = mtd_read(mtd, offset + sizeof(hdr), size, &bytes_read, buf);
+ if (err && !mtd_is_bitflip(err)) {
+ pr_err("Failed to read from %s at 0x%zx\n", mtd->name, offset + sizeof(hdr));
+ goto err_kfree;
+ }
+
+ buf[size] = '\0';
+
+ of_node_put(np);
+
+ return buf;
+
+err_kfree:
+ kfree(buf);
+err_put:
+ of_node_put(np);
+ return NULL;
+}
+
+static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd,
+ const struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct mtd_partition *parts;
+ char name[65];
+ size_t offset;
+ size_t bytes;
+ char *buf;
+ int idx;
+ int err;
+
+ parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL);
+ if (!parts) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ buf = mtd_parser_tplink_safeloader_read_table(mtd);
+ if (!buf) {
+ err = -ENOENT;
+ goto err_out;
+ }
+
+ for (idx = 0, offset = TPLINK_SAFELOADER_DATA_OFFSET;
+ idx < TPLINK_SAFELOADER_MAX_PARTS &&
+ sscanf(buf + offset, "partition %64s base 0x%llx size 0x%llx%zn\n",
+ name, &parts[idx].offset, &parts[idx].size, &bytes) == 3;
+ idx++, offset += bytes + 1) {
+ parts[idx].name = kstrdup(name, GFP_KERNEL);
+ if (!parts[idx].name) {
+ err = -ENOMEM;
+ goto err_free;
+ }
+ }
+
+ if (idx == TPLINK_SAFELOADER_MAX_PARTS)
+ pr_warn("Reached maximum number of partitions!\n");
+
+ kfree(buf);
+
+ *pparts = parts;
+
+ return idx;
+
+err_free:
+ for (idx -= 1; idx >= 0; idx--)
+ kfree(parts[idx].name);
+err_out:
+ return err;
+};
+
+static void mtd_parser_tplink_safeloader_cleanup(const struct mtd_partition *pparts,
+ int nr_parts)
+{
+ int i;
+
+ for (i = 0; i < nr_parts; i++)
+ kfree(pparts[i].name);
+
+ kfree(pparts);
+}
+
+static const struct of_device_id mtd_parser_tplink_safeloader_of_match_table[] = {
+ { .compatible = "tplink,safeloader-partitions" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mtd_parser_tplink_safeloader_of_match_table);
+
+static struct mtd_part_parser mtd_parser_tplink_safeloader = {
+ .parse_fn = mtd_parser_tplink_safeloader_parse,
+ .cleanup = mtd_parser_tplink_safeloader_cleanup,
+ .name = "tplink-safeloader",
+ .of_match_table = mtd_parser_tplink_safeloader_of_match_table,
+};
+module_mtd_part_parser(mtd_parser_tplink_safeloader);
+
+MODULE_LICENSE("GPL");
--
2.34.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout
2022-10-15 9:29 [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout Rafał Miłecki
2022-10-15 9:29 ` [PATCH V3 2/2] mtd: parsers: add TP-Link SafeLoader partitions table parser Rafał Miłecki
@ 2022-10-17 18:32 ` Rob Herring
2022-10-18 9:56 ` Miquel Raynal
2 siblings, 0 replies; 5+ messages in thread
From: Rob Herring @ 2022-10-17 18:32 UTC (permalink / raw)
To: Rafał Miłecki
Cc: Miquel Raynal, Arınç ÜNAL, Hauke Mehrtens,
Sergio Paracuellos, Florian Fainelli, linux-mips, Rob Herring,
Vignesh Raghavendra, John Crispin, devicetree, linux-mtd,
linux-arm-kernel, bcm-kernel-feedback-list, Richard Weinberger,
Rafał Miłecki, Krzysztof Kozlowski
On Sat, 15 Oct 2022 11:29:49 +0200, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Most TP-Link home routers use the same partitioning system based on a
> custom ASCII table.
>
> It doesn't seem to have any official name. GPL sources contain tool
> named simply "make_flash" and Makefile target "FlashMaker".
>
> This partitions table format was first found in devices with a custom
> SafeLoader bootloader so it was called SafeLoader by a community. Later
> it was ported to other bootloaders but it seems the name sticked.
>
> Add binding for describing flashes with SafeLoader partitions table. It
> allows operating systems to parse it properly and register proper flash
> layout.
>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
> V2: Fix typo in commit: s/same/name/
> V3: Drop quotes from $ref
> Describe flash space coverage & partitions types in the binding
> See commit body of PATCH 2/2 for real life example
> ---
> .../tplink,safeloader-partitions.yaml | 49 +++++++++++++++++++
> 1 file changed, 49 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mtd/partitions/tplink,safeloader-partitions.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout
2022-10-15 9:29 [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout Rafał Miłecki
2022-10-15 9:29 ` [PATCH V3 2/2] mtd: parsers: add TP-Link SafeLoader partitions table parser Rafał Miłecki
2022-10-17 18:32 ` [PATCH V3 1/2] dt-bindings: mtd: partitions: add TP-Link SafeLoader layout Rob Herring
@ 2022-10-18 9:56 ` Miquel Raynal
2 siblings, 0 replies; 5+ messages in thread
From: Miquel Raynal @ 2022-10-18 9:56 UTC (permalink / raw)
To: Rafał Miłecki, Miquel Raynal, Richard Weinberger,
Vignesh Raghavendra, Rob Herring, Krzysztof Kozlowski
Cc: linux-mtd, devicetree, Florian Fainelli, Hauke Mehrtens,
bcm-kernel-feedback-list, John Crispin,
Arınç ÜNAL, Sergio Paracuellos, linux-arm-kernel,
linux-mips, Rafał Miłecki
On Sat, 2022-10-15 at 09:29:49 UTC, =?utf-8?b?UmFmYcWCIE1pxYJlY2tp?= wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Most TP-Link home routers use the same partitioning system based on a
> custom ASCII table.
>
> It doesn't seem to have any official name. GPL sources contain tool
> named simply "make_flash" and Makefile target "FlashMaker".
>
> This partitions table format was first found in devices with a custom
> SafeLoader bootloader so it was called SafeLoader by a community. Later
> it was ported to other bootloaders but it seems the name sticked.
>
> Add binding for describing flashes with SafeLoader partitions table. It
> allows operating systems to parse it properly and register proper flash
> layout.
>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> Reviewed-by: Rob Herring <robh@kernel.org>
Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next, thanks.
Miquel
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 5+ messages in thread