This source file includes following definitions.
- rd_request
- rd_ioctl
- rd_open
- rd_init
- identify_ramdisk_image
- rd_load
- malloc
- free
- gzip_mark
- gzip_release
- fill_inbuf
- flush_window
- error
- crd_load
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <linux/sched.h>
29 #include <linux/minix_fs.h>
30 #include <linux/ext2_fs.h>
31 #include <linux/fs.h>
32 #include <linux/kernel.h>
33 #include <linux/string.h>
34 #include <linux/mm.h>
35 #include <linux/mman.h>
36 #include <linux/malloc.h>
37 #include <linux/ioctl.h>
38
39 #include <asm/system.h>
40 #include <asm/segment.h>
41
42 extern void wait_for_keypress(void);
43
44
45
46
47
48
49 #define MAJOR_NR RAMDISK_MAJOR
50 #include <linux/blk.h>
51
52 #define BUILD_CRAMDISK
53 #define NUM_RAMDISKS 8
54
55 void rd_load(void);
56 static int crd_load(struct file *fp, struct file *outfp);
57
58
59
60 static int rd_length[NUM_RAMDISKS];
61 static int rd_blocksizes[NUM_RAMDISKS];
62
63
64
65
66
67
68
69 int rd_doload = 0;
70 int rd_prompt = 1;
71 int rd_image_start = 0;
72
73
74
75
76
77
78
79 static void rd_request(void)
80 {
81 unsigned int minor;
82 int offset, len;
83
84 repeat:
85 INIT_REQUEST;
86
87 minor = MINOR(CURRENT->rq_dev);
88
89 if (minor >= NUM_RAMDISKS) {
90 end_request(0);
91 goto repeat;
92 }
93
94 offset = CURRENT->sector << 9;
95 len = CURRENT->current_nr_sectors << 9;
96
97 if ((offset + len) > rd_length[minor]) {
98 end_request(0);
99 goto repeat;
100 }
101
102 if (CURRENT->cmd == READ) {
103 memset(CURRENT->buffer, 0, len);
104 }
105 set_bit(BH_Protected, &CURRENT->bh->b_state);
106
107 end_request(1);
108 goto repeat;
109 }
110
111 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
112 {
113 int err;
114
115 if (!inode || !inode->i_rdev)
116 return -EINVAL;
117
118 switch (cmd) {
119 case BLKFLSBUF:
120 if (!suser()) return -EACCES;
121 invalidate_buffers(inode->i_rdev);
122 break;
123 case BLKGETSIZE:
124 if (!arg) return -EINVAL;
125 err = verify_area(VERIFY_WRITE, (long *) arg,
126 sizeof(long));
127 if (err)
128 return err;
129 put_user(rd_length[MINOR(inode->i_rdev)] / 512,
130 (long *) arg);
131 return 0;
132
133 default:
134 break;
135 };
136
137 return 0;
138 }
139
140 static int rd_open(struct inode * inode, struct file * filp)
141 {
142
143 if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
144 return -ENODEV;
145
146 return 0;
147 }
148
149 static struct file_operations fd_fops = {
150 NULL,
151 block_read,
152 block_write,
153 NULL,
154 NULL,
155 rd_ioctl,
156 NULL,
157 rd_open,
158 NULL,
159 block_fsync
160 };
161
162
163 int rd_init(void)
164 {
165 int i;
166
167 if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
168 printk("RAMDISK2 : Could not get major %d", MAJOR_NR);
169 return -EIO;
170 }
171
172 blk_dev[MAJOR_NR].request_fn = &rd_request;
173
174 for (i = 0; i < NUM_RAMDISKS; i++) {
175 rd_length[i] = (16384 * 1024);
176 rd_blocksizes[i] = 1024;
177 }
178
179 blksize_size[MAJOR_NR] = rd_blocksizes;
180
181 return 0;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 int
196 identify_ramdisk_image(int device, struct file *fp, int start_block)
197 {
198 const int size = 512;
199 struct minix_super_block *minixsb;
200 struct ext2_super_block *ext2sb;
201 int nblocks = -1;
202 int max_blocks;
203 unsigned char *buf;
204
205 buf = kmalloc(size, GFP_KERNEL);
206 if (buf == 0)
207 return -1;
208
209 minixsb = (struct minix_super_block *) buf;
210 ext2sb = (struct ext2_super_block *) buf;
211 memset(buf, 0xe5, size);
212
213
214
215
216 if (fp->f_op->lseek)
217 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
218 fp->f_pos = start_block * BLOCK_SIZE;
219
220 fp->f_op->read(fp->f_inode, fp, buf, size);
221
222
223
224
225 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
226 printk(KERN_NOTICE
227 "RAMDISK: Compressed image found at block %d\n",
228 start_block);
229 nblocks = 0;
230 goto done;
231 }
232
233
234
235
236 if (fp->f_op->lseek)
237 fp->f_op->lseek(fp->f_inode, fp,
238 (start_block+1) * BLOCK_SIZE, 0);
239 fp->f_pos = (start_block+1) * BLOCK_SIZE;
240
241 fp->f_op->read(fp->f_inode, fp, buf, size);
242
243
244 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
245 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
246 printk(KERN_NOTICE
247 "RAMDISK: Minix filesystem found at block %d\n",
248 start_block);
249 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
250 goto done;
251 }
252
253
254 if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
255 printk(KERN_NOTICE
256 "RAMDISK: Ext2 filesystem found at block %d\n",
257 start_block);
258 nblocks = ext2sb->s_blocks_count;
259 goto done;
260 }
261 printk(KERN_NOTICE
262 "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n",
263 start_block);
264
265 done:
266 if (fp->f_op->lseek)
267 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
268 fp->f_pos = start_block * BLOCK_SIZE;
269
270 if ((nblocks > 0) && blk_size[MAJOR(device)]) {
271 max_blocks = blk_size[MAJOR(device)][MINOR(device)];
272 max_blocks -= start_block;
273 if (nblocks > max_blocks) {
274 printk(KERN_NOTICE
275 "RAMDISK: Restricting filesystem size "
276 "from %d to %d blocks.\n",
277 nblocks, max_blocks);
278 nblocks = max_blocks;
279 }
280 }
281 kfree(buf);
282 return nblocks;
283 }
284
285
286
287
288 void rd_load()
289 {
290 struct inode inode, out_inode;
291 struct file infile, outfile;
292 unsigned short fs;
293 int device, ram_device;
294 int nblocks, i;
295 char *buf;
296 unsigned short rotate = 0;
297 char rotator[4] = { '|' , '/' , '-' , '\\' };
298
299 if (rd_doload == 0)
300 return;
301
302 device = ROOT_DEV;
303 ram_device = (MAJOR_NR << 8);
304
305 if (MAJOR(device) != FLOPPY_MAJOR) return;
306
307 if (rd_prompt) {
308 printk(KERN_NOTICE
309 "VFS: Insert ramdisk floppy and press ENTER\n");
310 wait_for_keypress();
311 }
312
313 memset(&infile, 0, sizeof(infile));
314 memset(&inode, 0, sizeof(inode));
315 inode.i_rdev = device;
316 infile.f_mode = 1;
317 infile.f_inode = &inode;
318
319 memset(&outfile, 0, sizeof(outfile));
320 memset(&out_inode, 0, sizeof(out_inode));
321 out_inode.i_rdev = ram_device;
322 outfile.f_mode = 3;
323 outfile.f_inode = &out_inode;
324
325 if (blkdev_open(&inode, &infile) != 0) return;
326 if (blkdev_open(&out_inode, &outfile) != 0) return;
327
328 fs = get_fs();
329 set_fs(KERNEL_DS);
330
331 nblocks = identify_ramdisk_image(device, &infile, rd_image_start);
332 if (nblocks < 0)
333 goto done;
334
335 if (nblocks == 0) {
336 #ifdef BUILD_CRAMDISK
337 if (crd_load(&infile, &outfile) == 0)
338 goto successful_load;
339 #else
340 printk(KERN_NOTICE
341 "RAMDISK: Kernel does not support compressed "
342 "ramdisk images\n");
343 #endif
344 goto done;
345 }
346
347 if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
348 printk("RAMDISK: image too big! (%d/%d blocks)\n",
349 nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
350 goto done;
351 }
352
353
354
355
356 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
357 if (buf == 0) {
358 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
359 goto done;
360 }
361
362 printk(KERN_NOTICE "RAMDISK: Loading %d blocks into ram disk... ", nblocks);
363 for (i=0; i < nblocks; i++) {
364 infile.f_op->read(infile.f_inode, &infile, buf,
365 BLOCK_SIZE);
366 outfile.f_op->write(outfile.f_inode, &outfile, buf,
367 BLOCK_SIZE);
368 if (!(i % 16)) {
369 printk("%c\b", rotator[rotate & 0x3]);
370 rotate++;
371 }
372 }
373 printk("done.\n");
374 kfree(buf);
375
376 successful_load:
377 invalidate_buffers(ROOT_DEV);
378 ROOT_DEV = (MAJOR_NR << 8);
379
380 done:
381 if (infile.f_op->release)
382 infile.f_op->release(&inode, &infile);
383 set_fs(fs);
384 }
385
386 #ifdef BUILD_CRAMDISK
387
388
389
390
391
392 #define OF(args) args
393
394 #define memzero(s, n) memset ((s), 0, (n))
395
396
397 typedef unsigned char uch;
398 typedef unsigned short ush;
399 typedef unsigned long ulg;
400
401 #define INBUFSIZ 4096
402 #define WSIZE 0x8000
403
404
405 static uch *inbuf;
406 static uch *window;
407
408 static unsigned insize = 0;
409 static unsigned inptr = 0;
410 static unsigned outcnt = 0;
411 static exit_code = 0;
412 static long bytes_out = 0;
413 static struct file *crd_infp, *crd_outfp;
414
415 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
416
417
418 #define Assert(cond,msg)
419 #define Trace(x)
420 #define Tracev(x)
421 #define Tracevv(x)
422 #define Tracec(c,x)
423 #define Tracecv(c,x)
424
425 #define STATIC static
426
427 static int fill_inbuf(void);
428 static void flush_window(void);
429 static void *malloc(int size);
430 static void free(void *where);
431 static void error(char *m);
432 static void gzip_mark(void **);
433 static void gzip_release(void **);
434
435 #include "../../lib/inflate.c"
436
437 static void *malloc(int size)
438 {
439 return kmalloc(size, GFP_KERNEL);
440 }
441
442 static void free(void *where)
443 {
444 kfree(where);
445 }
446
447 static void gzip_mark(void **ptr)
448 {
449 }
450
451 static void gzip_release(void **ptr)
452 {
453 }
454
455
456
457
458
459
460 static int fill_inbuf()
461 {
462 if (exit_code) return -1;
463
464 insize = crd_infp->f_op->read(crd_infp->f_inode, crd_infp,
465 inbuf, INBUFSIZ);
466 if (insize == 0) return -1;
467
468 inptr = 1;
469
470 return inbuf[0];
471 }
472
473
474
475
476
477 static void flush_window()
478 {
479 ulg c = crc;
480 unsigned n;
481 uch *in, ch;
482
483 crd_outfp->f_op->write(crd_outfp->f_inode, crd_outfp, window,
484 outcnt);
485 in = window;
486 for (n = 0; n < outcnt; n++) {
487 ch = *in++;
488 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
489 }
490 crc = c;
491 bytes_out += (ulg)outcnt;
492 outcnt = 0;
493 }
494
495 static void error(char *x)
496 {
497 printk(KERN_ERR "%s", x);
498 exit_code = 1;
499 }
500
501 static int
502 crd_load(struct file * fp, struct file *outfp)
503 {
504 int result;
505
506 crd_infp = fp;
507 crd_outfp = outfp;
508 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
509 if (inbuf == 0) {
510 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
511 return -1;
512 }
513 window = kmalloc(WSIZE, GFP_KERNEL);
514 if (window == 0) {
515 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
516 kfree(inbuf);
517 return -1;
518 }
519 makecrc();
520 result = gunzip();
521 kfree(inbuf);
522 kfree(window);
523 return result;
524 }
525
526 #endif
527
528
529