root/drivers/block/ramdisk.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_rd_request
  2. rd_init
  3. do_load
  4. rd_load

   1 /*
   2  *  linux/kernel/blk_drv/ramdisk.c
   3  *
   4  *  Written by Theodore Ts'o, 12/2/91
   5  *
   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
   8  */
   9 
  10 
  11 #include <linux/config.h>
  12 #include <linux/sched.h>
  13 #include <linux/minix_fs.h>
  14 #include <linux/fs.h>
  15 #include <linux/kernel.h>
  16 #include <linux/string.h>
  17 #include <asm/system.h>
  18 #include <asm/segment.h>
  19 
  20 #define MAJOR_NR  MEM_MAJOR
  21 #include "blk.h"
  22 
  23 #define RAMDISK_MINOR   1
  24 
  25 extern void wait_for_keypress(void);
  26 
  27 char    *rd_start;
  28 int     rd_length = 0;
  29 static int rd_blocksizes[2] = {0, 0};
  30 
  31 static void do_rd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         int     len;
  34         char    *addr;
  35 
  36 repeat:
  37         INIT_REQUEST;
  38         addr = rd_start + (CURRENT->sector << 9);
  39         len = CURRENT->current_nr_sectors << 9;
  40 
  41         if ((MINOR(CURRENT->dev) != RAMDISK_MINOR) ||
  42             (addr+len > rd_start+rd_length)) {
  43                 end_request(0);
  44                 goto repeat;
  45         }
  46         if (CURRENT-> cmd == WRITE) {
  47                 (void ) memcpy(addr,
  48                               CURRENT->buffer,
  49                               len);
  50         } else if (CURRENT->cmd == READ) {
  51                 (void) memcpy(CURRENT->buffer, 
  52                               addr,
  53                               len);
  54         } else
  55                 panic("RAMDISK: unknown RAM disk command !\n");
  56         end_request(1);
  57         goto repeat;
  58 }
  59 
  60 static struct file_operations rd_fops = {
  61         NULL,                   /* lseek - default */
  62         block_read,             /* read - general block-dev read */
  63         block_write,            /* write - general block-dev write */
  64         NULL,                   /* readdir - bad */
  65         NULL,                   /* select */
  66         NULL,                   /* ioctl */
  67         NULL,                   /* mmap */
  68         NULL,                   /* no special open code */
  69         NULL,                   /* no special release code */
  70         block_fsync             /* fsync */
  71 };
  72 
  73 /*
  74  * Returns amount of memory which needs to be reserved.
  75  */
  76 long rd_init(long mem_start, int length)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78         int     i;
  79         char    *cp;
  80 
  81         if (register_blkdev(MEM_MAJOR,"rd",&rd_fops)) {
  82                 printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR);
  83                 return 0;
  84         }
  85         blk_dev[MEM_MAJOR].request_fn = DEVICE_REQUEST;
  86         rd_start = (char *) mem_start;
  87         rd_length = length;
  88         cp = rd_start;
  89         for (i=0; i < length; i++)
  90                 *cp++ = '\0';
  91 
  92         for(i=0;i<2;i++) rd_blocksizes[i] = 1024;
  93         blksize_size[MAJOR_NR] = rd_blocksizes;
  94 
  95         return(length);
  96 }
  97 
  98 static void do_load(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         struct buffer_head *bh;
 101         struct minix_super_block s;
 102         int             block, tries;
 103         int             i = 1;
 104         int             nblocks;
 105         char            *cp;
 106         
 107         /*
 108          * Check for a super block on the diskette.
 109          * The old-style boot/root diskettes had their RAM image
 110          * starting at block 512 of the boot diskette.  LINUX/Pro
 111          * uses the entire diskette as a file system, so in that
 112          * case, we have to look at block 0.  Be intelligent about
 113          * this, and check both... - FvK
 114          */
 115         for (tries = 0; tries < 1000; tries += 512) {
 116                 block = tries;
 117                 bh = breada(ROOT_DEV,block+1,BLOCK_SIZE, 0,  PAGE_SIZE);
 118                 if (!bh) {
 119                         printk("RAMDISK: I/O error while looking for super block!\n");
 120                         return;
 121                 }
 122 
 123                 /* This is silly- why do we require it to be a MINIX FS? */
 124                 *((struct minix_super_block *) &s) =
 125                         *((struct minix_super_block *) bh->b_data);
 126                 brelse(bh);
 127                 nblocks = s.s_nzones << s.s_log_zone_size;
 128                 if (s.s_magic != MINIX_SUPER_MAGIC &&
 129                     s.s_magic != MINIX_SUPER_MAGIC2) {
 130                         printk("RAMDISK: trying old-style RAM image.\n");
 131                         continue;
 132                 }
 133 
 134                 if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) {
 135                         printk("RAMDISK: image too big! (%d/%d blocks)\n",
 136                                         nblocks, rd_length >> BLOCK_SIZE_BITS);
 137                         return;
 138                 }
 139                 printk("RAMDISK: Loading %d blocks into RAM disk", nblocks);
 140 
 141                 /* We found an image file system.  Load it into core! */
 142                 cp = rd_start;
 143                 while (nblocks) {
 144                         if (nblocks > 2) 
 145                                 bh = breada(ROOT_DEV, block, BLOCK_SIZE, 0,  PAGE_SIZE);
 146                         else
 147                                 bh = bread(ROOT_DEV, block, BLOCK_SIZE);
 148                         if (!bh) {
 149                                 printk("RAMDISK: I/O error on block %d, aborting!\n", 
 150                                 block);
 151                                 return;
 152                         }
 153                         (void) memcpy(cp, bh->b_data, BLOCK_SIZE);
 154                         brelse(bh);
 155                         if (!(nblocks-- & 15)) printk(".");
 156                         cp += BLOCK_SIZE;
 157                         block++;
 158                         i++;
 159                 }
 160                 printk("\ndone\n");
 161 
 162                 /* We loaded the file system image.  Prepare for mounting it. */
 163                 ROOT_DEV = ((MEM_MAJOR << 8) | RAMDISK_MINOR);
 164                 return;
 165         }
 166 }
 167 
 168 /*
 169  * If the root device is the RAM disk, try to load it.
 170  * In order to do this, the root device is originally set to the
 171  * floppy, and we later change it to be RAM disk.
 172  */
 173 void rd_load(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175         struct inode inode;
 176         struct file filp;
 177 
 178         /* If no RAM disk specified, give up early. */
 179         if (!rd_length)
 180                 return;
 181         printk("RAMDISK: %d bytes, starting at 0x%x\n",
 182                         rd_length, (int) rd_start);
 183 
 184         /* If we are doing a diskette boot, we might have to pre-load it. */
 185         if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR)
 186                 return;
 187 
 188         /* for Slackware install disks */
 189         printk(KERN_NOTICE "VFS: Insert ramdisk floppy and press ENTER\n");
 190         wait_for_keypress();
 191 
 192         memset(&filp, 0, sizeof(filp));
 193         memset(&inode, 0, sizeof(inode));
 194         inode.i_rdev = ROOT_DEV;
 195         filp.f_mode = 1; /* read only */
 196         filp.f_inode = &inode;
 197         if(blkdev_open(&inode, &filp) == 0 ){
 198                 do_load();
 199                 if(filp.f_op && filp.f_op->release)
 200                         filp.f_op->release(&inode,&filp);
 201         }
 202 }

/* [previous][next][first][last][top][bottom][index][help] */