/* * Convert endianess */ void do_endianconvert (void) { char *p = data; union jffs2_node_union *node, newnode; int fd, len; jint32_t mode; uint32_t crc; fd = open (cnvfile, O_WRONLY | O_CREAT, 0644); if (fd < 0) { fprintf (stderr, "Cannot open / create file: %s\n", cnvfile); return; } while ( p < (data + imglen)) { node = (union jffs2_node_union*) p; /* Skip empty space */ if (je16_to_cpu (node->u.magic) == 0xFFFF && je16_to_cpu (node->u.nodetype) == 0xFFFF) { write (fd, p, 4); p += 4; continue; } if (je16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - data, je16_to_cpu (node->u.magic)); newnode.u.magic = cnv_e16 (node->u.magic); newnode.u.nodetype = cnv_e16 (node->u.nodetype); write (fd, &newnode, 4); p += 4; continue; } crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); if (crc != je32_to_cpu (node->u.hdr_crc)) { printf ("Wrong hdr_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, je32_to_cpu (node->u.hdr_crc), crc); } switch(je16_to_cpu(node->u.nodetype)) { case JFFS2_NODETYPE_INODE: newnode.i.magic = cnv_e16 (node->i.magic); newnode.i.nodetype = cnv_e16 (node->i.nodetype); newnode.i.totlen = cnv_e32 (node->i.totlen); newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); newnode.i.ino = cnv_e32 (node->i.ino); newnode.i.version = cnv_e32 (node->i.version); mode.v32 = node->i.mode.m; mode = cnv_e32 (mode); newnode.i.mode.m = mode.v32; newnode.i.uid = cnv_e16 (node->i.uid); newnode.i.gid = cnv_e16 (node->i.gid); newnode.i.isize = cnv_e32 (node->i.isize); newnode.i.atime = cnv_e32 (node->i.atime); newnode.i.mtime = cnv_e32 (node->i.mtime); newnode.i.ctime = cnv_e32 (node->i.ctime); newnode.i.offset = cnv_e32 (node->i.offset); newnode.i.csize = cnv_e32 (node->i.csize); newnode.i.dsize = cnv_e32 (node->i.dsize); newnode.i.compr = node->i.compr; newnode.i.usercompr = node->i.usercompr; newnode.i.flags = cnv_e16 (node->i.flags); if (recalccrc) { len = je32_to_cpu(node->i.csize); newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len)); } else newnode.i.data_crc = cnv_e32 (node->i.data_crc); newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8)); write (fd, &newnode, sizeof (struct jffs2_raw_inode)); write (fd, p + sizeof (struct jffs2_raw_inode), PAD (je32_to_cpu (node->i.totlen) - sizeof (struct jffs2_raw_inode))); p += PAD(je32_to_cpu (node->i.totlen)); break; case JFFS2_NODETYPE_DIRENT: newnode.d.magic = cnv_e16 (node->d.magic); newnode.d.nodetype = cnv_e16 (node->d.nodetype); newnode.d.totlen = cnv_e32 (node->d.totlen); newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); newnode.d.pino = cnv_e32 (node->d.pino); newnode.d.version = cnv_e32 (node->d.version); newnode.d.ino = cnv_e32 (node->d.ino); newnode.d.mctime = cnv_e32 (node->d.mctime); newnode.d.nsize = node->d.nsize; newnode.d.type = node->d.type; newnode.d.unused[0] = node->d.unused[0]; newnode.d.unused[1] = node->d.unused[1]; newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8)); if (recalccrc) newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize)); else newnode.d.name_crc = cnv_e32 (node->d.name_crc); write (fd, &newnode, sizeof (struct jffs2_raw_dirent)); write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (je32_to_cpu (node->d.totlen) - sizeof (struct jffs2_raw_dirent))); p += PAD(je32_to_cpu (node->d.totlen)); break; case JFFS2_NODETYPE_CLEANMARKER: case JFFS2_NODETYPE_PADDING: newnode.u.magic = cnv_e16 (node->u.magic); newnode.u.nodetype = cnv_e16 (node->u.nodetype); newnode.u.totlen = cnv_e32 (node->u.totlen); newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); write (fd, &newnode, sizeof (struct jffs2_unknown_node)); len = PAD(je32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node)); if (len > 0) write (fd, p + sizeof (struct jffs2_unknown_node), len); p += PAD(je32_to_cpu (node->u.totlen)); break; case JFFS2_NODETYPE_SUMMARY : { struct jffs2_sum_marker *sm_ptr; int i,sum_len; int counter = 0; newnode.s.magic = cnv_e16 (node->s.magic); newnode.s.nodetype = cnv_e16 (node->s.nodetype); newnode.s.totlen = cnv_e32 (node->s.totlen); newnode.s.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); newnode.s.sum_num = cnv_e32 (node->s.sum_num); newnode.s.cln_mkr = cnv_e32 (node->s.cln_mkr); newnode.s.padded = cnv_e32 (node->s.padded); newnode.s.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_summary) - 8)); // summary header p += sizeof (struct jffs2_raw_summary); // summary data sum_len = je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary) - sizeof (struct jffs2_sum_marker); for (i=0; i<je32_to_cpu (node->s.sum_num); i++) { union jffs2_sum_flash *fl_ptr; fl_ptr = (union jffs2_sum_flash *) p; switch (je16_to_cpu (fl_ptr->u.nodetype)) { case JFFS2_NODETYPE_INODE: fl_ptr->i.nodetype = cnv_e16 (fl_ptr->i.nodetype); fl_ptr->i.inode = cnv_e32 (fl_ptr->i.inode); fl_ptr->i.version = cnv_e32 (fl_ptr->i.version); fl_ptr->i.offset = cnv_e32 (fl_ptr->i.offset); fl_ptr->i.totlen = cnv_e32 (fl_ptr->i.totlen); p += sizeof (struct jffs2_sum_inode_flash); counter += sizeof (struct jffs2_sum_inode_flash); break; case JFFS2_NODETYPE_DIRENT: fl_ptr->d.nodetype = cnv_e16 (fl_ptr->d.nodetype); fl_ptr->d.totlen = cnv_e32 (fl_ptr->d.totlen); fl_ptr->d.offset = cnv_e32 (fl_ptr->d.offset); fl_ptr->d.pino = cnv_e32 (fl_ptr->d.pino); fl_ptr->d.version = cnv_e32 (fl_ptr->d.version); fl_ptr->d.ino = cnv_e32 (fl_ptr->d.ino); p += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize; counter += sizeof (struct jffs2_sum_dirent_flash) + fl_ptr->d.nsize; break; default : printf("Unknown node in summary information!!! nodetype(%x)\n", je16_to_cpu (fl_ptr->u.nodetype)); exit(EXIT_FAILURE); break; } } //pad p += sum_len - counter; // summary marker sm_ptr = (struct jffs2_sum_marker *) p; sm_ptr->offset = cnv_e32 (sm_ptr->offset); sm_ptr->magic = cnv_e32 (sm_ptr->magic); p += sizeof (struct jffs2_sum_marker); // generate new crc on sum data newnode.s.sum_crc = cpu_to_e32 ( crc32(0, ((char *) node) + sizeof (struct jffs2_raw_summary), je32_to_cpu (node->s.totlen) - sizeof (struct jffs2_raw_summary))); // write out new node header write(fd, &newnode, sizeof (struct jffs2_raw_summary)); // write out new summary data write(fd, &node->s.sum, sum_len + sizeof (struct jffs2_sum_marker)); break; } case 0xffff: write (fd, p, 4); p += 4; break; default: printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", je16_to_cpu (node->u.nodetype), p - data, je32_to_cpu (node->u.totlen)); p += PAD(je32_to_cpu (node->u.totlen)); } } close (fd); }
/* * Convert endianess */ void do_endianconvert (void) { char *p = data; union jffs2_node_union *node, newnode; int fd, len; jint32_t mode; uint32_t crc; fd = open (cnvfile, O_WRONLY | O_CREAT, 0644); if (fd < 0) { fprintf (stderr, "Cannot open / create file: %s\n", cnvfile); return; } while ( p < (data + imglen)) { node = (union jffs2_node_union*) p; /* Skip empty space */ if (de16_to_cpu (node->u.magic) == 0xFFFF && de16_to_cpu (node->u.nodetype) == 0xFFFF) { write (fd, p, 4); p += 4; continue; } if (de16_to_cpu (node->u.magic) != JFFS2_MAGIC_BITMASK) { printf ("Wrong bitmask at 0x%08x, 0x%04x\n", p - data, de16_to_cpu (node->u.magic)); newnode.u.magic = cnv_e16 (node->u.magic); newnode.u.nodetype = cnv_e16 (node->u.nodetype); write (fd, &newnode, 4); p += 4; continue; } crc = crc32 (0, node, sizeof (struct jffs2_unknown_node) - 4); if (crc != de32_to_cpu (node->u.hdr_crc)) { printf ("Wrong hdr_crc at 0x%08x, 0x%08x instead of 0x%08x\n", p - data, de32_to_cpu (node->u.hdr_crc), crc); } switch(de16_to_cpu(node->u.nodetype)) { case JFFS2_NODETYPE_INODE: newnode.i.magic = cnv_e16 (node->i.magic); newnode.i.nodetype = cnv_e16 (node->i.nodetype); newnode.i.totlen = cnv_e32 (node->i.totlen); newnode.i.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); newnode.i.ino = cnv_e32 (node->i.ino); newnode.i.version = cnv_e32 (node->i.version); mode.v32 = node->i.mode.m; mode = cnv_e32 (mode); newnode.i.mode.m = mode.v32; newnode.i.uid = cnv_e16 (node->i.uid); newnode.i.gid = cnv_e16 (node->i.gid); newnode.i.isize = cnv_e32 (node->i.isize); newnode.i.atime = cnv_e32 (node->i.atime); newnode.i.mtime = cnv_e32 (node->i.mtime); newnode.i.ctime = cnv_e32 (node->i.ctime); newnode.i.offset = cnv_e32 (node->i.offset); newnode.i.csize = cnv_e32 (node->i.csize); newnode.i.dsize = cnv_e32 (node->i.dsize); newnode.i.compr = node->i.compr; newnode.i.usercompr = node->i.usercompr; newnode.i.flags = cnv_e16 (node->i.flags); if (recalccrc) { len = de32_to_cpu(node->i.csize); newnode.i.data_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_inode), len)); } else newnode.i.data_crc = cnv_e32 (node->i.data_crc); newnode.i.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_inode) - 8)); write (fd, &newnode, sizeof (struct jffs2_raw_inode)); write (fd, p + sizeof (struct jffs2_raw_inode), PAD (de32_to_cpu (node->i.totlen) - sizeof (struct jffs2_raw_inode))); p += PAD(de32_to_cpu (node->i.totlen)); break; case JFFS2_NODETYPE_DIRENT: newnode.d.magic = cnv_e16 (node->d.magic); newnode.d.nodetype = cnv_e16 (node->d.nodetype); newnode.d.totlen = cnv_e32 (node->d.totlen); newnode.d.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); newnode.d.pino = cnv_e32 (node->d.pino); newnode.d.version = cnv_e32 (node->d.version); newnode.d.ino = cnv_e32 (node->d.ino); newnode.d.mctime = cnv_e32 (node->d.mctime); newnode.d.nsize = node->d.nsize; newnode.d.type = node->d.type; newnode.d.unused[0] = node->d.unused[0]; newnode.d.unused[1] = node->d.unused[1]; newnode.d.node_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_raw_dirent) - 8)); if (recalccrc) newnode.d.name_crc = cpu_to_e32 ( crc32(0, p + sizeof (struct jffs2_raw_dirent), node->d.nsize)); else newnode.d.name_crc = cnv_e32 (node->d.name_crc); write (fd, &newnode, sizeof (struct jffs2_raw_dirent)); write (fd, p + sizeof (struct jffs2_raw_dirent), PAD (de32_to_cpu (node->d.totlen) - sizeof (struct jffs2_raw_dirent))); p += PAD(de32_to_cpu (node->d.totlen)); break; case JFFS2_NODETYPE_CLEANMARKER: case JFFS2_NODETYPE_PADDING: newnode.u.magic = cnv_e16 (node->u.magic); newnode.u.nodetype = cnv_e16 (node->u.nodetype); newnode.u.totlen = cnv_e32 (node->u.totlen); newnode.u.hdr_crc = cpu_to_e32 (crc32 (0, &newnode, sizeof (struct jffs2_unknown_node) - 4)); write (fd, &newnode, sizeof (struct jffs2_unknown_node)); len = PAD(de32_to_cpu (node->u.totlen) - sizeof (struct jffs2_unknown_node)); if (len > 0) write (fd, p + sizeof (struct jffs2_unknown_node), len); p += PAD(de32_to_cpu (node->u.totlen)); break; case 0xffff: write (fd, p, 4); p += 4; break; default: printf ("Unknown node type: 0x%04x at 0x%08x, totlen 0x%08x\n", de16_to_cpu (node->u.nodetype), p - data, de32_to_cpu (node->u.totlen)); p += PAD(de32_to_cpu (node->u.totlen)); } } close (fd); }