kernel: mtdsplit_uimage: add "openwrt, ih-magic" device-tree property
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>
This commit is contained in:
		| @@ -69,13 +69,17 @@ read_uimage_header(struct mtd_info *mtd, size_t offset, u_char *buf, | |||||||
| 	return 0; | 	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); | 	struct device_node *np = mtd_get_of_node(master); | ||||||
|  |  | ||||||
| 	if (!np || !of_device_is_compatible(np, "openwrt,uimage")) | 	if (!np || !of_device_is_compatible(np, "openwrt,uimage")) | ||||||
| 		return; | 		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, | static int __mtdsplit_parse_uimage(struct mtd_info *master, | ||||||
| 		   const struct mtd_partition **pparts, | 		   const struct mtd_partition **pparts, | ||||||
| 		   struct mtd_part_parser_data *data, | 		   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; | 	struct mtd_partition *parts; | ||||||
| 	u_char *buf; | 	u_char *buf; | ||||||
| @@ -100,6 +104,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, | |||||||
| 	int uimage_part, rf_part; | 	int uimage_part, rf_part; | ||||||
| 	int ret; | 	int ret; | ||||||
| 	int extralen = 0; | 	int extralen = 0; | ||||||
|  | 	u32 ih_magic = IH_MAGIC; | ||||||
| 	enum mtdsplit_part_type type; | 	enum mtdsplit_part_type type; | ||||||
|  |  | ||||||
| 	nr_parts = 2; | 	nr_parts = 2; | ||||||
| @@ -113,7 +118,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, | |||||||
| 		goto err_free_parts; | 		goto err_free_parts; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	uimage_parse_dt(master, &extralen); | 	uimage_parse_dt(master, &extralen, &ih_magic); | ||||||
|  |  | ||||||
| 	/* find uImage on erase block boundaries */ | 	/* find uImage on erase block boundaries */ | ||||||
| 	for (offset = 0; offset < master->size; offset += master->erasesize) { | 	for (offset = 0; offset < master->size; offset += master->erasesize) { | ||||||
| @@ -125,7 +130,7 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master, | |||||||
| 		if (ret) | 		if (ret) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		ret = find_header(buf, MAX_HEADER_LEN); | 		ret = find_header(buf, MAX_HEADER_LEN, ih_magic); | ||||||
| 		if (ret < 0) { | 		if (ret < 0) { | ||||||
| 			pr_debug("no valid uImage found in \"%s\" at offset %llx\n", | 			pr_debug("no valid uImage found in \"%s\" at offset %llx\n", | ||||||
| 				 master->name, (unsigned long long) offset); | 				 master->name, (unsigned long long) offset); | ||||||
| @@ -213,26 +218,26 @@ err_free_parts: | |||||||
| 	return ret; | 	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; | 	struct uimage_header *header = (struct uimage_header *)buf; | ||||||
|  |  | ||||||
| 	/* default sanity checks */ | 	/* default sanity checks */ | ||||||
| 	if (be32_to_cpu(header->ih_magic) != IH_MAGIC) { | 	if (be32_to_cpu(header->ih_magic) != ih_magic) { | ||||||
| 		pr_debug("invalid uImage magic: %08x\n", | 		pr_debug("invalid uImage magic: %08x != %08x\n", | ||||||
| 			 be32_to_cpu(header->ih_magic)); | 			 be32_to_cpu(header->ih_magic), ih_magic); | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (header->ih_os != IH_OS_LINUX) { | 	if (header->ih_os != IH_OS_LINUX) { | ||||||
| 		pr_debug("invalid uImage OS: %08x\n", | 		pr_debug("invalid uImage OS: %08x != %08x\n", | ||||||
| 			 be32_to_cpu(header->ih_os)); | 			 be32_to_cpu(header->ih_os), IH_OS_LINUX); | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (header->ih_type != IH_TYPE_KERNEL) { | 	if (header->ih_type != IH_TYPE_KERNEL) { | ||||||
| 		pr_debug("invalid uImage type: %08x\n", | 		pr_debug("invalid uImage type: %08x != %08x\n", | ||||||
| 			 be32_to_cpu(header->ih_type)); | 			 be32_to_cpu(header->ih_type), IH_TYPE_KERNEL); | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -274,7 +279,7 @@ static struct mtd_part_parser uimage_generic_parser = { | |||||||
| #define FW_MAGIC_WNDR3700V2	0x33373031 | #define FW_MAGIC_WNDR3700V2	0x33373031 | ||||||
| #define FW_MAGIC_WPN824N	0x31313030 | #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; | 	struct uimage_header *header = (struct uimage_header *)buf; | ||||||
| 	uint8_t expected_type = IH_TYPE_FILESYSTEM; | 	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_SG8208M	0x00000006 | ||||||
| #define FW_MAGIC_SG8310PM	0x83000006 | #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; | 	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_EDIMAX_OFFSET	20 | ||||||
| #define FW_MAGIC_EDIMAX		0x43535953 | #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; | 	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) | 	if (be32_to_cpu(*magic) != FW_MAGIC_EDIMAX) | ||||||
| 		return -EINVAL; | 		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 FW_EDIMAX_OFFSET; | ||||||
|  |  | ||||||
| 	return -EINVAL; | 	return -EINVAL; | ||||||
| @@ -430,7 +435,7 @@ static struct mtd_part_parser uimage_edimax_parser = { | |||||||
|  |  | ||||||
| #define IH_MAGIC_OKLI	0x4f4b4c49 | #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; | 	struct uimage_header *header = (struct uimage_header *)buf; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Bjørn Mork
					Bjørn Mork