2 * ramdisk.c - Multiple RAM disk driver - gzip-loading version - v. 0.8 beta.
4 * (C) Chad Page, Theodore Ts'o, et. al, 1995.
6 * This RAM disk is designed to have filesystems created on it and mounted
7 * just like a regular floppy disk.
9 * It also does something suggested by Linus: use the buffer cache as the
10 * RAM disk data. This makes it possible to dynamically allocate the RAM disk
11 * buffer - with some consequences I have to deal with as I write this.
13 * This code is based on the original ramdisk.c, written mostly by
14 * Theodore Ts'o (TYT) in 1991. The code was largely rewritten by
15 * Chad Page to use the buffer cache to store the RAM disk data in
16 * 1995; Theodore then took over the driver again, and cleaned it up
17 * for inclusion in the mainline kernel.
19 * The original CRAMDISK code was written by Richard Lyons, and
20 * adapted by Chad Page to use the new RAM disk interface. Theodore
21 * Ts'o rewrote it so that both the compressed RAM disk loader and the
22 * kernel decompressor uses the same inflate.c codebase. The RAM disk
23 * loader now also loads into a dynamic (buffer cache based) RAM disk,
24 * not the old static RAM disk. Support for the old static RAM disk has
25 * been completely removed.
27 * Loadable module support added by Tom Dyas.
29 * Further cleanups by Chad Page (page0588@sundance.sjsu.edu):
30 * Cosmetic changes in #ifdef MODULE, code movement, etc.
31 * When the RAM disk module is removed, free the protected buffers
32 * Default RAM disk size changed to 2.88 MB
34 * Added initrd: Werner Almesberger & Hans Lermen, Feb '96
36 * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
39 * Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
43 #include <linux/config.h>
44 #include <linux/sched.h>
45 #include <linux/minix_fs.h>
46 #include <linux/ext2_fs.h>
47 #include <linux/romfs_fs.h>
49 #include <linux/kernel.h>
50 #include <linux/string.h>
52 #include <linux/mman.h>
53 #include <linux/malloc.h>
54 #include <linux/ioctl.h>
56 #include <linux/module.h>
57 #include <linux/init.h>
59 #include <asm/system.h>
60 #include <asm/uaccess.h>
61 #include <asm/byteorder.h>
63 extern void wait_for_keypress(void);
66 * 35 has been officially registered as the RAMDISK major number, but
67 * so is the original MAJOR number of 1. We're using 1 in
68 * include/linux/major.h for now
70 #define MAJOR_NR RAMDISK_MAJOR
71 #include <linux/blk.h>
73 /* The RAM disk size is now a parameter */
74 #define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
77 /* We don't have to load RAM disks or gunzip them in a module. */
79 #define BUILD_CRAMDISK
82 static int crd_load(struct file
*fp
, struct file
*outfp
);
84 #ifdef CONFIG_BLK_DEV_INITRD
85 static int initrd_users
= 0;
89 /* Various static variables go here. Most are used only in the RAM disk code.
92 static int rd_length
[NUM_RAMDISKS
];
93 static int rd_blocksizes
[NUM_RAMDISKS
];
96 * Parameters for the boot-loading of the RAM disk. These are set by
97 * init/main.c (from arguments to the kernel command line) or from the
98 * architecture-specific setup routine (from the stored boot sector
101 int rd_size
= 4096; /* Size of the RAM disks */
104 int rd_doload
= 0; /* 1 = load RAM disk, 0 = don't load */
105 int rd_prompt
= 1; /* 1 = prompt for RAM disk, 0 = don't prompt */
106 int rd_image_start
= 0; /* starting block # of image */
107 #ifdef CONFIG_BLK_DEV_INITRD
108 unsigned long initrd_start
,initrd_end
;
109 int mount_initrd
= 1; /* zero if initrd should not be mounted */
110 int initrd_below_start_ok
= 0;
115 * Basically, my strategy here is to set up a buffer-head which can't be
116 * deleted, and make that my Ramdisk. If the request is outside of the
117 * allocated size, we must get rid of it...
120 static void rd_request(void)
128 minor
= MINOR(CURRENT
->rq_dev
);
130 if (minor
>= NUM_RAMDISKS
) {
135 offset
= CURRENT
->sector
<< 9;
136 len
= CURRENT
->current_nr_sectors
<< 9;
138 if ((offset
+ len
) > rd_length
[minor
]) {
144 * If we're reading, fill the buffer with 0's. This is okay since
145 * we're using protected buffers which should never get freed...
147 * If we're writing, we protect the buffer.
150 if (CURRENT
->cmd
== READ
)
151 memset(CURRENT
->buffer
, 0, len
);
153 set_bit(BH_Protected
, &CURRENT
->bh
->b_state
);
159 static int rd_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
163 if (!inode
|| !inode
->i_rdev
)
168 if (!capable(CAP_SYS_ADMIN
)) return -EACCES
;
169 invalidate_buffers(inode
->i_rdev
);
171 case BLKGETSIZE
: /* Return device size */
172 if (!arg
) return -EINVAL
;
173 err
= verify_area(VERIFY_WRITE
, (long *) arg
,
177 put_user(rd_length
[MINOR(inode
->i_rdev
)] / 512,
189 #ifdef CONFIG_BLK_DEV_INITRD
191 static ssize_t
initrd_read(struct file
*file
, char *buf
,
192 size_t count
, loff_t
*ppos
)
196 left
= initrd_end
- initrd_start
- *ppos
;
197 if (count
> left
) count
= left
;
198 if (count
== 0) return 0;
199 copy_to_user(buf
, (char *)initrd_start
+ *ppos
, count
);
205 static int initrd_release(struct inode
*inode
,struct file
*file
)
209 if (--initrd_users
) return 0;
210 for (i
= initrd_start
; i
< initrd_end
; i
+= PAGE_SIZE
)
217 static struct file_operations initrd_fops
= {
219 initrd_read
, /* read */
227 initrd_release
, /* release */
234 static int rd_open(struct inode
* inode
, struct file
* filp
)
236 #ifdef CONFIG_BLK_DEV_INITRD
237 if (DEVICE_NR(inode
->i_rdev
) == INITRD_MINOR
) {
238 if (!initrd_start
) return -ENODEV
;
240 filp
->f_op
= &initrd_fops
;
245 if (DEVICE_NR(inode
->i_rdev
) >= NUM_RAMDISKS
)
253 static int rd_release(struct inode
* inode
, struct file
* filp
)
259 static struct file_operations fd_fops
= {
260 NULL
, /* lseek - default */
261 block_read
, /* read - block dev read */
262 block_write
, /* write - block dev write */
263 NULL
, /* readdir - not here! */
265 rd_ioctl
, /* ioctl */
269 rd_release
, /* module needs to decrement use count */
270 block_fsync
/* fsync */
273 /* This is the registration and initialization section of the RAM disk driver */
274 __initfunc(int rd_init(void))
278 if (register_blkdev(MAJOR_NR
, "ramdisk", &fd_fops
)) {
279 printk("RAMDISK: Could not get major %d", MAJOR_NR
);
283 blk_dev
[MAJOR_NR
].request_fn
= &rd_request
;
285 for (i
= 0; i
< NUM_RAMDISKS
; i
++) {
286 rd_length
[i
] = (rd_size
* 1024);
287 rd_blocksizes
[i
] = 1024;
290 blksize_size
[MAJOR_NR
] = rd_blocksizes
;
292 printk("RAM disk driver initialized: %d RAM disks of %dK size\n",
293 NUM_RAMDISKS
, rd_size
);
298 /* loadable module support */
302 int init_module(void)
304 int error
= rd_init();
306 printk(KERN_INFO
"RAMDISK: Loaded as module.\n");
310 /* Before freeing the module, invalidate all of the protected buffers! */
311 void cleanup_module(void)
315 for (i
= 0 ; i
< NUM_RAMDISKS
; i
++)
316 invalidate_buffers(MKDEV(MAJOR_NR
, i
));
318 unregister_blkdev( MAJOR_NR
, "ramdisk" );
319 blk_dev
[MAJOR_NR
].request_fn
= 0;
324 /* End of non-loading portions of the RAM disk driver */
328 * This routine tries to find a RAM disk image to load, and returns the
329 * number of blocks to read for a non-compressed image, 0 if the image
330 * is a compressed image, and -1 if an image with the right magic
331 * numbers could not be found.
333 * We currently check for the following magic numbers:
340 identify_ramdisk_image(kdev_t device
, struct file
*fp
, int start_block
))
342 const int size
= 512;
343 struct minix_super_block
*minixsb
;
344 struct ext2_super_block
*ext2sb
;
345 struct romfs_super_block
*romfsb
;
349 buf
= kmalloc(size
, GFP_KERNEL
);
353 minixsb
= (struct minix_super_block
*) buf
;
354 ext2sb
= (struct ext2_super_block
*) buf
;
355 romfsb
= (struct romfs_super_block
*) buf
;
356 memset(buf
, 0xe5, size
);
359 * Read block 0 to test for gzipped kernel
361 if (fp
->f_op
->llseek
)
362 fp
->f_op
->llseek(fp
, start_block
* BLOCK_SIZE
, 0);
363 fp
->f_pos
= start_block
* BLOCK_SIZE
;
365 fp
->f_op
->read(fp
, buf
, size
, &fp
->f_pos
);
368 * If it matches the gzip magic numbers, return -1
370 if (buf
[0] == 037 && ((buf
[1] == 0213) || (buf
[1] == 0236))) {
372 "RAMDISK: Compressed image found at block %d\n",
378 /* romfs is at block zero too */
379 if (romfsb
->word0
== ROMSB_WORD0
&&
380 romfsb
->word1
== ROMSB_WORD1
) {
382 "RAMDISK: romfs filesystem found at block %d\n",
384 nblocks
= (ntohl(romfsb
->size
)+BLOCK_SIZE
-1)>>BLOCK_SIZE_BITS
;
389 * Read block 1 to test for minix and ext2 superblock
391 if (fp
->f_op
->llseek
)
392 fp
->f_op
->llseek(fp
, (start_block
+1) * BLOCK_SIZE
, 0);
393 fp
->f_pos
= (start_block
+1) * BLOCK_SIZE
;
395 fp
->f_op
->read(fp
, buf
, size
, &fp
->f_pos
);
398 if (minixsb
->s_magic
== MINIX_SUPER_MAGIC
||
399 minixsb
->s_magic
== MINIX_SUPER_MAGIC2
) {
401 "RAMDISK: Minix filesystem found at block %d\n",
403 nblocks
= minixsb
->s_nzones
<< minixsb
->s_log_zone_size
;
408 if (ext2sb
->s_magic
== cpu_to_le16(EXT2_SUPER_MAGIC
)) {
410 "RAMDISK: ext2 filesystem found at block %d\n",
412 nblocks
= le32_to_cpu(ext2sb
->s_blocks_count
);
417 "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
421 if (fp
->f_op
->llseek
)
422 fp
->f_op
->llseek(fp
, start_block
* BLOCK_SIZE
, 0);
423 fp
->f_pos
= start_block
* BLOCK_SIZE
;
430 * This routine loads in the RAM disk image.
432 __initfunc(static void rd_load_image(kdev_t device
,int offset
))
434 struct inode inode
, out_inode
;
435 struct file infile
, outfile
;
436 struct dentry in_dentry
, out_dentry
;
441 unsigned short rotate
= 0;
442 unsigned short devblocks
= 0;
443 char rotator
[4] = { '|' , '/' , '-' , '\\' };
445 ram_device
= MKDEV(MAJOR_NR
, 0);
447 memset(&infile
, 0, sizeof(infile
));
448 memset(&inode
, 0, sizeof(inode
));
449 memset(&in_dentry
, 0, sizeof(in_dentry
));
450 inode
.i_rdev
= device
;
451 infile
.f_mode
= 1; /* read only */
452 infile
.f_dentry
= &in_dentry
;
453 in_dentry
.d_inode
= &inode
;
455 memset(&outfile
, 0, sizeof(outfile
));
456 memset(&out_inode
, 0, sizeof(out_inode
));
457 memset(&out_dentry
, 0, sizeof(out_dentry
));
458 out_inode
.i_rdev
= ram_device
;
459 outfile
.f_mode
= 3; /* read/write */
460 outfile
.f_dentry
= &out_dentry
;
461 out_dentry
.d_inode
= &out_inode
;
463 if (blkdev_open(&inode
, &infile
) != 0) return;
464 if (blkdev_open(&out_inode
, &outfile
) != 0) return;
469 nblocks
= identify_ramdisk_image(device
, &infile
, offset
);
474 #ifdef BUILD_CRAMDISK
475 if (crd_load(&infile
, &outfile
) == 0)
476 goto successful_load
;
479 "RAMDISK: Kernel does not support compressed "
480 "RAM disk images\n");
485 if (nblocks
> (rd_length
[0] >> BLOCK_SIZE_BITS
)) {
486 printk("RAMDISK: image too big! (%d/%d blocks)\n",
487 nblocks
, rd_length
[0] >> BLOCK_SIZE_BITS
);
492 * OK, time to copy in the data
494 buf
= kmalloc(BLOCK_SIZE
, GFP_KERNEL
);
496 printk(KERN_ERR
"RAMDISK: could not allocate buffer\n");
500 if (blk_size
[MAJOR(device
)])
501 devblocks
= blk_size
[MAJOR(device
)][MINOR(device
)];
503 #ifdef CONFIG_BLK_DEV_INITRD
504 if (MAJOR(device
) == MAJOR_NR
&& MINOR(device
) == INITRD_MINOR
)
508 if (devblocks
== 0) {
509 printk(KERN_ERR
"RAMDISK: could not determine device size\n");
513 printk(KERN_NOTICE
"RAMDISK: Loading %d blocks [%d disk%s] into ram disk... ",
514 nblocks
, ((nblocks
-1)/devblocks
)+1, nblocks
>devblocks
? "s" : "");
515 for (i
=0; i
< nblocks
; i
++) {
516 if (i
&& (i
% devblocks
== 0)) {
517 printk("done disk #%d.\n", i
/devblocks
);
519 invalidate_buffers(device
);
520 if (infile
.f_op
->release
)
521 infile
.f_op
->release(&inode
, &infile
);
522 printk("Please insert disk #%d and press ENTER\n", i
/devblocks
+1);
524 if (blkdev_open(&inode
, &infile
) != 0) {
525 printk("Error opening disk.\n");
529 printk("Loading disk #%d... ", i
/devblocks
+1);
531 infile
.f_op
->read(&infile
, buf
, BLOCK_SIZE
, &infile
.f_pos
);
532 outfile
.f_op
->write(&outfile
, buf
, BLOCK_SIZE
, &outfile
.f_pos
);
534 printk("%c\b", rotator
[rotate
& 0x3]);
542 invalidate_buffers(device
);
543 ROOT_DEV
= MKDEV(MAJOR_NR
,0);
546 if (infile
.f_op
->release
)
547 infile
.f_op
->release(&inode
, &infile
);
552 __initfunc(void rd_load(void))
557 if (MAJOR(ROOT_DEV
) != FLOPPY_MAJOR
) return;
560 #ifdef CONFIG_BLK_DEV_FD
564 "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n");
568 rd_load_image(ROOT_DEV
,rd_image_start
);
573 #ifdef CONFIG_BLK_DEV_INITRD
574 __initfunc(void initrd_load(void))
576 rd_load_image(MKDEV(MAJOR_NR
, INITRD_MINOR
),0);
580 #endif /* RD_LOADER */
582 #ifdef BUILD_CRAMDISK
588 #define OF(args) args
590 #define memzero(s, n) memset ((s), 0, (n))
593 typedef unsigned char uch
;
594 typedef unsigned short ush
;
595 typedef unsigned long ulg
;
597 #define INBUFSIZ 4096
598 #define WSIZE 0x8000 /* window size--must be a power of two, and */
599 /* at least 32K for zip's deflate method */
604 static unsigned insize
= 0; /* valid bytes in inbuf */
605 static unsigned inptr
= 0; /* index of next byte to be processed in inbuf */
606 static unsigned outcnt
= 0; /* bytes in output buffer */
607 static int exit_code
= 0;
608 static long bytes_out
= 0;
609 static struct file
*crd_infp
, *crd_outfp
;
611 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
613 /* Diagnostic functions (stubbed out) */
614 #define Assert(cond,msg)
621 #define STATIC static
623 static int fill_inbuf(void);
624 static void flush_window(void);
625 static void *malloc(int size
);
626 static void free(void *where
);
627 static void error(char *m
);
628 static void gzip_mark(void **);
629 static void gzip_release(void **);
631 #include "../../lib/inflate.c"
633 __initfunc(static void *malloc(int size
))
635 return kmalloc(size
, GFP_KERNEL
);
638 __initfunc(static void free(void *where
))
643 __initfunc(static void gzip_mark(void **ptr
))
647 __initfunc(static void gzip_release(void **ptr
))
652 /* ===========================================================================
653 * Fill the input buffer. This is called only when the buffer is empty
654 * and at least one byte is really needed.
656 __initfunc(static int fill_inbuf(void))
658 if (exit_code
) return -1;
660 insize
= crd_infp
->f_op
->read(crd_infp
, inbuf
, INBUFSIZ
,
662 if (insize
== 0) return -1;
669 /* ===========================================================================
670 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
671 * (Used for the decompressed data only.)
673 __initfunc(static void flush_window(void))
675 ulg c
= crc
; /* temporary variable */
679 crd_outfp
->f_op
->write(crd_outfp
, window
, outcnt
, &crd_outfp
->f_pos
);
681 for (n
= 0; n
< outcnt
; n
++) {
683 c
= crc_32_tab
[((int)c
^ ch
) & 0xff] ^ (c
>> 8);
686 bytes_out
+= (ulg
)outcnt
;
690 __initfunc(static void error(char *x
))
692 printk(KERN_ERR
"%s", x
);
696 __initfunc(static int
697 crd_load(struct file
* fp
, struct file
*outfp
))
703 inbuf
= kmalloc(INBUFSIZ
, GFP_KERNEL
);
705 printk(KERN_ERR
"RAMDISK: Couldn't allocate gzip buffer\n");
708 window
= kmalloc(WSIZE
, GFP_KERNEL
);
710 printk(KERN_ERR
"RAMDISK: Couldn't allocate gzip window\n");
721 #endif /* BUILD_CRAMDISK */