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

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