cramfs-01-endian.patch 8.3 KB

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