From ed39f7ec1abde0d447a2dde8a8dce8042a3c5b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no> Date: Wed, 20 Jan 2021 18:36:47 +0100 Subject: [PATCH] kernel: mtdsplit_uimage: add "openwrt, ih-magic" device-tree property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many devices use uimages with non-standard magic values. Let device tree override the default magic. Signed-off-by: Bjørn Mork <bjorn@mork.no> --- .../drivers/mtd/mtdsplit/mtdsplit_uimage.c | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c index f5e48c661e8..58c40e9ec70 100644 --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c @@ -69,13 +69,17 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, return 0; } -static void uimage_parse_dt(struct mtd_info *master, int *extralen) +static void uimage_parse_dt(struct mtd_info *master, int *extralen, u32 *ih_magic) { struct device_node *np = mtd_get_of_node(master); if (!np || !of_device_is_compatible(np, "openwrt,uimage")) return; - of_property_read_u32(np, "openwrt,padding", extralen); + + if (!of_property_read_u32(np, "openwrt,padding", extralen)) + pr_debug("got openwrt,padding=%d from device-tree\n", *extralen); + if (!of_property_read_u32(np, "openwrt,ih-magic", ih_magic)) + pr_debug("got openwrt,ih-magic=%08x from device-tree\n", *ih_magic); } /** @@ -87,7 +91,7 @@ static void uimage_parse_dt(struct mtd_info *master, int *extralen) static int __mtdsplit_parse_uimage(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data, - ssize_t (*find_header)(u_char *buf, size_t len)) + ssize_t (*find_header)(u_char *buf, size_t len, u32 ih_magic)) { struct mtd_partition *parts; u_char *buf; @@ -100,6 +104,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, int uimage_part, rf_part; int ret; int extralen = 0; + u32 ih_magic = IH_MAGIC; enum mtdsplit_part_type type; nr_parts = 2; @@ -113,7 +118,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, goto err_free_parts; } - uimage_parse_dt(master, &extralen); + uimage_parse_dt(master, &extralen, &ih_magic); /* find uImage on erase block boundaries */ for (offset = 0; offset < master->size; offset += master->erasesize) { @@ -125,7 +130,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, if (ret) continue; - ret = find_header(buf, MAX_HEADER_LEN); + ret = find_header(buf, MAX_HEADER_LEN, ih_magic); if (ret < 0) { pr_debug("no valid uImage found in \"%s\" at offset %llx\n", master->name, (unsigned long long) offset); @@ -213,26 +218,26 @@ err_free_parts: return ret; } -static ssize_t uimage_verify_default(u_char *buf, size_t len) +static ssize_t uimage_verify_default(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; /* default sanity checks */ - if (be32_to_cpu(header->ih_magic) != IH_MAGIC) { - pr_debug("invalid uImage magic: %08x\n", - be32_to_cpu(header->ih_magic)); + if (be32_to_cpu(header->ih_magic) != ih_magic) { + pr_debug("invalid uImage magic: %08x != %08x\n", + be32_to_cpu(header->ih_magic), ih_magic); return -EINVAL; } if (header->ih_os != IH_OS_LINUX) { - pr_debug("invalid uImage OS: %08x\n", - be32_to_cpu(header->ih_os)); + pr_debug("invalid uImage OS: %08x != %08x\n", + be32_to_cpu(header->ih_os), IH_OS_LINUX); return -EINVAL; } if (header->ih_type != IH_TYPE_KERNEL) { - pr_debug("invalid uImage type: %08x\n", - be32_to_cpu(header->ih_type)); + pr_debug("invalid uImage type: %08x != %08x\n", + be32_to_cpu(header->ih_type), IH_TYPE_KERNEL); return -EINVAL; } @@ -274,7 +279,7 @@ static struct mtd_part_parser uimage_generic_parser = { #define FW_MAGIC_WNDR3700V2 0x33373031 #define FW_MAGIC_WPN824N 0x31313030 -static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len) +static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; uint8_t expected_type = IH_TYPE_FILESYSTEM; @@ -336,7 +341,7 @@ static struct mtd_part_parser uimage_netgear_parser = { #define FW_MAGIC_SG8208M 0x00000006 #define FW_MAGIC_SG8310PM 0x83000006 -static ssize_t uimage_verify_allnet(u_char *buf, size_t len) +static ssize_t uimage_verify_allnet(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf; @@ -383,7 +388,7 @@ static struct mtd_part_parser uimage_allnet_parser = { #define FW_EDIMAX_OFFSET 20 #define FW_MAGIC_EDIMAX 0x43535953 -static ssize_t uimage_find_edimax(u_char *buf, size_t len) +static ssize_t uimage_find_edimax(u_char *buf, size_t len, u32 ih_magic) { u32 *magic; @@ -396,7 +401,7 @@ static ssize_t uimage_find_edimax(u_char *buf, size_t len) if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) return -EINVAL; - if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len)) + if (!uimage_verify_default(buf + FW_EDIMAX_OFFSET, len, ih_magic)) return FW_EDIMAX_OFFSET; return -EINVAL; @@ -430,7 +435,7 @@ static struct mtd_part_parser uimage_edimax_parser = { #define IH_MAGIC_OKLI 0x4f4b4c49 -static ssize_t uimage_verify_okli(u_char *buf, size_t len) +static ssize_t uimage_verify_okli(u_char *buf, size_t len, u32 ih_magic) { struct uimage_header *header = (struct uimage_header *)buf;