diff options
Diffstat (limited to 'src/kernel/blk_drv/ramdisk.c')
-rw-r--r-- | src/kernel/blk_drv/ramdisk.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/kernel/blk_drv/ramdisk.c b/src/kernel/blk_drv/ramdisk.c new file mode 100644 index 0000000..dc99f7c --- /dev/null +++ b/src/kernel/blk_drv/ramdisk.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * linux/kernel/blk_drv/ramdisk.c | ||
3 | * | ||
4 | * Written by Theodore Ts'o, 12/2/91 | ||
5 | */ | ||
6 | |||
7 | #include <string.h> | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/fs.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/segment.h> | ||
15 | #include <asm/memory.h> | ||
16 | |||
17 | #define MAJOR_NR 1 | ||
18 | #include "blk.h" | ||
19 | |||
20 | char *rd_start; | ||
21 | int rd_length = 0; | ||
22 | |||
23 | void do_rd_request(void) | ||
24 | { | ||
25 | int len; | ||
26 | char *addr; | ||
27 | |||
28 | INIT_REQUEST; | ||
29 | addr = rd_start + (CURRENT->sector << 9); | ||
30 | len = CURRENT->nr_sectors << 9; | ||
31 | if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) { | ||
32 | end_request(0); | ||
33 | goto repeat; | ||
34 | } | ||
35 | if (CURRENT-> cmd == WRITE) { | ||
36 | (void ) memcpy(addr, | ||
37 | CURRENT->buffer, | ||
38 | len); | ||
39 | } else if (CURRENT->cmd == READ) { | ||
40 | (void) memcpy(CURRENT->buffer, | ||
41 | addr, | ||
42 | len); | ||
43 | } else | ||
44 | panic("unknown ramdisk-command"); | ||
45 | end_request(1); | ||
46 | goto repeat; | ||
47 | } | ||
48 | |||
49 | /* | ||
50 | * Returns amount of memory which needs to be reserved. | ||
51 | */ | ||
52 | long rd_init(long mem_start, int length) | ||
53 | { | ||
54 | int i; | ||
55 | char *cp; | ||
56 | |||
57 | blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; | ||
58 | rd_start = (char *) mem_start; | ||
59 | rd_length = length; | ||
60 | cp = rd_start; | ||
61 | for (i=0; i < length; i++) | ||
62 | *cp++ = '\0'; | ||
63 | return(length); | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * If the root device is the ram disk, try to load it. | ||
68 | * In order to do this, the root device is originally set to the | ||
69 | * floppy, and we later change it to be ram disk. | ||
70 | */ | ||
71 | void rd_load(void) | ||
72 | { | ||
73 | struct buffer_head *bh; | ||
74 | struct super_block s; | ||
75 | int block = 256; /* Start at block 256 */ | ||
76 | int i = 1; | ||
77 | int nblocks; | ||
78 | char *cp; /* Move pointer */ | ||
79 | |||
80 | if (!rd_length) | ||
81 | return; | ||
82 | printk("Ram disk: %d bytes, starting at 0x%x\n", rd_length, | ||
83 | (int) rd_start); | ||
84 | if (MAJOR(ROOT_DEV) != 2) | ||
85 | return; | ||
86 | bh = breada(ROOT_DEV,block+1,block,block+2,-1); | ||
87 | if (!bh) { | ||
88 | printk("Disk error while looking for ramdisk!\n"); | ||
89 | return; | ||
90 | } | ||
91 | *((struct d_super_block *) &s) = *((struct d_super_block *) bh->b_data); | ||
92 | brelse(bh); | ||
93 | if (s.s_magic != SUPER_MAGIC) | ||
94 | /* No ram disk image present, assume normal floppy boot */ | ||
95 | return; | ||
96 | nblocks = s.s_nzones << s.s_log_zone_size; | ||
97 | if (nblocks > (rd_length >> BLOCK_SIZE_BITS)) { | ||
98 | printk("Ram disk image too big! (%d blocks, %d avail)\n", | ||
99 | nblocks, rd_length >> BLOCK_SIZE_BITS); | ||
100 | return; | ||
101 | } | ||
102 | printk("Loading %d bytes into ram disk... 0000k", | ||
103 | nblocks << BLOCK_SIZE_BITS); | ||
104 | cp = rd_start; | ||
105 | while (nblocks) { | ||
106 | if (nblocks > 2) | ||
107 | bh = breada(ROOT_DEV, block, block+1, block+2, -1); | ||
108 | else | ||
109 | bh = bread(ROOT_DEV, block); | ||
110 | if (!bh) { | ||
111 | printk("I/O error on block %d, aborting load\n", | ||
112 | block); | ||
113 | return; | ||
114 | } | ||
115 | (void) memcpy(cp, bh->b_data, BLOCK_SIZE); | ||
116 | brelse(bh); | ||
117 | printk("\010\010\010\010\010%4dk",i); | ||
118 | cp += BLOCK_SIZE; | ||
119 | block++; | ||
120 | nblocks--; | ||
121 | i++; | ||
122 | } | ||
123 | printk("\010\010\010\010\010done \n"); | ||
124 | ROOT_DEV=0x0101; | ||
125 | } | ||