瀏覽代碼

kernel: mtdsplit: wrgg: Support big and little endian

The WRGG images exist in both big and little endian variants,
as can be seen from the image generator in
tools/firmware-utils/src/mkwrggimg.c, you either pass
the "-b" flag or not. The D-Link DIR-685 is using little
endian images so we need to support splitting these.

Detect endianness like this: if the kernel entity size
gets silly big (bigger than the flash memory) we are
probably using the wrong endianness.

Example: my kernel of 0x0067ff64 was switched around by
wrong endianness and detected as 0x64ff67a0 (the actual
size in swapped endianness + header 0xa0).

Signed-off-by: Linus Walleij <[email protected]>
Signed-off-by: Christian Lamparter <[email protected]>
Linus Walleij 6 年之前
父節點
當前提交
b907097291
共有 1 個文件被更改,包括 10 次插入0 次删除
  1. 10 0
      target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_wrgg.c

+ 10 - 0
target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_wrgg.c

@@ -72,6 +72,16 @@ static int mtdsplit_parse_wrgg(struct mtd_info *master,
 	/* sanity checks */
 	if (le32_to_cpu(hdr.magic1) == WRGG03_MAGIC) {
 		kernel_ent_size = hdr_len + be32_to_cpu(hdr.size);
+		/*
+		 * If this becomes silly big it's probably because the
+		 * WRGG image is little-endian.
+		 */
+		if (kernel_ent_size > master->size)
+			kernel_ent_size = hdr_len + le32_to_cpu(hdr.size);
+
+		/* Now what ?! It's neither */
+		if (kernel_ent_size > master->size)
+			return -EINVAL;
 	} else if (le32_to_cpu(hdr.magic1) == WRG_MAGIC) {
 		kernel_ent_size = sizeof(struct wrg_header) + le32_to_cpu(
 		                  ((struct wrg_header*)&hdr)->size);