From: charles Date: Wed, 16 Jul 2003 03:00:48 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: https://yaffs.net/gitweb/?p=yaffs%2F.git;a=commitdiff_plain;h=ce026971bc840746fbea0c681a8af4ad7282575c *** empty log message *** --- diff --git a/utils/mkyaffsimage.c b/utils/mkyaffsimage.c index 814e2af..c21c631 100644 --- a/utils/mkyaffsimage.c +++ b/utils/mkyaffsimage.c @@ -17,6 +17,9 @@ * * Nick Bane modifications flagged NCB * + * Endian handling patches by James Ng. + * + * */ #include @@ -33,7 +36,7 @@ #define MAX_OBJECTS 10000 -const char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.6 2002-12-13 00:13:06 charles Exp $"; +const char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.7 2003-07-16 03:00:48 charles Exp $"; // External functions for ECC on data void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); @@ -58,6 +61,7 @@ static int outFile; static int error; +static int convert_endian = 0; static int obj_compare(const void *a, const void * b) { @@ -147,7 +151,17 @@ static void yaffs_CalcTagsECC(yaffs_Tags *tags) unsigned ecc = 0; unsigned bit = 0; - tags->ecc = 0; + // Clear ECC fields + if (!convert_endian) + { + tags->ecc = 0; + } + else + { + // Because we're in "munged tag" mode, we have to clear it manually + b[6] &= 0xC0; + b[7] &= 0x03; + } for(i = 0; i < 8; i++) { @@ -162,9 +176,17 @@ static void yaffs_CalcTagsECC(yaffs_Tags *tags) } } - tags->ecc = ecc; - - + // Write out ECC + if (!convert_endian) + { + tags->ecc = ecc; + } + else + { + // We have to munge the ECC again. + b[6] |= ((ecc >> 6) & 0x3F); + b[7] |= ((ecc & 0x3F) << 2); + } } static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr) { @@ -182,7 +204,36 @@ static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr) sparePtr->tagByte7 = tu->asBytes[7]; } - +/* This little function converts a little endian tag to a big endian tag. + * NOTE: The tag is not usable after this other than calculating the CRC + * with. + */ +static void little_to_big_endian(yaffs_Tags *tagsPtr) +{ + yaffs_TagsUnion * tags = (yaffs_TagsUnion* )tagsPtr; // Work in bytes. + yaffs_TagsUnion temp; + + memset(&temp, 0, sizeof(temp)); + // Ick, I hate magic numbers. + temp.asBytes[0] = ((tags->asBytes[2] & 0x0F) << 4) | ((tags->asBytes[1] & 0xF0) >> 4); + temp.asBytes[1] = ((tags->asBytes[1] & 0x0F) << 4) | ((tags->asBytes[0] & 0xF0) >> 4); + temp.asBytes[2] = ((tags->asBytes[0] & 0x0F) << 4) | ((tags->asBytes[2] & 0x30) >> 2) | ((tags->asBytes[3] & 0xC0) >> 6); + temp.asBytes[3] = ((tags->asBytes[3] & 0x3F) << 2) | ((tags->asBytes[2] & 0xC0) >> 6); + temp.asBytes[4] = ((tags->asBytes[6] & 0x03) << 6) | ((tags->asBytes[5] & 0xFC) >> 2); + temp.asBytes[5] = ((tags->asBytes[5] & 0x03) << 6) | ((tags->asBytes[4] & 0xFC) >> 2); + temp.asBytes[6] = ((tags->asBytes[4] & 0x03) << 6) | (tags->asBytes[7] & 0x3F); + temp.asBytes[7] = (tags->asBytes[6] & 0xFC) | ((tags->asBytes[7] & 0xC0) >> 6); + + // Now copy it back. + tags->asBytes[0] = temp.asBytes[0]; + tags->asBytes[1] = temp.asBytes[1]; + tags->asBytes[2] = temp.asBytes[2]; + tags->asBytes[3] = temp.asBytes[3]; + tags->asBytes[4] = temp.asBytes[4]; + tags->asBytes[5] = temp.asBytes[5]; + tags->asBytes[6] = temp.asBytes[6]; + tags->asBytes[7] = temp.asBytes[7]; +} static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) { @@ -199,6 +250,11 @@ static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) t.serialNumber = 0; t.byteCount = nBytes; t.objectId = objId; + + if (convert_endian) + { + little_to_big_endian(&t); + } yaffs_CalcTagsECC(&t); yaffs_LoadTagsIntoSpare(&s,&t); @@ -210,6 +266,72 @@ static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) } +#define SWAP32(x) ((((x) & 0x000000FF) << 24) | \ + (((x) & 0x0000FF00) << 8 ) | \ + (((x) & 0x00FF0000) >> 8 ) | \ + (((x) & 0xFF000000) >> 24)) + +#define SWAP16(x) ((((x) & 0x00FF) << 8) | \ + (((x) & 0xFF00) >> 8)) + +// This one is easier, since the types are more standard. No funky shifts here. +static void object_header_little_to_big_endian(yaffs_ObjectHeader* oh) +{ + oh->type = SWAP32(oh->type); // GCC makes enums 32 bits. + oh->parentObjectId = SWAP32(oh->parentObjectId); // int + oh->sum__NoLongerUsed = SWAP16(oh->sum__NoLongerUsed); // __u16 - Not used, but done for completeness. + // name = skip. Char array. Not swapped. + oh->st_mode = SWAP32(oh->st_mode); +#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case. + // In fact, WinCE would be *THE* place where this would be an issue! + oh->notForWinCE[0] = SWAP32(oh->notForWinCE[0]); + oh->notForWinCE[1] = SWAP32(oh->notForWinCE[1]); + oh->notForWinCE[2] = SWAP32(oh->notForWinCE[2]); + oh->notForWinCE[3] = SWAP32(oh->notForWinCE[3]); + oh->notForWinCE[4] = SWAP32(oh->notForWinCE[4]); +#else + // Regular POSIX. + oh->st_uid = SWAP32(oh->st_uid); + oh->st_gid = SWAP32(oh->st_gid); + oh->st_atime = SWAP32(oh->st_atime); + oh->st_mtime = SWAP32(oh->st_mtime); + oh->st_ctime = SWAP32(oh->st_ctime); +#endif + + oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that! + oh->equivalentObjectId = SWAP32(oh->equivalentObjectId); + // alias - char array. + oh->st_rdev = SWAP32(oh->st_rdev); + +#ifdef CONFIG_YAFFS_WINCE + oh->win_ctime[0] = SWAP32(oh->win_ctime[0]); + oh->win_ctime[1] = SWAP32(oh->win_ctime[1]); + oh->win_atime[0] = SWAP32(oh->win_atime[0]); + oh->win_atime[1] = SWAP32(oh->win_atime[1]); + oh->win_mtime[0] = SWAP32(oh->win_mtime[0]); + oh->win_mtime[1] = SWAP32(oh->win_mtime[1]); + oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); + oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); + oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); + oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); + oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); + oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); +#else + oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); + oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); + oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); + oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); + oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); + oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); + oh->roomToGrow[6] = SWAP32(oh->roomToGrow[6]); + oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]); + oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]); + oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]); + oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]); + oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]); +#endif +} + static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias) { __u8 bytes[512]; @@ -252,6 +374,11 @@ static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, in { strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH); } + + if (convert_endian) + { + object_header_little_to_big_endian(oh); + } return write_chunk(bytes,objId,0,0xffff); @@ -409,14 +536,20 @@ int main(int argc, char *argv[]) printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n"); - if(argc != 3) + if(argc <= 3) { - printf("usage: mkyaffsimage dir image_file\n"); + printf("usage: mkyaffsimage dir image_file [convert]\n"); printf(" dir the directory tree to be converted\n"); printf(" image_file the output file to hold the image\n"); + printf(" 'convert' produce a big-endian image from a little-endian machine\n"); exit(1); } + if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert")))) + { + convert_endian = 1; + } + if(stat(argv[1],&stats) < 0) { printf("Could not stat %s\n",argv[1]);