comparison mpffs/common.c @ 30:9c3c5a572b57

mpffs-ls works with the length code stubbed out
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Jun 2013 06:28:58 +0000
parents e96d6862cec0
children 3cca8070ef0f
comparison
equal deleted inserted replaced
29:e96d6862cec0 30:9c3c5a572b57
15 #include <unistd.h> 15 #include <unistd.h>
16 #include "types.h" 16 #include "types.h"
17 #include "struct.h" 17 #include "struct.h"
18 18
19 u8 mpffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02}; 19 u8 mpffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02};
20 u8 blank_flash_line[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
21 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
20 22
21 char *imgfile; 23 char *imgfile;
22 u32 eraseblk_size; 24 u32 eraseblk_size;
23 int total_blocks; 25 int total_blocks;
24 u32 total_ffs_size; 26 u32 total_ffs_size;
25 u8 *image, *indexblk; 27 u8 *image, *indexblk;
26 int index_blk_num, root_node_no; 28 int index_blk_num = -1, root_node_no;
29 struct objinfo root;
27 int verbose; 30 int verbose;
28 31
29 /* 32 /*
30 * The following function is used to verify that the specified or computed 33 * The following function is used to verify that the specified or computed
31 * flash erase block size is a power of 2. 34 * flash erase block size is a power of 2.
40 return count; 43 return count;
41 } 44 }
42 45
43 eraseblk_size_reasonable() 46 eraseblk_size_reasonable()
44 { 47 {
45 if (count_ones(eraseblk_size) != 1 || eraseblk_size < 16384) { 48 if (count_ones(eraseblk_size) != 1 || eraseblk_size < 16384 ||
49 eraseblk_size > 0x100000) {
46 fprintf(stderr, "0x%lx is an unreasonable erase block size\n", 50 fprintf(stderr, "0x%lx is an unreasonable erase block size\n",
47 (u_long) eraseblk_size); 51 (u_long) eraseblk_size);
48 exit(1); 52 exit(1);
49 } 53 }
54 }
55
56 parse_cmdline_options(argc, argv)
57 char **argv;
58 {
59 extern char *optarg;
60 int c;
61
62 while ((c = getopt(argc, argv, "a:e:mn:pr:v")) != EOF)
63 switch (c) {
64 case 'a':
65 index_blk_num = atoi(optarg);
66 continue;
67 case 'e':
68 eraseblk_size = strtoul(optarg, 0, 0);
69 eraseblk_size_reasonable();
70 continue;
71 case 'm': /* "moko" */
72 eraseblk_size = 0x10000;
73 total_blocks = 7;
74 continue;
75 case 'n':
76 total_blocks = atoi(optarg);
77 if (total_blocks < 1) {
78 fprintf(stderr, "invalid -n value\n");
79 exit(1);
80 }
81 continue;
82 case 'p': /* Pirelli */
83 eraseblk_size = 0x40000;
84 total_blocks = 18;
85 continue;
86 case 'r':
87 root_node_no = atoi(optarg);
88 continue;
89 case 'v':
90 verbose++;
91 continue;
92 default:
93 usage();
94 exit(1);
95 }
96
97 return(0);
50 } 98 }
51 99
52 read_img_file() 100 read_img_file()
53 { 101 {
54 int fd; 102 int fd;
112 find_index_block() 160 find_index_block()
113 { 161 {
114 int i, abcnt; 162 int i, abcnt;
115 u8 *ptr; 163 u8 *ptr;
116 164
117 if (index_blk_num) { 165 if (index_blk_num >= 0) {
118 if (index_blk_num < 0 || index_blk_num >= total_blocks) { 166 if (index_blk_num >= total_blocks) {
119 fprintf(stderr, 167 fprintf(stderr,
120 "invalid block # given with the -a option\n"); 168 "invalid block # given with the -a option\n");
121 exit(1); 169 exit(1);
122 } 170 }
123 ptr = image + index_blk_num * eraseblk_size; 171 ptr = image + index_blk_num * eraseblk_size;
203 invdptr: fprintf(stderr, "index entry #%x: invalid data pointer\n", 251 invdptr: fprintf(stderr, "index entry #%x: invalid data pointer\n",
204 oi->entryno); 252 oi->entryno);
205 exit(1); 253 exit(1);
206 } 254 }
207 dptr <<= 4; 255 dptr <<= 4;
208 if (dptr >= total_img_size - oi->len) 256 if (dptr > total_ffs_size - oi->len)
209 goto invdptr; 257 goto invdptr;
210 oi->offset = dptr; 258 oi->offset = dptr;
211 oi->dataptr = image + dptr; 259 oi->dataptr = image + dptr;
212 return(0); 260 return(0);
213 } 261 }
260 fprintf(stderr, 308 fprintf(stderr,
261 "chunk starting at %x (index entry %x): no valid termination found\n", 309 "chunk starting at %x (index entry %x): no valid termination found\n",
262 ch->offset, ch->entryno); 310 ch->offset, ch->entryno);
263 exit(1); 311 exit(1);
264 } 312 }
313
314 find_root_node()
315 {
316 struct objinfo obj;
317 u16 lim;
318
319 lim = (eraseblk_size >> 4) - 1;
320 if (root_node_no) {
321 if (root_node_no < 1 || root_node_no > lim) {
322 fprintf(stderr,
323 "root node # given with -r is invalid\n");
324 exit(1);
325 }
326 return(1);
327 }
328 for (obj.entryno = 1; obj.entryno <= lim; obj.entryno++) {
329 get_index_entry(&obj);
330 if (!bcmp(obj.idxrec, blank_flash_line, 16))
331 break;
332 if (obj.type != 0xF2)
333 continue;
334 validate_chunk(&obj);
335 validate_obj_name(&obj);
336 if (*obj.dataptr != '/')
337 continue;
338 root_node_no = obj.entryno;
339 if (verbose)
340 printf("Found root node at index #%x\n", root_node_no);
341 return(0);
342 }
343 fprintf(stderr, "error: no root node found (try -r)\n");
344 exit(1);
345 }
346
347 validate_root_node()
348 {
349 root.entryno = root_node_no;
350 get_index_entry(&root);
351 validate_chunk(&root);
352 validate_obj_name(&root);
353 if (verbose)
354 printf("Root node name: %s\n", (char *)root.dataptr);
355 if (root.type != 0xF2) {
356 fprintf(stderr,
357 "error: index entry #%x (expected root dir) is not a directory\n",
358 root_node_no);
359 exit(1);
360 }
361 if (root.sibling != 0xFFFF)
362 fprintf(stderr,
363 "warning: root entry has a non-nil sibling pointer\n");
364 return(0);
365 }
366
367 preliminaries()
368 {
369 read_img_file();
370 find_index_block();
371 find_root_node();
372 validate_root_node();
373 }