do_mounts_rd.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. #include <linux/kernel.h>
  2. #include <linux/fs.h>
  3. #include <linux/minix_fs.h>
  4. #include <linux/ext2_fs.h>
  5. #include <linux/romfs_fs.h>
  6. #include <linux/cramfs_fs.h>
  7. #include <linux/initrd.h>
  8. #include <linux/string.h>
  9. #include "do_mounts.h"
  10. #define BUILD_CRAMDISK
  11. int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */
  12. static int __init prompt_ramdisk(char *str)
  13. {
  14. rd_prompt = simple_strtol(str,NULL,0) & 1;
  15. return 1;
  16. }
  17. __setup("prompt_ramdisk=", prompt_ramdisk);
  18. int __initdata rd_image_start; /* starting block # of image */
  19. static int __init ramdisk_start_setup(char *str)
  20. {
  21. rd_image_start = simple_strtol(str,NULL,0);
  22. return 1;
  23. }
  24. __setup("ramdisk_start=", ramdisk_start_setup);
  25. static int __init crd_load(int in_fd, int out_fd);
  26. /*
  27. * This routine tries to find a RAM disk image to load, and returns the
  28. * number of blocks to read for a non-compressed image, 0 if the image
  29. * is a compressed image, and -1 if an image with the right magic
  30. * numbers could not be found.
  31. *
  32. * We currently check for the following magic numbers:
  33. * minix
  34. * ext2
  35. * romfs
  36. * cramfs
  37. * gzip
  38. */
  39. static int __init
  40. identify_ramdisk_image(int fd, int start_block)
  41. {
  42. const int size = 512;
  43. struct minix_super_block *minixsb;
  44. struct ext2_super_block *ext2sb;
  45. struct romfs_super_block *romfsb;
  46. struct cramfs_super *cramfsb;
  47. int nblocks = -1;
  48. unsigned char *buf;
  49. buf = kmalloc(size, GFP_KERNEL);
  50. if (buf == 0)
  51. return -1;
  52. minixsb = (struct minix_super_block *) buf;
  53. ext2sb = (struct ext2_super_block *) buf;
  54. romfsb = (struct romfs_super_block *) buf;
  55. cramfsb = (struct cramfs_super *) buf;
  56. memset(buf, 0xe5, size);
  57. /*
  58. * Read block 0 to test for gzipped kernel
  59. */
  60. sys_lseek(fd, start_block * BLOCK_SIZE, 0);
  61. sys_read(fd, buf, size);
  62. /*
  63. * If it matches the gzip magic numbers, return -1
  64. */
  65. if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
  66. printk(KERN_NOTICE
  67. "RAMDISK: Compressed image found at block %d\n",
  68. start_block);
  69. nblocks = 0;
  70. goto done;
  71. }
  72. /* romfs is at block zero too */
  73. if (romfsb->word0 == ROMSB_WORD0 &&
  74. romfsb->word1 == ROMSB_WORD1) {
  75. printk(KERN_NOTICE
  76. "RAMDISK: romfs filesystem found at block %d\n",
  77. start_block);
  78. nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
  79. goto done;
  80. }
  81. if (cramfsb->magic == CRAMFS_MAGIC) {
  82. printk(KERN_NOTICE
  83. "RAMDISK: cramfs filesystem found at block %d\n",
  84. start_block);
  85. nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
  86. goto done;
  87. }
  88. /*
  89. * Read block 1 to test for minix and ext2 superblock
  90. */
  91. sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
  92. sys_read(fd, buf, size);
  93. /* Try minix */
  94. if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
  95. minixsb->s_magic == MINIX_SUPER_MAGIC2) {
  96. printk(KERN_NOTICE
  97. "RAMDISK: Minix filesystem found at block %d\n",
  98. start_block);
  99. nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
  100. goto done;
  101. }
  102. /* Try ext2 */
  103. if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
  104. printk(KERN_NOTICE
  105. "RAMDISK: ext2 filesystem found at block %d\n",
  106. start_block);
  107. nblocks = le32_to_cpu(ext2sb->s_blocks_count) <<
  108. le32_to_cpu(ext2sb->s_log_block_size);
  109. goto done;
  110. }
  111. printk(KERN_NOTICE
  112. "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
  113. start_block);
  114. done:
  115. sys_lseek(fd, start_block * BLOCK_SIZE, 0);
  116. kfree(buf);
  117. return nblocks;
  118. }
  119. int __init rd_load_image(char *from)
  120. {
  121. int res = 0;
  122. int in_fd, out_fd;
  123. unsigned long rd_blocks, devblocks;
  124. int nblocks, i, disk;
  125. char *buf = NULL;
  126. unsigned short rotate = 0;
  127. #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
  128. char rotator[4] = { '|' , '/' , '-' , '\\' };
  129. #endif
  130. out_fd = sys_open("/dev/ram", O_RDWR, 0);
  131. if (out_fd < 0)
  132. goto out;
  133. in_fd = sys_open(from, O_RDONLY, 0);
  134. if (in_fd < 0)
  135. goto noclose_input;
  136. nblocks = identify_ramdisk_image(in_fd, rd_image_start);
  137. if (nblocks < 0)
  138. goto done;
  139. if (nblocks == 0) {
  140. #ifdef BUILD_CRAMDISK
  141. if (crd_load(in_fd, out_fd) == 0)
  142. goto successful_load;
  143. #else
  144. printk(KERN_NOTICE
  145. "RAMDISK: Kernel does not support compressed "
  146. "RAM disk images\n");
  147. #endif
  148. goto done;
  149. }
  150. /*
  151. * NOTE NOTE: nblocks is not actually blocks but
  152. * the number of kibibytes of data to load into a ramdisk.
  153. * So any ramdisk block size that is a multiple of 1KiB should
  154. * work when the appropriate ramdisk_blocksize is specified
  155. * on the command line.
  156. *
  157. * The default ramdisk_blocksize is 1KiB and it is generally
  158. * silly to use anything else, so make sure to use 1KiB
  159. * blocksize while generating ext2fs ramdisk-images.
  160. */
  161. if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
  162. rd_blocks = 0;
  163. else
  164. rd_blocks >>= 1;
  165. if (nblocks > rd_blocks) {
  166. printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n",
  167. nblocks, rd_blocks);
  168. goto done;
  169. }
  170. /*
  171. * OK, time to copy in the data
  172. */
  173. if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
  174. devblocks = 0;
  175. else
  176. devblocks >>= 1;
  177. if (strcmp(from, "/initrd.image") == 0)
  178. devblocks = nblocks;
  179. if (devblocks == 0) {
  180. printk(KERN_ERR "RAMDISK: could not determine device size\n");
  181. goto done;
  182. }
  183. buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
  184. if (buf == 0) {
  185. printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
  186. goto done;
  187. }
  188. printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ",
  189. nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
  190. for (i = 0, disk = 1; i < nblocks; i++) {
  191. if (i && (i % devblocks == 0)) {
  192. printk("done disk #%d.\n", disk++);
  193. rotate = 0;
  194. if (sys_close(in_fd)) {
  195. printk("Error closing the disk.\n");
  196. goto noclose_input;
  197. }
  198. change_floppy("disk #%d", disk);
  199. in_fd = sys_open(from, O_RDONLY, 0);
  200. if (in_fd < 0) {
  201. printk("Error opening disk.\n");
  202. goto noclose_input;
  203. }
  204. printk("Loading disk #%d... ", disk);
  205. }
  206. sys_read(in_fd, buf, BLOCK_SIZE);
  207. sys_write(out_fd, buf, BLOCK_SIZE);
  208. #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
  209. if (!(i % 16)) {
  210. printk("%c\b", rotator[rotate & 0x3]);
  211. rotate++;
  212. }
  213. #endif
  214. }
  215. printk("done.\n");
  216. successful_load:
  217. res = 1;
  218. done:
  219. sys_close(in_fd);
  220. noclose_input:
  221. sys_close(out_fd);
  222. out:
  223. kfree(buf);
  224. sys_unlink("/dev/ram");
  225. return res;
  226. }
  227. int __init rd_load_disk(int n)
  228. {
  229. if (rd_prompt)
  230. change_floppy("root floppy disk to be loaded into RAM disk");
  231. create_dev("/dev/root", ROOT_DEV);
  232. create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
  233. return rd_load_image("/dev/root");
  234. }
  235. #ifdef BUILD_CRAMDISK
  236. /*
  237. * gzip declarations
  238. */
  239. #define OF(args) args
  240. #ifndef memzero
  241. #define memzero(s, n) memset ((s), 0, (n))
  242. #endif
  243. typedef unsigned char uch;
  244. typedef unsigned short ush;
  245. typedef unsigned long ulg;
  246. #define INBUFSIZ 4096
  247. #define WSIZE 0x8000 /* window size--must be a power of two, and */
  248. /* at least 32K for zip's deflate method */
  249. static uch *inbuf;
  250. static uch *window;
  251. static unsigned insize; /* valid bytes in inbuf */
  252. static unsigned inptr; /* index of next byte to be processed in inbuf */
  253. static unsigned outcnt; /* bytes in output buffer */
  254. static int exit_code;
  255. static int unzip_error;
  256. static long bytes_out;
  257. static int crd_infd, crd_outfd;
  258. #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  259. /* Diagnostic functions (stubbed out) */
  260. #define Assert(cond,msg)
  261. #define Trace(x)
  262. #define Tracev(x)
  263. #define Tracevv(x)
  264. #define Tracec(c,x)
  265. #define Tracecv(c,x)
  266. #define STATIC static
  267. #define INIT __init
  268. static int __init fill_inbuf(void);
  269. static void __init flush_window(void);
  270. static void __init *malloc(size_t size);
  271. static void __init free(void *where);
  272. static void __init error(char *m);
  273. static void __init gzip_mark(void **);
  274. static void __init gzip_release(void **);
  275. #include "../lib/inflate.c"
  276. static void __init *malloc(size_t size)
  277. {
  278. return kmalloc(size, GFP_KERNEL);
  279. }
  280. static void __init free(void *where)
  281. {
  282. kfree(where);
  283. }
  284. static void __init gzip_mark(void **ptr)
  285. {
  286. }
  287. static void __init gzip_release(void **ptr)
  288. {
  289. }
  290. /* ===========================================================================
  291. * Fill the input buffer. This is called only when the buffer is empty
  292. * and at least one byte is really needed.
  293. * Returning -1 does not guarantee that gunzip() will ever return.
  294. */
  295. static int __init fill_inbuf(void)
  296. {
  297. if (exit_code) return -1;
  298. insize = sys_read(crd_infd, inbuf, INBUFSIZ);
  299. if (insize == 0) {
  300. error("RAMDISK: ran out of compressed data");
  301. return -1;
  302. }
  303. inptr = 1;
  304. return inbuf[0];
  305. }
  306. /* ===========================================================================
  307. * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  308. * (Used for the decompressed data only.)
  309. */
  310. static void __init flush_window(void)
  311. {
  312. ulg c = crc; /* temporary variable */
  313. unsigned n, written;
  314. uch *in, ch;
  315. written = sys_write(crd_outfd, window, outcnt);
  316. if (written != outcnt && unzip_error == 0) {
  317. printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n",
  318. written, outcnt, bytes_out);
  319. unzip_error = 1;
  320. }
  321. in = window;
  322. for (n = 0; n < outcnt; n++) {
  323. ch = *in++;
  324. c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
  325. }
  326. crc = c;
  327. bytes_out += (ulg)outcnt;
  328. outcnt = 0;
  329. }
  330. static void __init error(char *x)
  331. {
  332. printk(KERN_ERR "%s\n", x);
  333. exit_code = 1;
  334. unzip_error = 1;
  335. }
  336. static int __init crd_load(int in_fd, int out_fd)
  337. {
  338. int result;
  339. insize = 0; /* valid bytes in inbuf */
  340. inptr = 0; /* index of next byte to be processed in inbuf */
  341. outcnt = 0; /* bytes in output buffer */
  342. exit_code = 0;
  343. bytes_out = 0;
  344. crc = (ulg)0xffffffffL; /* shift register contents */
  345. crd_infd = in_fd;
  346. crd_outfd = out_fd;
  347. inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
  348. if (inbuf == 0) {
  349. printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
  350. return -1;
  351. }
  352. window = kmalloc(WSIZE, GFP_KERNEL);
  353. if (window == 0) {
  354. printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
  355. kfree(inbuf);
  356. return -1;
  357. }
  358. makecrc();
  359. result = gunzip();
  360. if (unzip_error)
  361. result = 1;
  362. kfree(inbuf);
  363. kfree(window);
  364. return result;
  365. }
  366. #endif /* BUILD_CRAMDISK */