aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/lantiq
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2016-05-02 18:50:23 +0000
committerLuka Perkov <luka@openwrt.org>2016-06-19 19:18:29 +0200
commitb55c724fd64f72d896d5faa5a6dccf502928bdd6 (patch)
treeb872591d4387ab0e97b6b0db315960c00ec20b1a /target/linux/lantiq
parent2b17907b3e51572432e908cfad7ba9631cf448c4 (diff)
downloadmaster-187ad058-b55c724fd64f72d896d5faa5a6dccf502928bdd6.tar.gz
master-187ad058-b55c724fd64f72d896d5faa5a6dccf502928bdd6.tar.bz2
master-187ad058-b55c724fd64f72d896d5faa5a6dccf502928bdd6.zip
lantiq: handle the dual-firmware layout of brnboot
brnboot based devices can have two Image partitions. When flashing images via the brnboot recovery web interface, the Image partitions are written alternating. The current active Image partition is stored in the first byte of the Primary_Setting partition by using 0x00 for Code_Image_0 and 0x01 for Code_Image_1. By using the information about the active "Code Image", it is possible to ensure that the rootfs belongs to the current booted Image/Kernel. Signed-off-by: Mathias Kresin <openwrt@kresin.me> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@49281 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/lantiq')
-rw-r--r--target/linux/lantiq/patches-4.4/0101-find_active_root.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches-4.4/0101-find_active_root.patch b/target/linux/lantiq/patches-4.4/0101-find_active_root.patch
new file mode 100644
index 0000000000..978def35e6
--- /dev/null
+++ b/target/linux/lantiq/patches-4.4/0101-find_active_root.patch
@@ -0,0 +1,93 @@
+--- a/drivers/mtd/ofpart.c
++++ b/drivers/mtd/ofpart.c
+@@ -25,6 +25,38 @@ static bool node_has_compatible(struct d
+ return of_get_property(pp, "compatible", NULL);
+ }
+
++static uint8_t * brnboot_get_selected_root_part(struct mtd_info *master,
++ loff_t offset)
++{
++ static uint8_t root_id;
++ int err, len;
++
++ err = mtd_read(master, offset, 0x01, &len, &root_id);
++
++ if (mtd_is_bitflip(err) || !err)
++ return &root_id;
++
++ return NULL;
++}
++
++static void brnboot_set_active_root_part(struct mtd_partition *pparts,
++ struct device_node **part_nodes,
++ int nr_parts,
++ uint8_t *root_id)
++{
++ int i;
++
++ for (i = 0; i < nr_parts; i++) {
++ int part_root_id;
++
++ if (!of_property_read_u32(part_nodes[i], "brnboot,root-id", &part_root_id)
++ && part_root_id == *root_id) {
++ pparts[i].name = "firmware";
++ break;
++ }
++ }
++}
++
+ static int parse_ofpart_partitions(struct mtd_info *master,
+ struct mtd_partition **pparts,
+ struct mtd_part_parser_data *data)
+@@ -35,7 +67,8 @@ static int parse_ofpart_partitions(struc
+ struct device_node *pp;
+ int nr_parts, i, ret = 0;
+ bool dedicated = true;
+-
++ uint8_t *proot_id = NULL;
++ struct device_node **part_nodes;
+
+ if (!data)
+ return 0;
+@@ -73,7 +106,9 @@ static int parse_ofpart_partitions(struc
+ return 0;
+
+ *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL);
+- if (!*pparts)
++ part_nodes = kzalloc(nr_parts * sizeof(*part_nodes), GFP_KERNEL);
++
++ if (!*pparts || !part_nodes)
+ return -ENOMEM;
+
+ i = 0;
+@@ -121,12 +156,22 @@ static int parse_ofpart_partitions(struc
+ if (of_get_property(pp, "lock", &len))
+ (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK;
+
++ if (!proot_id && of_device_is_compatible(pp, "brnboot,root-selector"))
++ proot_id = brnboot_get_selected_root_part(master, (*pparts)[i].offset);
++
++ part_nodes[i] = pp;
++
+ i++;
+ }
+
+ if (!nr_parts)
+ goto ofpart_none;
+
++ if (proot_id)
++ brnboot_set_active_root_part(*pparts, part_nodes, nr_parts, proot_id);
++
++ kfree(part_nodes);
++
+ return nr_parts;
+
+ ofpart_fail:
+@@ -136,6 +181,7 @@ ofpart_fail:
+ ofpart_none:
+ of_node_put(pp);
+ kfree(*pparts);
++ kfree(part_nodes);
+ *pparts = NULL;
+ return ret;
+ }