annotate mpffs/common.c @ 29:e96d6862cec0

mpffs-rdutils code started
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 30 Jun 2013 05:16:23 +0000
parents
children 9c3c5a572b57
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
1 /*
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
2 * This module contains the code that will be common between mpffs-cat,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
3 * mpffs-ls and mpffs-xtr.
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
4 */
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
5
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
6 #include <sys/types.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
7 #include <sys/file.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
8 #include <sys/stat.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
9 #include <endian.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
10 #include <ctype.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
11 #include <stdio.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
12 #include <string.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
13 #include <strings.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
14 #include <stdlib.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
15 #include <unistd.h>
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
16 #include "types.h"
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
17 #include "struct.h"
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
18
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
19 u8 mpffs_header[6] = {'F', 'f', 's', '#', 0x10, 0x02};
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
20
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
21 char *imgfile;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
22 u32 eraseblk_size;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
23 int total_blocks;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
24 u32 total_ffs_size;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
25 u8 *image, *indexblk;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
26 int index_blk_num, root_node_no;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
27 int verbose;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
28
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
29 /*
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
30 * The following function is used to verify that the specified or computed
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
31 * flash erase block size is a power of 2.
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
32 */
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
33 count_ones(word)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
34 u32 word;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
35 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
36 int count;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
37
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
38 for (count = 0; word; word >>= 1)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
39 count += word & 1;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
40 return count;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
41 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
42
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
43 eraseblk_size_reasonable()
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
44 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
45 if (count_ones(eraseblk_size) != 1 || eraseblk_size < 16384) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
46 fprintf(stderr, "0x%lx is an unreasonable erase block size\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
47 (u_long) eraseblk_size);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
48 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
49 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
50 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
51
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
52 read_img_file()
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
53 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
54 int fd;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
55 struct stat st;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
56
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
57 fd = open(imgfile, O_RDONLY);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
58 if (fd < 0) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
59 perror(imgfile);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
60 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
61 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
62 fstat(fd, &st);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
63 if (!S_ISREG(st.st_mode)) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
64 fprintf(stderr, "%s is not a regular file\n", imgfile);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
65 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
66 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
67 if (!eraseblk_size && !total_blocks) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
68 switch (st.st_size) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
69 case 0x70000:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
70 /* assume Closedmoko */
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
71 eraseblk_size = 0x10000;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
72 total_blocks = 7;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
73 break;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
74 case 0x480000:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
75 /* assume Pirelli */
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
76 eraseblk_size = 0x40000;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
77 total_blocks = 18;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
78 break;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
79 default:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
80 noauto: fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
81 "cannot intuit the flash parameters of %s: use -e and -n options\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
82 imgfile);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
83 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
84 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
85 } else if (!total_blocks) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
86 total_blocks = st.st_size / eraseblk_size;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
87 if (!total_blocks || total_blocks * eraseblk_size != st.st_size)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
88 goto noauto;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
89 } else if (!eraseblk_size) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
90 if (total_blocks * 0x10000 == st.st_size)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
91 eraseblk_size = 0x10000;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
92 else if (total_blocks * 0x40000 == st.st_size)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
93 eraseblk_size = 0x40000;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
94 else
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
95 goto noauto;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
96 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
97 total_ffs_size = eraseblk_size * total_blocks;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
98 if (st.st_size < total_ffs_size) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
99 fprintf(stderr, "%s has fewer than 0x%x bytes\n", imgfile,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
100 total_ffs_size);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
101 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
102 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
103 image = malloc(total_ffs_size);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
104 if (!image) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
105 perror("malloc");
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
106 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
107 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
108 read(fd, image, total_ffs_size);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
109 close(fd);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
110 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
111
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
112 find_index_block()
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
113 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
114 int i, abcnt;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
115 u8 *ptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
116
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
117 if (index_blk_num) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
118 if (index_blk_num < 0 || index_blk_num >= total_blocks) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
119 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
120 "invalid block # given with the -a option\n");
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
121 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
122 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
123 ptr = image + index_blk_num * eraseblk_size;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
124 if (bcmp(ptr, mpffs_header, 6) || ptr[8] != 0xAB) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
125 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
126 "no MPFFS index found at the specified block #%d\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
127 index_blk_num);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
128 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
129 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
130 indexblk = ptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
131 return(0);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
132 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
133 abcnt = 0;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
134 for (ptr = image, i = 0; i < total_blocks; i++, ptr += eraseblk_size) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
135 if (bcmp(ptr, mpffs_header, 6)) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
136 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
137 "warning: no MPFFS signature in erase block #%d (offset %x)\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
138 i, ptr - image);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
139 continue;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
140 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
141 switch (ptr[8]) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
142 case 0xAB:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
143 if (verbose)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
144 printf(
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
145 "Found AB index in erase block #%d (offset %x)\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
146 i, ptr - image);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
147 index_blk_num = i;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
148 indexblk = ptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
149 abcnt++;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
150 continue;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
151 case 0xBD:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
152 case 0xBF:
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
153 continue;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
154 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
155 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
156 "warning: non-understood block type %02X at offset %x\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
157 ptr[8], ptr - image);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
158 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
159 if (!indexblk) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
160 fprintf(stderr, "could not find an MPFFS index block in %s\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
161 imgfile);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
162 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
163 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
164 if (abcnt > 1) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
165 fprintf(stderr, "found more than one AB block; use -a\n");
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
166 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
167 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
168 return(0);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
169 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
170
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
171 get_index_entry(oi)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
172 struct objinfo *oi;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
173 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
174 struct mpffs_index *le;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
175
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
176 if (oi->entryno >= (eraseblk_size >> 4)) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
177 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
178 "error: index block pointer %x past the erase block size!\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
179 oi->entryno);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
180 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
181 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
182 le = (struct mpffs_index *) indexblk + oi->entryno;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
183 oi->idxrec = le;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
184 oi->len = le16toh(le->len);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
185 oi->type = le->type;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
186 oi->descend = le16toh(le->descend);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
187 oi->sibling = le16toh(le->sibling);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
188 return(0);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
189 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
190
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
191 validate_chunk(oi)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
192 struct objinfo *oi;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
193 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
194 u32 dptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
195
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
196 if (oi->len & 0xF || !oi->len) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
197 fprintf(stderr, "index entry #%x: invalid chunk length\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
198 oi->entryno);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
199 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
200 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
201 dptr = le32toh(oi->idxrec->dataptr);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
202 if (dptr > 0x0FFFFFFF) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
203 invdptr: fprintf(stderr, "index entry #%x: invalid data pointer\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
204 oi->entryno);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
205 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
206 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
207 dptr <<= 4;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
208 if (dptr >= total_img_size - oi->len)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
209 goto invdptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
210 oi->offset = dptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
211 oi->dataptr = image + dptr;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
212 return(0);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
213 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
214
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
215 validate_obj_name(oi)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
216 struct objinfo *oi;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
217 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
218 u8 *cp;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
219 int cnt;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
220
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
221 for (cp = oi->dataptr, cnt = 0; ; cp++, cnt++) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
222 if (cnt >= oi->len) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
223 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
224 "object at index %x: name expected at %x: length overrun\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
225 oi->entryno, oi->offset);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
226 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
227 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
228 if (!*cp)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
229 break;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
230 if (*cp < '!' || *cp > '~') {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
231 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
232 "object at index %x: name expected at %x: bad character\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
233 oi->entryno, oi->offset);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
234 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
235 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
236 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
237 if (!cnt) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
238 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
239 "object at index %x: name expected at %x: null string\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
240 oi->entryno, oi->offset);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
241 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
242 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
243 return(0);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
244 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
245
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
246 u8 *
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
247 find_end_of_chunk(ch)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
248 struct objinfo *ch;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
249 {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
250 u8 *p;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
251 int i;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
252
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
253 p = ch->dataptr + ch->len;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
254 for (i = 1; i <= 16; i++) {
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
255 if (!p[-i])
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
256 return(p - i);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
257 if (p[-1] != 0xFF)
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
258 break;
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
259 }
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
260 fprintf(stderr,
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
261 "chunk starting at %x (index entry %x): no valid termination found\n",
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
262 ch->offset, ch->entryno);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
263 exit(1);
e96d6862cec0 mpffs-rdutils code started
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff changeset
264 }