diff options
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.patch | 354 |
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 @@ | |||
1 | This patch adds support for 'dynamic partitions'. This basically | ||
2 | works 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 | |||
9 | Please note that currently the desired partition sizes are stored at compile-time | ||
10 | in an array in drivers/nand/nand_bbt.c, so this definitely needs to change before | ||
11 | submitting/merging upstream. | ||
12 | |||
13 | In order to calculate the partiton map (and set mtdparts accordingly), you can use | ||
14 | the 'dynpart' command at the prompt. Use 'saveenv' to make the setting permanent. | ||
15 | |||
16 | Signed-off-by: Harald Welte <laforge@openmoko.org> | ||
17 | |||
18 | Index: 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 | ||
109 | Index: 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 */ | ||
149 | Index: 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 | /***************************************************/ | ||
224 | Index: 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)) { | ||
285 | Index: 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 | } | ||
298 | Index: 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 */ | ||
310 | Index: 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 | + | ||
324 | Index: 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 | + | ||
343 | Index: 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 */ | ||