2 * buildimage - create Dreambox nand boot image.
4 * contains algorithms ripped from u-boot and first-stage.
12 #include <netinet/in.h>
14 int eraseblock_size, spare_size, sector_size, largepage;
16 #define SECTOR_SIZE_WITH_ECC (sector_size+spare_size)
20 * Pre-calculated 256-way 1 byte column parity
22 static const unsigned char nand_ecc_precalc_table[] = {
23 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
24 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
25 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
26 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
27 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
28 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
29 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
30 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
31 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
32 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
33 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
34 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
35 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
36 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
37 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
38 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
43 * Creates non-inverted ECC code from line parity
45 static void nand_trans_result(unsigned char reg2, unsigned char reg3,
46 unsigned char *ecc_code)
48 unsigned char a, b, i, tmp1, tmp2;
50 /* Initialize variables */
54 /* Calculate first ECC byte */
55 for (i = 0; i < 4; i++) {
56 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
59 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
65 /* Calculate second ECC byte */
67 for (i = 0; i < 4; i++) {
68 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
71 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
77 /* Store two of the ECC bytes */
83 * Calculate 3 byte ECC code for 256 byte block
85 static void nand_calculate_ecc (const unsigned char *dat, unsigned char *ecc_code)
87 unsigned char idx, reg1, reg3;
90 /* Initialize variables */
92 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
94 /* Build up column parity */
95 for(j = 0; j < 256; j++) {
97 /* Get CP0 - CP5 from table */
98 idx = nand_ecc_precalc_table[dat[j]];
101 /* All bit XOR = 1 ? */
103 reg3 ^= (unsigned char) j;
107 /* Create non-inverted ECC code from line parity */
108 nand_trans_result((reg1 & 0x40) ? ~reg3 : reg3, reg3, ecc_code);
110 /* Calculate final ECC code */
111 ecc_code[0] = ~ecc_code[0];
112 ecc_code[1] = ~ecc_code[1];
113 ecc_code[2] = ((~reg1) << 2) | 0x03;
116 void file_open(FILE **f, int *size, const char *filename)
118 *f = fopen(filename, "r");
124 fseek(*f, 0, SEEK_END);
126 fseek(*f, 0, SEEK_SET);
129 void die(const char *msg)
131 fprintf(stderr, "%s\n", msg);
135 void emit_4(unsigned long val)
141 #define TO_SECT(x) (x+sector_size-1)/sector_size
143 typedef void fnc_encode_ecc(unsigned char *dst, unsigned char *src, int cnt);
145 void encode_hevers(unsigned char *dst, unsigned char *src, int count)
150 dst[1] = count & 0xFF;
153 for(cnt=0; cnt<sector_size; cnt++)
161 if(cnt & 2) dst[6 + 2]^=temp;
162 if(cnt & 4) dst[6 + 3]^=temp;
163 if(cnt & 8) dst[6 + 4]^=temp;
164 if(cnt & 16) dst[6 + 5]^=temp;
165 if(cnt & 32) dst[6 + 6]^=temp;
166 if(cnt & 64) dst[6 + 7]^=temp;
167 if(cnt & 128) dst[6 + 8]^=temp;
168 if(cnt & 256) dst[6 + 9]^=temp;
175 dst[3] = count & 0xFF;
178 for(cnt=0; cnt<sector_size; cnt++)
186 if(cnt & 2) dst[43]^=temp;
187 if(cnt & 4) dst[44]^=temp;
188 if(cnt & 8) dst[45]^=temp;
189 if(cnt & 16) dst[46]^=temp;
190 if(cnt & 32) dst[47]^=temp;
191 if(cnt & 64) dst[48]^=temp;
192 if(cnt & 128) dst[49]^=temp;
193 if(cnt & 256) dst[50]^=temp;
198 void encode_jffs2(unsigned char *dst, unsigned char *src, int cnt)
200 memset(dst, 0xFF, spare_size);
204 unsigned char ecc_code[8];
205 nand_calculate_ecc (src, ecc_code);
206 nand_calculate_ecc (src+256, ecc_code+3);
207 dst[0] = ecc_code[0];
208 dst[1] = ecc_code[1];
209 dst[2] = ecc_code[2];
210 dst[3] = ecc_code[3];
213 dst[6] = ecc_code[4];
214 dst[7] = ecc_code[5];
216 if (!(cnt & ((eraseblock_size/sector_size)-1)))
227 memset(dst + 8, 0xFF, 8);
232 nand_calculate_ecc (src + i * 256, dst + 40 + i * 3);
234 if (!(cnt & ((eraseblock_size/sector_size)-1)))
248 void emit_file(FILE *src, int size, fnc_encode_ecc * eccfnc)
250 emit_4(size * SECTOR_SIZE_WITH_ECC);
254 unsigned char sector[sector_size + spare_size];
255 memset(sector, 0xFF, sector_size + spare_size);
256 int r = fread(sector, 1, sector_size, src);
259 eccfnc(sector + sector_size, sector, cnt);
260 write(1, sector, SECTOR_SIZE_WITH_ECC);
267 /* reserve to two sectors plus 1% for badblocks, and round down */
268 #define BADBLOCK_SAFE(x) ( ((x) - (eraseblock_size * 2) - (x) / 100) &~ eraseblock_size )
270 int main(int argc, char **argv)
272 if ((argc != 4) && (argc != 5) && (argc != 6) && (argc != 7) )
274 fprintf(stderr, "usage: %s <2nd.bin.gz> <boot.jffs2> <root.jffs2> [<arch>] [<flashsize-in-mb>] [options]> image.nfi\n", *argv);
278 FILE *f_2nd, *f_boot, *f_root;
279 int size_2nd, size_boot, size_root;
281 file_open(&f_2nd, &size_2nd, argv[1]);
282 file_open(&f_boot, &size_boot, argv[2]);
283 file_open(&f_root, &size_root, argv[3]);
285 int flashsize = 32*1024*1024;
287 flashsize = atoi(argv[5]) * 1024 * 1024;
290 int partition[] = {0x40000, 0x400000, flashsize};
292 if ((argc >= 7) && strstr(argv[6], "large"))
295 eraseblock_size = 128*1024;
298 partition[0] = 0x100000;
302 eraseblock_size = 16384;
305 partition[0] = 0x40000;
308 if (size_2nd > BADBLOCK_SAFE(partition[0]))
309 die("2nd stage is too big. did you gzip it before?");
310 if (size_boot > BADBLOCK_SAFE(partition[1] - partition[0]))
311 die("boot is too big. You can modify the buildimage tool, but you don't want that.");
312 if (size_root > BADBLOCK_SAFE(partition[2] - partition[1]))
313 die("root is too big. This doesn't work. sorry.");
315 int sectors_2nd = TO_SECT(size_2nd), sectors_boot = TO_SECT(size_boot), sectors_root = TO_SECT(size_root);
317 int num_partitions = 3;
319 int total_size = 4 + num_partitions * 4 + 4 + sectors_2nd * SECTOR_SIZE_WITH_ECC + 4 + sectors_boot * SECTOR_SIZE_WITH_ECC + 4 + sectors_root * SECTOR_SIZE_WITH_ECC;
321 /* in case an architecture is given, write NFI1 header */
324 char header[32] = "NFI1";
325 strncpy(header + 4, argv[4], 28);
326 write(1, header, 32);
333 emit_4(num_partitions * 4);
335 for (i=0; i < num_partitions; ++i)
336 emit_4(partition[i]);
339 emit_file(f_2nd, sectors_2nd, encode_hevers);
341 emit_file(f_boot, sectors_boot, encode_jffs2);
342 emit_file(f_root, sectors_root, encode_jffs2);