From: Imre Kaloz Date: Sun, 29 Jun 2014 13:03:55 +0000 (+0000) Subject: handle the dual-firmware layout on the WRT1900AC X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=974f13988c64ed1d47f3905288e265fdd21fafe2;p=openwrt%2Fstaging%2Fnbd.git handle the dual-firmware layout on the WRT1900AC Signed-off-by: Imre Kaloz SVN-Revision: 41384 --- diff --git a/target/linux/mvebu/patches-3.14/100-find_active_root.patch b/target/linux/mvebu/patches-3.14/100-find_active_root.patch new file mode 100644 index 0000000000..45fa5756c6 --- /dev/null +++ b/target/linux/mvebu/patches-3.14/100-find_active_root.patch @@ -0,0 +1,153 @@ +The WRT1900AC among other Linksys routers uses a dual-firmware layout. +The bootloader passes the active rootfs in bootargs and also sets the +rootfstype to jffs2 - which is clearly something we don't want. + +Rename both root= and rootfstype= variables to avoid issues and also +use the former to dynamically rename the active partition to "ubi". + + +Signed-off-by: Imre Kaloz + +--- a/arch/arm/boot/compressed/atags_to_fdt.c ++++ b/arch/arm/boot/compressed/atags_to_fdt.c +@@ -64,6 +64,18 @@ static uint32_t get_cell_size(const void + return cell_size; + } + ++static void mangle_bootargs(void *fdt, const char *fdt_cmdline) ++{ ++ char *rootdev; ++ char *rootfs; ++ ++ rootdev = strstr(fdt_cmdline, "root=/dev/mtdblock"); ++ strncpy(rootdev, "uboot_active_root=", 18); ++ ++ rootfs = strstr(fdt_cmdline, "rootfstype"); ++ strncpy(rootfs, "origfstype", 10); ++} ++ + static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline) + { + char cmdline[COMMAND_LINE_SIZE]; +@@ -133,6 +145,9 @@ int atags_to_fdt(void *atag_list, void * + + for_each_tag(atag, atag_list) { + if (atag->hdr.tag == ATAG_CMDLINE) { ++ /* Rename the original root= and rootfstype= options */ ++ mangle_bootargs(fdt, ++ atag->u.cmdline.cmdline); + /* Append the ATAGS command line to the device tree + * command line. + * NB: This means that if the same parameter is set in +--- a/arch/arm/boot/compressed/string.c ++++ b/arch/arm/boot/compressed/string.c +@@ -111,6 +111,53 @@ char *strchr(const char *s, int c) + return (char *)s; + } + ++/** ++ * strncpy - Copy a length-limited, %NUL-terminated string ++ * @dest: Where to copy the string to ++ * @src: Where to copy the string from ++ * @count: The maximum number of bytes to copy ++ * ++ * The result is not %NUL-terminated if the source exceeds ++ * @count bytes. ++ * ++ * In the case where the length of @src is less than that of ++ * count, the remainder of @dest will be padded with %NUL. ++ * ++ */ ++char *strncpy(char *dest, const char *src, size_t count) ++{ ++ char *tmp = dest; ++ ++ while (count) { ++ if ((*tmp = *src) != 0) ++ src++; ++ tmp++; ++ count--; ++ } ++ return dest; ++} ++ ++/** ++ * strstr - Find the first substring in a %NUL terminated string ++ * @s1: The string to be searched ++ * @s2: The string to search for ++ */ ++char *strstr(const char *s1, const char *s2) ++{ ++ size_t l1, l2; ++ ++ l2 = strlen(s2); ++ if (!l2) ++ return (char *)s1; ++ l1 = strlen(s1); ++ while (l1 >= l2) { ++ l1--; ++ if (!memcmp(s1, s2, l2)) ++ return (char *)s1; ++ s1++; ++ } ++ return NULL; ++} + #undef memset + + void *memset(void *s, int c, size_t count) +--- a/drivers/mtd/ofpart.c ++++ b/drivers/mtd/ofpart.c +@@ -25,12 +25,15 @@ static bool node_has_compatible(struct d + return of_get_property(pp, "compatible", NULL); + } + ++static int uboot_active_root; ++ + static int parse_ofpart_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) + { + struct device_node *node; + const char *partname; ++ const char *owrtpart = "ubi"; + struct device_node *pp; + int nr_parts, i; + +@@ -78,9 +81,15 @@ static int parse_ofpart_partitions(struc + (*pparts)[i].offset = of_read_number(reg, a_cells); + (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); + +- partname = of_get_property(pp, "label", &len); +- if (!partname) +- partname = of_get_property(pp, "name", &len); ++ if (uboot_active_root && (i == uboot_active_root)) { ++ partname = owrtpart; ++ } else { ++ partname = of_get_property(pp, "label", &len); ++ ++ if (!partname) ++ partname = of_get_property(pp, "name", &len); ++ } ++ + (*pparts)[i].name = partname; + + if (of_get_property(pp, "read-only", &len)) +@@ -178,6 +187,18 @@ static int __init ofpart_parser_init(voi + return 0; + } + ++static int __init active_root(char *str) ++{ ++ get_option(&str, &uboot_active_root); ++ ++ if (!uboot_active_root) ++ return 1; ++ ++ return 1; ++} ++ ++__setup("uboot_active_root=", active_root); ++ + static void __exit ofpart_parser_exit(void) + { + deregister_mtd_parser(&ofpart_parser);