cramfs-02-endian.patch 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. --- cramfs-1.1/mkcramfs.c.orig 2005-04-13 05:55:57.000000000 -0600
  2. +++ cramfs-1.1/mkcramfs.c 2005-04-13 16:19:57.000000000 -0600
  3. @@ -117,6 +117,7 @@
  4. static int opt_squash = 0;
  5. static char *opt_image = NULL;
  6. static char *opt_name = NULL;
  7. +static int swap_endian = 0;
  8. static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
  9. static const char *const memory_exhausted = "memory exhausted";
  10. @@ -155,6 +156,8 @@
  11. " -i file insert a file image into the filesystem (requires >= 2.4.0)\n"
  12. " -n name set name of cramfs filesystem\n"
  13. " -p pad by %d bytes for boot code\n"
  14. + " -l litte endian filesystem\n"
  15. + " -b big endian filesystem\n"
  16. " -s sort directory entries (old option, ignored)\n"
  17. " -v be more verbose\n"
  18. " -z make explicit holes (requires >= 2.3.39)\n"
  19. @@ -504,6 +506,50 @@
  20. return totalsize;
  21. }
  22. +/* routines to swap endianness/bitfields in inode/superblock block data */
  23. +static void fix_inode(struct cramfs_inode *inode)
  24. +{
  25. +#define wswap(x) (((x)>>24) | (((x)>>8)&0xff00) | (((x)&0xff00)<<8) | (((x)&0xff)<<24))
  26. + /* attempt #2 */
  27. + inode->mode = (inode->mode >> 8) | ((inode->mode&0xff)<<8);
  28. + inode->uid = (inode->uid >> 8) | ((inode->uid&0xff)<<8);
  29. + inode->size = (inode->size >> 16) | (inode->size&0xff00) |
  30. + ((inode->size&0xff)<<16);
  31. + ((u32*)inode)[2] = wswap(inode->offset | (inode->namelen<<26));
  32. +}
  33. +
  34. +static void fix_offset(struct cramfs_inode *inode, u32 offset)
  35. +{
  36. + u32 tmp = wswap(((u32*)inode)[2]);
  37. + ((u32*)inode)[2] = wswap((offset >> 2) | (tmp&0xfc000000));
  38. +}
  39. +
  40. +static void fix_block_pointer(u32 *p)
  41. +{
  42. + *p = wswap(*p);
  43. +}
  44. +
  45. +static void fix_super(struct cramfs_super *super)
  46. +{
  47. + u32 *p = (u32*)super;
  48. +
  49. + /* fix superblock fields */
  50. + p[0] = wswap(p[0]); /* magic */
  51. + p[1] = wswap(p[1]); /* size */
  52. + p[2] = wswap(p[2]); /* flags */
  53. + p[3] = wswap(p[3]); /* future */
  54. +
  55. + /* fix filesystem info fields */
  56. + p = (u32*)&super->fsid;
  57. + p[0] = wswap(p[0]); /* crc */
  58. + p[1] = wswap(p[1]); /* edition */
  59. + p[2] = wswap(p[2]); /* blocks */
  60. + p[3] = wswap(p[3]); /* files */
  61. +
  62. + fix_inode(&super->root);
  63. +#undef wswap
  64. +}
  65. +
  66. /* Returns sizeof(struct cramfs_super), which includes the root inode. */
  67. static unsigned int write_superblock(struct entry *root, char *base, int size)
  68. {
  69. @@ -539,6 +585,7 @@
  70. super->root.gid = root->gid;
  71. super->root.size = root->size;
  72. super->root.offset = offset >> 2;
  73. + if (swap_endian) fix_super(super);
  74. return offset;
  75. }
  76. @@ -553,7 +600,10 @@
  77. if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
  78. error_msg_and_die("filesystem too big");
  79. }
  80. - inode->offset = (offset >> 2);
  81. + if (swap_endian)
  82. + fix_offset(inode, offset);
  83. + else
  84. + inode->offset = (offset >> 2);
  85. }
  86. /*
  87. @@ -638,6 +688,7 @@
  88. stack_entries++;
  89. }
  90. entry = entry->next;
  91. + if (swap_endian) fix_inode(inode);
  92. }
  93. /*
  94. @@ -734,6 +785,7 @@
  95. }
  96. *(u32 *) (base + offset) = curr;
  97. + if (swap_endian) fix_block_pointer((u32*)(base + offset));
  98. offset += 4;
  99. } while (size);
  100. @@ -1146,7 +1198,7 @@
  101. progname = argv[0];
  102. /* command line options */
  103. - while ((c = getopt(argc, argv, "hEe:i:n:psvzD:q")) != EOF) {
  104. + while ((c = getopt(argc, argv, "hEe:i:n:psvzD:qlb")) != EOF) {
  105. switch (c) {
  106. case 'h':
  107. usage(MKFS_OK);
  108. @@ -1174,6 +1227,18 @@
  109. opt_pad = PAD_SIZE;
  110. fslen_ub += PAD_SIZE;
  111. break;
  112. + case 'b':
  113. +#if __BYTE_ORDER == __LITTLE_ENDIAN
  114. + swap_endian = 1;
  115. + printf("Swapping filesystem endian-ness\n");
  116. +#endif
  117. + break;
  118. + case 'l':
  119. +#if __BYTE_ORDER == __BIG_ENDIAN
  120. + swap_endian = 1;
  121. + printf("Swapping filesystem endian-ness\n");
  122. +#endif
  123. + break;
  124. case 's':
  125. /* old option, ignored */
  126. break;
  127. --- cramfs-1.1/cramfsck.c.orig 2005-04-25 11:50:31.000000000 -0700
  128. +++ cramfs-1.1/cramfsck.c 2005-04-25 16:53:25.000000000 -0700
  129. @@ -30,6 +30,7 @@
  130. * 2000/07/15: Daniel Quinlan (initial support for block devices)
  131. * 2002/01/10: Daniel Quinlan (additional checks, test more return codes,
  132. * use read if mmap fails, standardize messages)
  133. + * 2004/09/01: Alfonso Acosta (Add swapping support)
  134. */
  135. /* compile-time options */
  136. @@ -51,6 +52,7 @@
  137. #include <utime.h>
  138. #include <sys/ioctl.h>
  139. #define _LINUX_STRING_H_
  140. +#include <byteswap.h>
  141. #include "linux/cramfs_fs.h"
  142. #include <zlib.h>
  143. @@ -74,6 +76,7 @@
  144. static char *filename; /* ROM image filename */
  145. struct cramfs_super super; /* just find the cramfs superblock once */
  146. static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */
  147. +static int need_swapping = 0; /* fs and host dont have the same endianness */
  148. #ifdef INCLUDE_FS_TESTS
  149. static int opt_extract = 0; /* extract cramfs (-x) */
  150. static char *extract_dir = "/"; /* extraction directory (-x) */
  151. @@ -85,6 +88,9 @@
  152. static unsigned long start_data = ~0UL; /* start of the data (256 MB = max) */
  153. static unsigned long end_data = 0; /* end of the data */
  154. +/* access 32 byte variables */
  155. +#define CRAMFS_32(x) (need_swapping ? bswap_32(x) : x)
  156. +
  157. /* Guarantee access to at least 8kB at a time */
  158. #define ROMBUFFER_BITS 13
  159. #define ROMBUFFERSIZE (1 << ROMBUFFER_BITS)
  160. @@ -166,20 +172,34 @@
  161. if (super.magic == CRAMFS_MAGIC) {
  162. *start = 0;
  163. }
  164. + else if (super.magic == bswap_32(CRAMFS_MAGIC)) {
  165. + *start = 0;
  166. + need_swapping = 1;
  167. + }
  168. +
  169. else if (*length >= (PAD_SIZE + sizeof(super))) {
  170. lseek(fd, PAD_SIZE, SEEK_SET);
  171. if (read(fd, &super, sizeof(super)) != sizeof(super)) {
  172. die(FSCK_ERROR, 1, "read failed: %s", filename);
  173. }
  174. - if (super.magic == CRAMFS_MAGIC) {
  175. + if (super.magic == CRAMFS_32(CRAMFS_MAGIC)) {
  176. *start = PAD_SIZE;
  177. }
  178. }
  179. /* superblock tests */
  180. - if (super.magic != CRAMFS_MAGIC) {
  181. + if (super.magic != CRAMFS_32(CRAMFS_MAGIC)) {
  182. die(FSCK_UNCORRECTED, 0, "superblock magic not found");
  183. }
  184. + if (need_swapping){
  185. + super.size = bswap_32(super.size);
  186. + super.flags = bswap_32(super.flags);
  187. + super.future = bswap_32(super.future);
  188. + super.fsid.crc = bswap_32(super.fsid.crc);
  189. + super.fsid.edition = bswap_32(super.fsid.edition);
  190. + super.fsid.blocks = bswap_32(super.fsid.blocks);
  191. + super.fsid.files = bswap_32(super.fsid.files);
  192. + }
  193. if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
  194. die(FSCK_ERROR, 0, "unsupported filesystem features");
  195. }
  196. @@ -215,7 +235,10 @@
  197. die(FSCK_USAGE, 0, "unable to test CRC: old cramfs format");
  198. #endif /* not INCLUDE_FS_TESTS */
  199. }
  200. -
  201. + else if (need_swapping) {
  202. + /* crc checking in this case would mean translating the whole file */
  203. + return;
  204. + }
  205. crc = crc32(0L, Z_NULL, 0);
  206. buf = mmap(NULL, super.size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  207. @@ -300,12 +323,23 @@
  208. static struct cramfs_inode *cramfs_iget(struct cramfs_inode * i)
  209. {
  210. +#define wswap(x) (((x)>>24) | (((x)>>8)&0xff00) | (((x)&0xff00)<<8) | (((x)&0xff)<<24))
  211. struct cramfs_inode *inode = malloc(sizeof(struct cramfs_inode));
  212. if (!inode) {
  213. die(FSCK_ERROR, 1, "malloc failed");
  214. }
  215. - *inode = *i;
  216. + if(!need_swapping) {
  217. + *inode = *i;
  218. + }
  219. + else {
  220. + inode->mode=bswap_16(i->mode);
  221. + inode->uid=bswap_16(i->uid);
  222. + inode->size=bswap_32(i->size << 8);
  223. + inode->gid=i->gid;
  224. + inode->namelen = bswap_32(((u32*)i)[2]) >> 26;
  225. + inode->offset = bswap_32(((u32*)i)[2]) & 0x3FFFFFFF;
  226. + }
  227. return inode;
  228. }
  229. @@ -324,9 +358,9 @@
  230. */
  231. static struct cramfs_inode *read_super(void)
  232. {
  233. - unsigned long offset = super.root.offset << 2;
  234. -
  235. - if (!S_ISDIR(super.root.mode))
  236. + struct cramfs_inode *root = cramfs_iget(&super.root);
  237. + unsigned long offset = root->offset << 2;
  238. + if (!S_ISDIR(root->mode))
  239. die(FSCK_UNCORRECTED, 0, "root inode is not directory");
  240. if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
  241. ((offset != sizeof(struct cramfs_super)) &&
  242. @@ -334,7 +368,7 @@
  243. {
  244. die(FSCK_UNCORRECTED, 0, "bad root offset (%lu)", offset);
  245. }
  246. - return cramfs_iget(&super.root);
  247. + return root;
  248. }
  249. static int uncompress_block(void *src, int len)
  250. @@ -366,7 +400,7 @@
  251. do {
  252. unsigned long out = PAGE_CACHE_SIZE;
  253. - unsigned long next = *(u32 *) romfs_read(offset);
  254. + unsigned long next = CRAMFS_32(*(u32 *) romfs_read(offset));
  255. if (next > end_data) {
  256. end_data = next;
  257. @@ -529,7 +563,7 @@
  258. {
  259. unsigned long offset = i->offset << 2;
  260. unsigned long curr = offset + 4;
  261. - unsigned long next = *(u32 *) romfs_read(offset);
  262. + unsigned long next = CRAMFS_32(*(u32 *) romfs_read(offset));
  263. unsigned long size;
  264. if (offset == 0) {