2 * linux/kernel/blk_drv/ramdisk.c
4 * Written by Theodore Ts'o, 12/2/91
6 * Modifications by Fred N. van Kempen to allow for bootable root
7 * disks (which are used in LINUX/Pro). Also some cleanups. 03/03/93
11 #include <linux/config.h>
12 #include <linux/sched.h>
13 #include <linux/minix_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/string.h>
17 #include <asm/system.h>
18 #include <asm/segment.h>
20 #define MAJOR_NR MEM_MAJOR
23 #define RAMDISK_MINOR 1
28 static int rd_blocksizes
[2] = {0, 0};
30 static void do_rd_request(void)
37 addr
= rd_start
+ (CURRENT
->sector
<< 9);
38 len
= CURRENT
->current_nr_sectors
<< 9;
40 if ((MINOR(CURRENT
->dev
) != RAMDISK_MINOR
) ||
41 (addr
+len
> rd_start
+rd_length
)) {
45 if (CURRENT
-> cmd
== WRITE
) {
49 } else if (CURRENT
->cmd
== READ
) {
50 (void) memcpy(CURRENT
->buffer
,
54 panic("RAMDISK: unknown RAM disk command !\n");
59 static struct file_operations rd_fops
= {
60 NULL
, /* lseek - default */
61 block_read
, /* read - general block-dev read */
62 block_write
, /* write - general block-dev write */
63 NULL
, /* readdir - bad */
67 NULL
, /* no special open code */
68 NULL
, /* no special release code */
69 block_fsync
/* fsync */
73 * Returns amount of memory which needs to be reserved.
75 long rd_init(long mem_start
, int length
)
80 if (register_blkdev(MEM_MAJOR
,"rd",&rd_fops
)) {
81 printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR
);
84 blk_dev
[MEM_MAJOR
].request_fn
= DEVICE_REQUEST
;
85 rd_start
= (char *) mem_start
;
88 for (i
=0; i
< length
; i
++)
91 for(i
=0;i
<2;i
++) rd_blocksizes
[i
] = 1024;
92 blksize_size
[MAJOR_NR
] = rd_blocksizes
;
98 * If the root device is the RAM disk, try to load it.
99 * In order to do this, the root device is originally set to the
100 * floppy, and we later change it to be RAM disk.
104 struct buffer_head
*bh
;
105 struct minix_super_block s
;
111 /* If no RAM disk specified, give up early. */
112 if (!rd_length
) return;
113 printk("RAMDISK: %d bytes, starting at 0x%x\n",
114 rd_length
, (int) rd_start
);
116 /* If we are doing a diskette boot, we might have to pre-load it. */
117 if (MAJOR(ROOT_DEV
) != FLOPPY_MAJOR
) return;
120 * Check for a super block on the diskette.
121 * The old-style boot/root diskettes had their RAM image
122 * starting at block 512 of the boot diskette. LINUX/Pro
123 * uses the enire diskette as a file system, so in that
124 * case, we have to look at block 0. Be intelligent about
125 * this, and check both... - FvK
127 for (tries
= 0; tries
< 1000; tries
+= 512) {
129 bh
= breada(ROOT_DEV
,block
+1,block
,block
+2,-1);
131 printk("RAMDISK: I/O error while looking for super block!\n");
135 /* This is silly- why do we require it to be a MINIX FS? */
136 *((struct minix_super_block
*) &s
) =
137 *((struct minix_super_block
*) bh
->b_data
);
139 nblocks
= s
.s_nzones
<< s
.s_log_zone_size
;
140 if (s
.s_magic
!= MINIX_SUPER_MAGIC
&&
141 s
.s_magic
!= MINIX_SUPER_MAGIC2
) {
142 printk("RAMDISK: trying old-style RAM image.\n");
146 if (nblocks
> (rd_length
>> BLOCK_SIZE_BITS
)) {
147 printk("RAMDISK: image too big! (%d/%d blocks)\n",
148 nblocks
, rd_length
>> BLOCK_SIZE_BITS
);
151 printk("RAMDISK: Loading %d blocks into RAM disk", nblocks
);
153 /* We found an image file system. Load it into core! */
157 bh
= breada(ROOT_DEV
, block
, block
+1, block
+2, -1);
159 bh
= bread(ROOT_DEV
, block
, BLOCK_SIZE
);
161 printk("RAMDISK: I/O error on block %d, aborting!\n",
165 (void) memcpy(cp
, bh
->b_data
, BLOCK_SIZE
);
167 if (!(nblocks
-- & 15)) printk(".");
174 /* We loaded the file system image. Prepare for mounting it. */
175 ROOT_DEV
= ((MEM_MAJOR
<< 8) | RAMDISK_MINOR
);