summaryrefslogtreecommitdiff
path: root/target/linux
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2016-01-17 10:40:51 +0000
committerFelix Fietkau <nbd@openwrt.org>2016-01-17 10:40:51 +0000
commitbdd2772f1d1f822acedb7dadf9d5978ce2dbc2e2 (patch)
treeb8b786e2eff7311ec4bb2b31b88edcab2dd8c0c5 /target/linux
parent3348279ecae916154c87b18d3653f6f7b7dbe476 (diff)
downloadmtk-20170518-bdd2772f1d1f822acedb7dadf9d5978ce2dbc2e2.zip
mtk-20170518-bdd2772f1d1f822acedb7dadf9d5978ce2dbc2e2.tar.gz
mtk-20170518-bdd2772f1d1f822acedb7dadf9d5978ce2dbc2e2.tar.bz2
kernel: mtdsplit: add support for brnImages
This adds brnImage (used with the brnboot bootloader) firmware parsing support. brnboot verifies the integrity of the firmware stored on the "Code Image" partitions by looking at the 12 byte footer at the very end of the partition. This footer contains the checksum of the original brnImage (kernel + rootfs/squashfs) and must not be touched (by our JFFS2 rootfs_data - otherwise the image will not be bootable anymore). Big thanks to Mathias Kresin for analyzing the brnImage structure and finding out the information how to keep images valid even when adding a nested rootfs_data partition. Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> SVN-Revision: 48261
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/generic/config-3.181
-rw-r--r--target/linux/generic/config-4.11
-rw-r--r--target/linux/generic/config-4.31
-rw-r--r--target/linux/generic/config-4.41
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig5
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/Makefile1
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_brnimage.c104
7 files changed, 114 insertions, 0 deletions
diff --git a/target/linux/generic/config-3.18 b/target/linux/generic/config-3.18
index 36d8590..c8ba328 100644
--- a/target/linux/generic/config-3.18
+++ b/target/linux/generic/config-3.18
@@ -2265,6 +2265,7 @@ CONFIG_MTD_ROOTFS_SPLIT=y
# CONFIG_MTD_SPI_NOR is not set
# CONFIG_MTD_SPINAND_MT29F is not set
CONFIG_MTD_SPLIT=y
+# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
# CONFIG_MTD_SPLIT_FIRMWARE is not set
CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
# CONFIG_MTD_SPLIT_FIT_FW is not set
diff --git a/target/linux/generic/config-4.1 b/target/linux/generic/config-4.1
index 0f76041..ade6807 100644
--- a/target/linux/generic/config-4.1
+++ b/target/linux/generic/config-4.1
@@ -2357,6 +2357,7 @@ CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_SPI_NOR is not set
# CONFIG_MTD_SPINAND_MT29F is not set
CONFIG_MTD_SPLIT=y
+# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
# CONFIG_MTD_SPLIT_FIRMWARE is not set
CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
# CONFIG_MTD_SPLIT_FIT_FW is not set
diff --git a/target/linux/generic/config-4.3 b/target/linux/generic/config-4.3
index 5ec85fe..f5d8ce8 100644
--- a/target/linux/generic/config-4.3
+++ b/target/linux/generic/config-4.3
@@ -2415,6 +2415,7 @@ CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_SPI_NOR is not set
# CONFIG_MTD_SPINAND_MT29F is not set
CONFIG_MTD_SPLIT=y
+# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
# CONFIG_MTD_SPLIT_FIRMWARE is not set
CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
# CONFIG_MTD_SPLIT_FIT_FW is not set
diff --git a/target/linux/generic/config-4.4 b/target/linux/generic/config-4.4
index 5313222..c27192d 100644
--- a/target/linux/generic/config-4.4
+++ b/target/linux/generic/config-4.4
@@ -2318,6 +2318,7 @@ CONFIG_MTD_ROOTFS_ROOT_DEV=y
# CONFIG_MTD_SPI_NOR is not set
# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
CONFIG_MTD_SPLIT=y
+# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
# CONFIG_MTD_SPLIT_FIRMWARE is not set
CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
# CONFIG_MTD_SPLIT_FIT_FW is not set
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
index c4e3418..0370a21 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
@@ -49,3 +49,8 @@ config MTD_SPLIT_TRX_FW
bool "TRX image based firmware partition parser"
depends on MTD_SPLIT_SUPPORT
select MTD_SPLIT
+
+config MTD_SPLIT_BRNIMAGE_FW
+ bool "brnImage (brnboot image) firmware parser"
+ depends on MTD_SPLIT_SUPPORT
+ select MTD_SPLIT
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
index e09476b..ca24c71 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_MTD_SPLIT_FIT_FW) += mtdsplit_fit.o
obj-$(CONFIG_MTD_SPLIT_LZMA_FW) += mtdsplit_lzma.o
obj-$(CONFIG_MTD_SPLIT_TPLINK_FW) += mtdsplit_tplink.o
obj-$(CONFIG_MTD_SPLIT_TRX_FW) += mtdsplit_trx.o
+obj-$(CONFIG_MTD_SPLIT_BRNIMAGE_FW) += mtdsplit_brnimage.o
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_brnimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_brnimage.c
new file mode 100644
index 0000000..7ddd69b
--- /dev/null
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_brnimage.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2015 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/byteorder/generic.h>
+
+#include "mtdsplit.h"
+
+#define BRNIMAGE_NR_PARTS 2
+
+#define BRNIMAGE_ALIGN_BYTES 0x400
+#define BRNIMAGE_FOOTER_SIZE 12
+
+#define BRNIMAGE_MIN_OVERHEAD (BRNIMAGE_FOOTER_SIZE)
+#define BRNIMAGE_MAX_OVERHEAD (BRNIMAGE_ALIGN_BYTES + BRNIMAGE_FOOTER_SIZE)
+
+static int mtdsplit_parse_brnimage(struct mtd_info *master,
+ struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+{
+ struct mtd_partition *parts;
+ uint32_t buf;
+ unsigned long rootfs_offset, rootfs_size, kernel_size;
+ size_t len;
+ int ret;
+
+ for (rootfs_offset = 0; rootfs_offset < master->size;
+ rootfs_offset += BRNIMAGE_ALIGN_BYTES) {
+ ret = mtd_check_rootfs_magic(master, rootfs_offset);
+ if (!ret)
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ if (rootfs_offset >= master->size)
+ return -EINVAL;
+
+ ret = mtd_read(master, rootfs_offset - BRNIMAGE_FOOTER_SIZE, 4, &len,
+ (void *)&buf);
+ if (ret)
+ return ret;
+
+ if (len != 4)
+ return -EIO;
+
+ kernel_size = le32_to_cpu(buf);
+
+ if (kernel_size > (rootfs_offset - BRNIMAGE_MIN_OVERHEAD))
+ return -EINVAL;
+
+ if (kernel_size < (rootfs_offset - BRNIMAGE_MAX_OVERHEAD))
+ return -EINVAL;
+
+ /*
+ * The footer must be untouched as it contains the checksum of the
+ * original brnImage (kernel + squashfs)!
+ */
+ rootfs_size = master->size - rootfs_offset - BRNIMAGE_FOOTER_SIZE;
+
+ parts = kzalloc(BRNIMAGE_NR_PARTS * sizeof(*parts), GFP_KERNEL);
+ if (!parts)
+ return -ENOMEM;
+
+ parts[0].name = KERNEL_PART_NAME;
+ parts[0].offset = 0;
+ parts[0].size = kernel_size;
+
+ parts[1].name = ROOTFS_PART_NAME;
+ parts[1].offset = rootfs_offset;
+ parts[1].size = rootfs_size;
+
+ *pparts = parts;
+ return BRNIMAGE_NR_PARTS;
+}
+
+static struct mtd_part_parser mtdsplit_brnimage_parser = {
+ .owner = THIS_MODULE,
+ .name = "brnimage-fw",
+ .parse_fn = mtdsplit_parse_brnimage,
+ .type = MTD_PARSER_TYPE_FIRMWARE,
+};
+
+static int __init mtdsplit_brnimage_init(void)
+{
+ register_mtd_parser(&mtdsplit_brnimage_parser);
+
+ return 0;
+}
+
+subsys_initcall(mtdsplit_brnimage_init);