aboutsummaryrefslogtreecommitdiffstats
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
commit1aed104c80567a88bf408401a1cb58309cebbe8a (patch)
tree5e9e44350b961cf7313a2b72cf135e48869cfd65
parent1f3cdb86343af98e662553dce048789baae26ba0 (diff)
downloadupstream-1aed104c80567a88bf408401a1cb58309cebbe8a.tar.gz
upstream-1aed104c80567a88bf408401a1cb58309cebbe8a.tar.bz2
upstream-1aed104c80567a88bf408401a1cb58309cebbe8a.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> SVN-Revision: 44412
-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