aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2015-02-12 06:57:24 +0000
committerRafał Miłecki <zajec5@gmail.com>2015-02-12 06:57:24 +0000
commitf43fbf249693c8c93de5c877b8668020f4c1952d (patch)
tree34fdbcb4438846d2dffef367ddc2dce2480a9101 /target/linux
parente0ec46ed4d6a993181c4e65ce37b9fa7e415768a (diff)
downloadupstream-f43fbf249693c8c93de5c877b8668020f4c1952d.tar.gz
upstream-f43fbf249693c8c93de5c877b8668020f4c1952d.tar.bz2
upstream-f43fbf249693c8c93de5c877b8668020f4c1952d.zip
mtdsplit_uimage: more generic header verify function
Some devices have uImage headers after some extra headers (e.g. Edimax devices). To support such cases our verify callback function should be allowed to return header offset, not just a boolean value. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44412 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c37
1 files changed, 26 insertions, 11 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 1df0ac1ae1..fa89f33ac0 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c
@@ -71,10 +71,16 @@ read_uimage_header(struct mtd_info *mtd, size_t offset,
return 0;
}
+/**
+ * __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts
+ *
+ * @find_header: function to call for a block of data that will return offset
+ * of a valid uImage header if found
+ */
static int __mtdsplit_parse_uimage(struct mtd_info *master,
struct mtd_partition **pparts,
struct mtd_part_parser_data *data,
- bool (*verify)(struct uimage_header *hdr))
+ ssize_t (*find_header)(u_char *buf, size_t len))
{
struct mtd_partition *parts;
struct uimage_header *header;
@@ -106,11 +112,16 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master,
if (ret)
continue;
- if (!verify(header)) {
+ ret = find_header((u_char *)header, sizeof(*header));
+ if (ret < 0) {
pr_debug("no valid uImage found in \"%s\" at offset %llx\n",
master->name, (unsigned long long) offset);
continue;
}
+ if (ret > 0) {
+ pr_warn("extra header offsets are not supported yet\n");
+ continue;
+ }
uimage_size = sizeof(*header) + be32_to_cpu(header->ih_size);
if ((offset + uimage_size) > master->size) {
@@ -189,28 +200,30 @@ err_free_parts:
return ret;
}
-static bool uimage_verify_default(struct uimage_header *header)
+static ssize_t uimage_verify_default(u_char *buf, size_t len)
{
+ 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));
- return false;
+ return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX) {
pr_debug("invalid uImage OS: %08x\n",
be32_to_cpu(header->ih_os));
- return false;
+ return -EINVAL;
}
if (header->ih_type != IH_TYPE_KERNEL) {
pr_debug("invalid uImage type: %08x\n",
be32_to_cpu(header->ih_type));
- return false;
+ return -EINVAL;
}
- return true;
+ return 0;
}
static int
@@ -238,9 +251,11 @@ static struct mtd_part_parser uimage_generic_parser = {
#define FW_MAGIC_WNDR3700 0x33373030
#define FW_MAGIC_WNDR3700V2 0x33373031
-static bool uimage_verify_wndr3700(struct uimage_header *header)
+static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len)
{
+ struct uimage_header *header = (struct uimage_header *)buf;
uint8_t expected_type = IH_TYPE_FILESYSTEM;
+
switch be32_to_cpu(header->ih_magic) {
case FW_MAGIC_WNR612V2:
case FW_MAGIC_WNR1000V2:
@@ -254,14 +269,14 @@ static bool uimage_verify_wndr3700(struct uimage_header *header)
expected_type = IH_TYPE_KERNEL;
break;
default:
- return false;
+ return -EINVAL;
}
if (header->ih_os != IH_OS_LINUX ||
header->ih_type != expected_type)
- return false;
+ return -EINVAL;
- return true;
+ return 0;
}
static int