mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-19 13:48:06 +00:00
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:
parent
5ab5bacda2
commit
ed39f7ec1a
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user