summaryrefslogtreecommitdiffstats
path: root/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch')
-rw-r--r--meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch354
1 files changed, 354 insertions, 0 deletions
diff --git a/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch
new file mode 100644
index 0000000000..ecce004ca6
--- /dev/null
+++ b/meta/packages/uboot/u-boot-mkimage-openmoko-native/nand-dynamic_partitions.patch
@@ -0,0 +1,354 @@
1This patch adds support for 'dynamic partitions'. This basically
2works as follows:
3* The nand code generates a bad-block-table at the first scan of the chip
4* The dynamic partition code calculates the raw partition sizes based on
5 the bad block table. E.g. if you have a partition of size 0x30000, and there are
6 two bad blocks (0x4000 each) in it, the raw size will increase to 0x38000, and the
7 following partitions get shifted towards the end of flash.
8
9Please note that currently the desired partition sizes are stored at compile-time
10in an array in drivers/nand/nand_bbt.c, so this definitely needs to change before
11submitting/merging upstream.
12
13In order to calculate the partiton map (and set mtdparts accordingly), you can use
14the 'dynpart' command at the prompt. Use 'saveenv' to make the setting permanent.
15
16Signed-off-by: Harald Welte <laforge@openmoko.org>
17
18Index: u-boot/drivers/nand/nand_bbt.c
19===================================================================
20--- u-boot.orig/drivers/nand/nand_bbt.c
21+++ u-boot/drivers/nand/nand_bbt.c
22@@ -1044,9 +1044,86 @@
23 switch ((int)res) {
24 case 0x00: return 0;
25 case 0x01: return 1;
26+ case 0x03: return 1;
27 case 0x02: return allowbbt ? 0 : 1;
28 }
29 return 1;
30 }
31
32+#if defined(CONFIG_NAND_DYNPART)
33+
34+extern unsigned int dynpart_size[];
35+extern char *dynpart_names[];
36+
37+#define MTDPARTS_MAX_SIZE 512
38+
39+
40+static int skip_offs(const struct nand_chip *this, unsigned int offs)
41+{
42+ int block = (int) (offs >> (this->bbt_erase_shift - 1));
43+ u_int8_t bbt = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
44+
45+ return bbt == 3;
46+}
47+
48+int nand_create_mtd_dynpart(struct mtd_info *mtd)
49+{
50+ struct nand_chip *this = mtd->priv;
51+ int part;
52+ char *mtdparts;
53+ unsigned int cur_offs = 0;
54+
55+ mtdparts = malloc(MTDPARTS_MAX_SIZE); /* FIXME: bounds checking */
56+ if (!mtdparts)
57+ return -ENOMEM;
58+
59+ sprintf(mtdparts, "mtdparts=" CFG_NAND_DYNPART_MTD_KERNEL_NAME ":");
60+
61+ for (part = 0; dynpart_size[part] != 0; part++) {
62+ unsigned int bb_delta = 0;
63+ unsigned int offs = 0;
64+ char mtdpart[32];
65+
66+ for (offs = cur_offs;
67+ offs < cur_offs + dynpart_size[part] + bb_delta;
68+ offs += mtd->erasesize) {
69+ if (skip_offs(this, offs))
70+ bb_delta += mtd->erasesize;
71+ }
72+
73+ /*
74+ * Absorb bad blocks immediately following this partition also
75+ * into the partition, in order to make next partition start
76+ * with a good block. This simplifies handling of the
77+ * environment partition.
78+ */
79+ while (offs < this->chipsize && skip_offs(this, offs)) {
80+ bb_delta += mtd->erasesize;
81+ offs += mtd->erasesize;
82+ }
83+
84+ if (cur_offs + dynpart_size[part] + bb_delta > this->chipsize)
85+ dynpart_size[part] = this->chipsize - cur_offs - bb_delta;
86+#if 0
87+ printf("partition %u: start = 0x%08x, end=%08x size=%08x, size_inc_bb=%08x\n",
88+ part, cur_offs, cur_offs + dynpart_size[part] + bb_delta,
89+ dynpart_size[part], dynpart_size[part] + bb_delta);
90+#endif
91+ cur_offs += dynpart_size[part] + bb_delta;
92+ sprintf(mtdpart, "0x%.8x(%.16s),", dynpart_size[part] + bb_delta,
93+ dynpart_names[part]);
94+ mtdpart[sizeof(mtdpart)-1] = '\0';
95+ strncat(mtdparts, mtdpart,
96+ MTDPARTS_MAX_SIZE-strlen(mtdparts)-1);
97+ }
98+
99+ mtdparts[strlen(mtdparts)-1] = '\0';
100+ printf("mtdparts %s\n", mtdparts);
101+ setenv("mtdparts", mtdparts);
102+
103+ free(mtdparts);
104+ return 0;
105+}
106+#endif /* CONFIG_NAND_DYNPART */
107+
108 #endif
109Index: u-boot/include/configs/neo1973_gta01.h
110===================================================================
111--- u-boot.orig/include/configs/neo1973_gta01.h
112+++ u-boot/include/configs/neo1973_gta01.h
113@@ -99,7 +99,7 @@
114 CFG_CMD_ELF | \
115 CFG_CMD_MISC | \
116 /* CFG_CMD_USB | */ \
117- /* CFG_CMD_JFFS2 | */ \
118+ CFG_CMD_JFFS2 | \
119 CFG_CMD_DIAG | \
120 /* CFG_CMD_HWFLOW | */ \
121 CFG_CMD_SAVES | \
122@@ -212,13 +212,13 @@
123 #define CONFIG_FAT 1
124 #define CONFIG_SUPPORT_VFAT
125
126-#if 0
127+#if 1
128 /* JFFS2 driver */
129 #define CONFIG_JFFS2_CMDLINE 1
130 #define CONFIG_JFFS2_NAND 1
131 #define CONFIG_JFFS2_NAND_DEV 0
132-#define CONFIG_JFFS2_NAND_OFF 0x634000
133-#define CONFIG_JFFS2_NAND_SIZE 0x39cc000
134+//#define CONFIG_JFFS2_NAND_OFF 0x634000
135+//#define CONFIG_JFFS2_NAND_SIZE 0x39cc000
136 #endif
137
138 /* ATAG configuration */
139@@ -257,4 +257,9 @@
140
141 #define CONFIG_DRIVER_PCF50606 1
142
143+#define MTDIDS_DEFAULT "nand0=neo1973-nand"
144+#define MTPARTS_DEFAULT "neo1973-nand:256k(u-boot),16k(u-boot_env),2M(kernel),640k(splash),-(jffs2)"
145+#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "neo1973-nand"
146+#define CONFIG_NAND_DYNPART
147+
148 #endif /* __CONFIG_H */
149Index: u-boot/common/cmd_jffs2.c
150===================================================================
151--- u-boot.orig/common/cmd_jffs2.c
152+++ u-boot/common/cmd_jffs2.c
153@@ -1841,6 +1841,29 @@
154 return NULL;
155 }
156
157+/* Return the 'net size' of the partition (i.e. excluding any bad blocks) */
158+unsigned int nand_net_part_size(struct part_info *part)
159+{
160+ struct mtd_info *mtd;
161+ unsigned int offs;
162+ unsigned int bb_delta = 0;
163+
164+ if (!part || !part->dev || !part->dev->id ||
165+ part->dev->id->num >= CFG_MAX_NAND_DEVICE)
166+ return 0;
167+
168+ mtd = &nand_info[part->dev->id->num];
169+
170+ for (offs = part->offset; offs < part->offset + part->size;
171+ offs += mtd->erasesize) {
172+ if (nand_isbad_bbt(mtd, offs, 0))
173+ bb_delta += mtd->erasesize;
174+ }
175+
176+ return part->size - bb_delta;
177+}
178+
179+
180 /***************************************************/
181 /* U-boot commands */
182 /***************************************************/
183@@ -2132,6 +2155,24 @@
184 printf ("Usage:\n%s\n", cmdtp->usage);
185 return 1;
186 }
187+
188+#if defined(CONFIG_NAND_DYNPART)
189+extern int nand_create_mtd_dynpart(struct mtd_info *mtd);
190+
191+int do_dynpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
192+{
193+#if 0
194+ int i = simple_strtoul(argv[1], NULL, 0);
195+ if (i >= CFG_MAX_NAND_DEVICE)
196+ return -EINVAL;
197+#endif
198+ nand_create_mtd_dynpart(&nand_info[0]);
199+
200+ return 0;
201+}
202+#endif /* CONFIG_NAND_DYNPART */
203+
204+
205 #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
206
207 /***************************************************/
208@@ -2197,6 +2238,15 @@
209 "<name> := '(' NAME ')'\n"
210 "<ro-flag> := when set to 'ro' makes partition read-only (not used, passed to kernel)\n"
211 );
212+
213+#if defined(CONFIG_NAND_DYNPART)
214+U_BOOT_CMD(
215+ dynpart, 1, 1, do_dynpart,
216+ "dynpart\t- dynamically calculate partition table based on BBT\n",
217+ "\n"
218+ " - sets 'mtdparts' according to BBT\n");
219+#endif /* CONFIG_NAND_DYNPART */
220+
221 #endif /* #ifdef CONFIG_JFFS2_CMDLINE */
222
223 /***************************************************/
224Index: u-boot/common/cmd_nand.c
225===================================================================
226--- u-boot.orig/common/cmd_nand.c
227+++ u-boot/common/cmd_nand.c
228@@ -101,7 +101,7 @@
229 }
230
231 int
232-arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
233+arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size, int net)
234 {
235 int idx = nand_curr_device;
236 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
237@@ -122,10 +122,17 @@
238 printf("'%s' is not a number\n", argv[1]);
239 return -1;
240 }
241- if (*size > part->size)
242- *size = part->size;
243+ if (*size > part->size) {
244+ if (net)
245+ *size = nand_net_part_size(part);
246+ else
247+ *size = part->size;
248+ }
249 } else {
250- *size = part->size;
251+ if (net)
252+ *size = nand_net_part_size(part);
253+ else
254+ *size = part->size;
255 }
256 idx = dev->id->num;
257 *nand = nand_info[idx];
258@@ -261,7 +268,7 @@
259
260 printf("\nNAND %s: ", scrub ? "scrub" : "erase");
261 /* skip first two or three arguments, look for offset and size */
262- if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
263+ if (arg_off_size(argc - o, argv + o, nand, &off, &size, 0) != 0)
264 return 1;
265
266 memset(&opts, 0, sizeof(opts));
267@@ -323,7 +330,7 @@
268
269 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
270 printf("\nNAND %s: ", read ? "read" : "write");
271- if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
272+ if (arg_off_size(argc - 3, argv + 3, nand, &off, &size, 1) != 0)
273 return 1;
274
275 s = strchr(cmd, '.');
276@@ -445,7 +452,7 @@
277 }
278
279 if (strcmp(cmd, "unlock") == 0) {
280- if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
281+ if (arg_off_size(argc - 2, argv + 2, nand, &off, &size, 0) < 0)
282 return 1;
283
284 if (!nand_unlock(nand, off, size)) {
285Index: u-boot/common/cmd_dynenv.c
286===================================================================
287--- u-boot.orig/common/cmd_dynenv.c
288+++ u-boot/common/cmd_dynenv.c
289@@ -60,7 +60,7 @@
290 buf[2] = 'V';
291 buf[3] = '0';
292
293- if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy) < 0) {
294+ if (arg_off_size(argc-2, argv+2, mtd, &addr, &dummy, 1) < 0) {
295 printf("Offset or partition name expected\n");
296 goto fail;
297 }
298Index: u-boot/include/util.h
299===================================================================
300--- u-boot.orig/include/util.h
301+++ u-boot/include/util.h
302@@ -28,6 +28,6 @@
303
304 /* common/cmd_nand.c */
305 int arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off,
306- ulong *size);
307+ ulong *size, int net);
308
309 #endif /* UTIL_H */
310Index: u-boot/board/qt2410/qt2410.c
311===================================================================
312--- u-boot.orig/board/qt2410/qt2410.c
313+++ u-boot/board/qt2410/qt2410.c
314@@ -126,3 +126,9 @@
315
316 return 0;
317 }
318+
319+unsigned int dynpart_size[] = {
320+ CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
321+char *dynpart_names[] = {
322+ "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
323+
324Index: u-boot/board/neo1973/gta01/gta01.c
325===================================================================
326--- u-boot.orig/board/neo1973/gta01/gta01.c
327+++ u-boot/board/neo1973/gta01/gta01.c
328@@ -429,3 +434,14 @@
329 return 0;
330 }
331
332+
333+/* The sum of all part_size[]s must equal to the NAND size, i.e., 0x4000000.
334+ "initrd" is sized such that it can hold two uncompressed 16 bit 640*480
335+ images: 640*480*2*2 = 1228800 < 1245184. */
336+
337+unsigned int dynpart_size[] = {
338+ CFG_UBOOT_SIZE, 0x4000, 0x200000, 0xa0000, 0x3d5c000-CFG_UBOOT_SIZE, 0 };
339+char *dynpart_names[] = {
340+ "u-boot", "u-boot_env", "kernel", "splash", "rootfs", NULL };
341+
342+
343Index: u-boot/include/configs/qt2410.h
344===================================================================
345--- u-boot.orig/include/configs/qt2410.h
346+++ u-boot/include/configs/qt2410.h
347@@ -283,5 +283,7 @@
348
349 #define MTDIDS_DEFAULT "nand0=qt2410-nand"
350 #define MTPARTS_DEFAULT "qt2410-nand:192k(u-boot),8k(u-boot_env),2M(kernel),2M(splash),-(jffs2)"
351+#define CFG_NAND_DYNPART_MTD_KERNEL_NAME "qt2410-nand"
352+#define CONFIG_NAND_DYNPART
353
354 #endif /* __CONFIG_H */