⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ramdisk.c.txt

📁 Linux块设备驱动分析与模拟实现
💻 TXT
字号:
  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 
 26 char    *rd_start;
 27 int     rd_length = 0;
 28 static int rd_blocksizes[2] = {0, 0};
 29 
 30 static void do_rd_request(void)
 31 {
 32         int     len;
 33         char    *addr;
 34 
 35 repeat:
 36         INIT_REQUEST;
 37         addr = rd_start + (CURRENT->sector << 9);
 38         len = CURRENT->current_nr_sectors << 9;
 39 
 40         if ((MINOR(CURRENT->dev) != RAMDISK_MINOR) ||
 41             (addr+len > rd_start+rd_length)) {
 42                 end_request(0);
 43                 goto repeat;
 44         }
 45         if (CURRENT-> cmd == WRITE) {
 46                 (void ) memcpy(addr,
 47                               CURRENT->buffer,
 48                               len);
 49         } else if (CURRENT->cmd == READ) {
 50                 (void) memcpy(CURRENT->buffer, 
 51                               addr,
 52                               len);
 53         } else
 54                 panic("RAMDISK: unknown RAM disk command !\n");
 55         end_request(1);
 56         goto repeat;
 57 }
 58 
 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 */
 64         NULL,                   /* select */
 65         NULL,                   /* ioctl */
 66         NULL,                   /* mmap */
 67         NULL,                   /* no special open code */
 68         NULL,                   /* no special release code */
 69         block_fsync             /* fsync */
 70 };
 71 
 72 /*
 73  * Returns amount of memory which needs to be reserved.
 74  */
 75 long rd_init(long mem_start, int length)
 76 {
 77         int     i;
 78         char    *cp;
 79 
 80         if (register_blkdev(MEM_MAJOR,"rd",&rd_fops)) {
 81                 printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR);
 82                 return 0;
 83         }
 84         blk_dev[MEM_MAJOR].request_fn = DEVICE_REQUEST;
 85         rd_start = (char *) mem_start;
 86         rd_length = length;
 87         cp = rd_start;
 88         for (i=0; i < length; i++)
 89                 *cp++ = '\0';
 90 
 91         for(i=0;i<2;i++) rd_blocksizes[i] = 1024;
 92         blksize_size[MAJOR_NR] = rd_blocksizes;
 93 
 94         return(length);
 95 }
 96 
 97 /*
 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.
101  */
102 void rd_load(void)
103 {
104         struct buffer_head *bh;
105         struct minix_super_block s;
106         int             block, tries;
107         int             i = 1;
108         int             nblocks;
109         char            *cp;
110 
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);
115 
116         /* If we are doing a diskette boot, we might have to pre-load it. */
117         if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
118 
119         /*
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
126          */
127         for (tries = 0; tries < 1000; tries += 512) {
128                 block = tries;
129                 bh = breada(ROOT_DEV,block+1,block,block+2,-1);
130                 if (!bh) {
131                         printk("RAMDISK: I/O error while looking for super block!\n");
132                         return;
133                 }
134 
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);
138                 brelse(bh);
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");
143                         continue;
144                 }
145 
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);
149                         return;
150                 }
151                 printk("RAMDISK: Loading %d blocks into RAM disk", nblocks);
152 
153                 /* We found an image file system.  Load it into core! */
154                 cp = rd_start;
155                 while (nblocks) {
156                         if (nblocks > 2) 
157                                 bh = breada(ROOT_DEV, block, block+1, block+2, -1);
158                         else
159                                 bh = bread(ROOT_DEV, block, BLOCK_SIZE);
160                         if (!bh) {
161                                 printk("RAMDISK: I/O error on block %d, aborting!\n", 
162                                 block);
163                                 return;
164                         }
165                         (void) memcpy(cp, bh->b_data, BLOCK_SIZE);
166                         brelse(bh);
167                         if (!(nblocks-- & 15)) printk(".");
168                         cp += BLOCK_SIZE;
169                         block++;
170                         i++;
171                 }
172                 printk("\ndone\n");
173 
174                 /* We loaded the file system image.  Prepare for mounting it. */
175                 ROOT_DEV = ((MEM_MAJOR << 8) | RAMDISK_MINOR);
176                 return;
177         }
178 }
179 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -