Root/target/linux/lantiq/patches-3.3/0019-owrt-mtd-split.patch

1From 2a295753a10823a47542c779a25bbb1f52c71281 Mon Sep 17 00:00:00 2001
2From: John Crispin <blogic@openwrt.org>
3Date: Fri, 3 Aug 2012 10:27:13 +0200
4Subject: [PATCH 19/25] owrt mtd split
5
6---
7 .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 1 +
8 arch/mips/lantiq/setup.c | 7 +
9 drivers/mtd/Kconfig | 4 +
10 drivers/mtd/mtdpart.c | 173 +++++++++++++++++++-
11 4 files changed, 184 insertions(+), 1 deletions(-)
12
13diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
14index 1ec8f2a..1ff93cc 100644
15--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
16+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
17@@ -166,6 +166,7 @@ extern unsigned char ltq_boot_select(void);
18 
19 extern __iomem void *ltq_ebu_membase;
20 extern __iomem void *ltq_cgu_membase;
21+extern unsigned long ltq_brn_boot;
22 
23 static inline int ltq_is_ase(void)
24 {
25diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c
26index 1ff6c9d..708e969 100644
27--- a/arch/mips/lantiq/setup.c
28+++ b/arch/mips/lantiq/setup.c
29@@ -18,6 +18,9 @@
30 #include "devices.h"
31 #include "prom.h"
32 
33+/* set to 1 if the bootloader is BRN-BOOT instead of u-boot */
34+unsigned long ltq_brn_boot = 0;
35+
36 void __init plat_mem_setup(void)
37 {
38     /* assume 16M as default incase uboot fails to pass proper ramsize */
39@@ -38,6 +41,10 @@ void __init plat_mem_setup(void)
40             if (strict_strtoul(e, 0, &memsize))
41                 pr_warn("bad memsize specified\n");
42         }
43+ if (!strncmp(e, "BRN-BOOT", 8)){
44+ pr_info("Found BRN-BOOT instead of u-boot\n");
45+ ltq_brn_boot = 1;
46+ }
47         envp++;
48     }
49     memsize *= 1024 * 1024;
50diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
51index 982a98b..e2f3f3e 100644
52--- a/drivers/mtd/Kconfig
53+++ b/drivers/mtd/Kconfig
54@@ -31,6 +31,10 @@ config MTD_ROOTFS_SPLIT
55     bool "Automatically split 'rootfs' partition for squashfs"
56     default y
57 
58+config MTD_UIMAGE_SPLIT
59+ bool "Automatically split 'linux' partition into 'kernel' and 'rootfs'"
60+ default y
61+
62 config MTD_REDBOOT_PARTS
63     tristate "RedBoot partition table parsing"
64     ---help---
65diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
66index 855b70b..93711e2 100644
67--- a/drivers/mtd/mtdpart.c
68+++ b/drivers/mtd/mtdpart.c
69@@ -867,6 +867,168 @@ static int refresh_rootfs_split(struct mtd_info *mtd)
70 }
71 #endif /* CONFIG_MTD_ROOTFS_SPLIT */
72 
73+#ifdef CONFIG_MTD_UIMAGE_SPLIT
74+static unsigned long find_uimage_size(struct mtd_info *mtd,
75+ unsigned long offset)
76+{
77+#define UBOOT_MAGIC 0x56190527
78+ unsigned long magic = 0;
79+ unsigned long temp;
80+ size_t len;
81+ int ret;
82+
83+ ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
84+ if (ret || len != sizeof(magic))
85+ return 0;
86+
87+ if (le32_to_cpu(magic) != UBOOT_MAGIC)
88+ return 0;
89+
90+ ret = mtd->read(mtd, offset + 12, 4, &len, (void *)&temp);
91+ if (ret || len != sizeof(temp))
92+ return 0;
93+
94+ return temp + 0x40;
95+}
96+
97+static unsigned long find_eva_size(struct mtd_info *mtd,
98+ unsigned long offset)
99+{
100+#define EVA_MAGIC 0xfeed1281
101+ unsigned long magic = 0;
102+ unsigned long temp;
103+ size_t len;
104+ int ret;
105+
106+ ret = mtd->read(mtd, offset, 4, &len, (void *)&magic);
107+ if (ret || len != sizeof(magic))
108+ return 0;
109+
110+ if (le32_to_cpu(magic) != EVA_MAGIC)
111+ return 0;
112+
113+ ret = mtd->read(mtd, offset + 4, 4, &len, (void *)&temp);
114+ if (ret || len != sizeof(temp))
115+ return 0;
116+
117+ /* add eva header size */
118+ temp = le32_to_cpu(temp) + 0x18;
119+
120+ temp &= ~0xffff;
121+ temp += 0x10000;
122+ return temp;
123+}
124+
125+static int detect_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
126+{
127+ unsigned long temp;
128+ size_t len;
129+ int ret;
130+
131+ ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
132+ if (ret || len != sizeof(temp))
133+ return 0;
134+
135+
136+ return le32_to_cpu(temp) == SQUASHFS_MAGIC;
137+}
138+
139+static int detect_eva_squashfs_partition(struct mtd_info *mtd, unsigned long offset)
140+{
141+ unsigned long temp;
142+ size_t len;
143+ int ret;
144+
145+ ret = mtd->read(mtd, offset, 4, &len, (void *)&temp);
146+ if (ret || len != sizeof(temp))
147+ return 0;
148+
149+ return be32_to_cpu(temp) == SQUASHFS_MAGIC;
150+}
151+
152+static unsigned long find_brnimage_size(struct mtd_info *mtd,
153+ unsigned long offset)
154+{
155+ unsigned long buf[4];
156+ // Assume at most 2MB of kernel image
157+ unsigned long end = offset + (2 << 20);
158+ unsigned long ptr = offset + 0x400 - 12;
159+ size_t len;
160+ int ret;
161+
162+ while (ptr < end) {
163+ long size_min = ptr - 0x400 - 12 - offset;
164+ long size_max = ptr + 12 - offset;
165+ ret = mtd->read(mtd, ptr, 16, &len, (void *)buf);
166+ if (ret || len != 16)
167+ return 0;
168+
169+ if (le32_to_cpu(buf[0]) < size_min ||
170+ le32_to_cpu(buf[0]) > size_max) {
171+ ptr += 0x400;
172+ continue;
173+ }
174+
175+ if (le32_to_cpu(buf[3]) == SQUASHFS_MAGIC)
176+ return ptr + 12 - offset;
177+
178+ ptr += 0x400;
179+ }
180+
181+ return 0;
182+}
183+
184+static int split_uimage(struct mtd_info *mtd,
185+ const struct mtd_partition *part)
186+{
187+ static struct mtd_partition split_partitions[] = {
188+ {
189+ .name = "kernel",
190+ .offset = 0x0,
191+ .size = 0x0,
192+ }, {
193+ .name = "rootfs",
194+ .offset = 0x0,
195+ .size = 0x0,
196+ },
197+ };
198+
199+ split_partitions[0].size = find_uimage_size(mtd, part->offset);
200+ if (!split_partitions[0].size) {
201+ split_partitions[0].size = find_eva_size(mtd, part->offset);
202+ if (!split_partitions[0].size) {
203+ split_partitions[0].size = find_brnimage_size(mtd, part->offset);
204+ if (!split_partitions[0].size) {
205+ printk(KERN_NOTICE "no uImage or brnImage or eva found in linux partition\n");
206+ return -1;
207+ }
208+ }
209+ }
210+
211+ if (detect_eva_squashfs_partition(mtd,
212+ part->offset
213+ + split_partitions[0].size)) {
214+ split_partitions[0].size += 0x100;
215+ pr_info("found eva dummy squashfs behind kernel\n");
216+ } else if (!detect_squashfs_partition(mtd,
217+ part->offset
218+ + split_partitions[0].size)) {
219+ split_partitions[0].size &= ~(mtd->erasesize - 1);
220+ split_partitions[0].size += mtd->erasesize;
221+ } else {
222+ pr_info("found squashfs behind kernel\n");
223+ }
224+
225+ split_partitions[0].offset = part->offset;
226+ split_partitions[1].offset = part->offset + split_partitions[0].size;
227+ split_partitions[1].size = part->size - split_partitions[0].size;
228+
229+ add_mtd_partitions(mtd, split_partitions, 2);
230+
231+ return 0;
232+}
233+#endif
234+
235 /*
236  * This function, given a master MTD object and a partition table, creates
237  * and registers slave MTD objects which are bound to the master according to
238@@ -883,7 +1045,7 @@ int add_mtd_partitions(struct mtd_info *master,
239     struct mtd_part *slave;
240     uint64_t cur_offset = 0;
241     int i;
242-#ifdef CONFIG_MTD_ROOTFS_SPLIT
243+#if defined(CONFIG_MTD_ROOTFS_SPLIT) || defined(CONFIG_MTD_UIMAGE_SPLIT)
244     int ret;
245 #endif
246 
247@@ -900,6 +1062,15 @@ int add_mtd_partitions(struct mtd_info *master,
248 
249         add_mtd_device(&slave->mtd);
250 
251+#ifdef CONFIG_MTD_UIMAGE_SPLIT
252+ if (!strcmp(parts[i].name, "linux")) {
253+ ret = split_uimage(master, &parts[i]);
254+
255+ if (ret)
256+ printk(KERN_WARNING "Can't split linux partition\n");
257+ }
258+#endif
259+
260         if (!strcmp(parts[i].name, "rootfs")) {
261 #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
262             if (ROOT_DEV == 0) {
263--
2641.7.9.1
265
266

Archive Download this file



interactive