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