This source file includes following definitions.
- rd_request
- rd_ioctl
- initrd_read
- initrd_release
- rd_open
- rd_release
- rd_init
- init_module
- cleanup_module
- identify_ramdisk_image
- rd_load_image
- rd_load
- initrd_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
29
30
31
32
33
34
35
36
37
38
39
40 #include <linux/config.h>
41 #include <linux/sched.h>
42 #include <linux/minix_fs.h>
43 #include <linux/ext2_fs.h>
44 #include <linux/fs.h>
45 #include <linux/kernel.h>
46 #include <linux/string.h>
47 #include <linux/mm.h>
48 #include <linux/mman.h>
49 #include <linux/malloc.h>
50 #include <linux/ioctl.h>
51 #include <linux/fd.h>
52 #include <linux/module.h>
53
54 #include <asm/system.h>
55 #include <asm/segment.h>
56
57 extern void wait_for_keypress(void);
58
59
60
61
62
63
64 #define MAJOR_NR RAMDISK_MAJOR
65 #include <linux/blk.h>
66
67
68 #define NUM_RAMDISKS 16
69
70 #ifndef MODULE
71
72 #define RD_LOADER
73 #define BUILD_CRAMDISK
74
75 void rd_load(void);
76 static int crd_load(struct file *fp, struct file *outfp);
77
78 #ifdef CONFIG_BLK_DEV_INITRD
79 static int initrd_users = 0;
80 #endif
81 #endif
82
83
84
85 static int rd_length[NUM_RAMDISKS];
86 static int rd_blocksizes[NUM_RAMDISKS];
87
88
89
90
91
92
93
94 int rd_size = 4096;
95
96 #ifndef MODULE
97 int rd_doload = 0;
98 int rd_prompt = 1;
99 int rd_image_start = 0;
100 #ifdef CONFIG_BLK_DEV_INITRD
101 unsigned long initrd_start,initrd_end;
102 int mount_initrd = 1;
103 #endif
104 #endif
105
106
107
108
109
110
111
112 static void rd_request(void)
113 {
114 unsigned int minor;
115 int offset, len;
116
117 repeat:
118 INIT_REQUEST;
119
120 minor = MINOR(CURRENT->rq_dev);
121
122 if (minor >= NUM_RAMDISKS) {
123 end_request(0);
124 goto repeat;
125 }
126
127 offset = CURRENT->sector << 9;
128 len = CURRENT->current_nr_sectors << 9;
129
130 if ((offset + len) > rd_length[minor]) {
131 end_request(0);
132 goto repeat;
133 }
134
135
136
137
138
139
140
141
142 if (CURRENT->cmd == READ)
143 memset(CURRENT->buffer, 0, len);
144 else
145 set_bit(BH_Protected, &CURRENT->bh->b_state);
146
147 end_request(1);
148 goto repeat;
149 }
150
151 static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
152 {
153 int err;
154
155 if (!inode || !inode->i_rdev)
156 return -EINVAL;
157
158 switch (cmd) {
159 case BLKFLSBUF:
160 if (!suser()) return -EACCES;
161 invalidate_buffers(inode->i_rdev);
162 break;
163 case BLKGETSIZE:
164 if (!arg) return -EINVAL;
165 err = verify_area(VERIFY_WRITE, (long *) arg,
166 sizeof(long));
167 if (err)
168 return err;
169 put_user(rd_length[MINOR(inode->i_rdev)] / 512,
170 (long *) arg);
171 return 0;
172
173 default:
174 break;
175 };
176
177 return 0;
178 }
179
180
181 #ifdef CONFIG_BLK_DEV_INITRD
182
183 static int initrd_read(struct inode *inode,struct file *file,char *buf,
184 int count)
185 {
186 int left;
187
188 left = initrd_end-initrd_start-file->f_pos;
189 if (count > left) count = left;
190 if (count <= 0) return 0;
191 memcpy_tofs(buf,(char *) initrd_start+file->f_pos,count);
192 file->f_pos += count;
193 return count;
194 }
195
196
197 static void initrd_release(struct inode *inode,struct file *file)
198 {
199 unsigned long i;
200
201 if (--initrd_users) return;
202 for (i = initrd_start; i < initrd_end; i += PAGE_SIZE)
203 free_page(i);
204 initrd_start = 0;
205 }
206
207
208 static struct file_operations initrd_fops = {
209 NULL,
210 initrd_read,
211 NULL,
212 NULL,
213 NULL,
214 NULL,
215 NULL,
216 NULL,
217 initrd_release,
218 NULL
219 };
220
221 #endif
222
223
224 static int rd_open(struct inode * inode, struct file * filp)
225 {
226 #ifdef CONFIG_BLK_DEV_INITRD
227 if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
228 if (!initrd_start) return -ENODEV;
229 initrd_users++;
230 filp->f_op = &initrd_fops;
231 return 0;
232 }
233 #endif
234
235 if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
236 return -ENODEV;
237
238 MOD_INC_USE_COUNT;
239
240 return 0;
241 }
242
243 #ifdef MODULE
244 static void rd_release(struct inode * inode, struct file * filp)
245 {
246 MOD_DEC_USE_COUNT;
247 }
248 #endif
249
250 static struct file_operations fd_fops = {
251 NULL,
252 block_read,
253 block_write,
254 NULL,
255 NULL,
256 rd_ioctl,
257 NULL,
258 rd_open,
259 #ifndef MODULE
260 NULL,
261 #else
262 rd_release,
263 #endif
264 block_fsync
265 };
266
267
268 int rd_init(void)
269 {
270 int i;
271
272 if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) {
273 printk("RAMDISK: Could not get major %d", MAJOR_NR);
274 return -EIO;
275 }
276
277 blk_dev[MAJOR_NR].request_fn = &rd_request;
278
279 for (i = 0; i < NUM_RAMDISKS; i++) {
280 rd_length[i] = (rd_size * 1024);
281 rd_blocksizes[i] = 1024;
282 }
283
284 blksize_size[MAJOR_NR] = rd_blocksizes;
285
286 printk("Ramdisk driver initialized : %d ramdisks of %dK size\n",
287 NUM_RAMDISKS, rd_size);
288
289 return 0;
290 }
291
292
293
294 #ifdef MODULE
295
296 int init_module(void)
297 {
298 int error = rd_init();
299 if (!error)
300 printk(KERN_INFO "RAMDISK: Loaded as module.\n");
301 return error;
302 }
303
304
305 void cleanup_module(void)
306 {
307 int i;
308
309 for (i = 0 ; i < NUM_RAMDISKS; i++)
310 invalidate_buffers(MKDEV(MAJOR_NR, i));
311
312 unregister_blkdev( MAJOR_NR, "ramdisk" );
313 blk_dev[MAJOR_NR].request_fn = 0;
314 }
315
316 #endif
317
318
319
320 #ifdef RD_LOADER
321
322
323
324
325
326
327
328
329
330
331
332 int
333 identify_ramdisk_image(kdev_t device, struct file *fp, int start_block)
334 {
335 const int size = 512;
336 struct minix_super_block *minixsb;
337 struct ext2_super_block *ext2sb;
338 int nblocks = -1;
339 int max_blocks;
340 unsigned char *buf;
341
342 buf = kmalloc(size, GFP_KERNEL);
343 if (buf == 0)
344 return -1;
345
346 minixsb = (struct minix_super_block *) buf;
347 ext2sb = (struct ext2_super_block *) buf;
348 memset(buf, 0xe5, size);
349
350
351
352
353 if (fp->f_op->lseek)
354 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
355 fp->f_pos = start_block * BLOCK_SIZE;
356
357 fp->f_op->read(fp->f_inode, fp, buf, size);
358
359
360
361
362 if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
363 printk(KERN_NOTICE
364 "RAMDISK: Compressed image found at block %d\n",
365 start_block);
366 nblocks = 0;
367 goto done;
368 }
369
370
371
372
373 if (fp->f_op->lseek)
374 fp->f_op->lseek(fp->f_inode, fp,
375 (start_block+1) * BLOCK_SIZE, 0);
376 fp->f_pos = (start_block+1) * BLOCK_SIZE;
377
378 fp->f_op->read(fp->f_inode, fp, buf, size);
379
380
381 if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
382 minixsb->s_magic == MINIX_SUPER_MAGIC2) {
383 printk(KERN_NOTICE
384 "RAMDISK: Minix filesystem found at block %d\n",
385 start_block);
386 nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
387 goto done;
388 }
389
390
391 if (ext2sb->s_magic == EXT2_SUPER_MAGIC) {
392 printk(KERN_NOTICE
393 "RAMDISK: Ext2 filesystem found at block %d\n",
394 start_block);
395 nblocks = ext2sb->s_blocks_count;
396 goto done;
397 }
398 printk(KERN_NOTICE
399 "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n",
400 start_block);
401
402 done:
403 if (fp->f_op->lseek)
404 fp->f_op->lseek(fp->f_inode, fp, start_block * BLOCK_SIZE, 0);
405 fp->f_pos = start_block * BLOCK_SIZE;
406
407 if ((nblocks > 0) && blk_size[MAJOR(device)]) {
408 max_blocks = blk_size[MAJOR(device)][MINOR(device)];
409 max_blocks -= start_block;
410 if (nblocks > max_blocks) {
411 printk(KERN_NOTICE
412 "RAMDISK: Restricting filesystem size "
413 "from %d to %d blocks.\n",
414 nblocks, max_blocks);
415 nblocks = max_blocks;
416 }
417 }
418 kfree(buf);
419 return nblocks;
420 }
421
422
423
424
425 static void rd_load_image(kdev_t device,int offset)
426 {
427 struct inode inode, out_inode;
428 struct file infile, outfile;
429 unsigned short fs;
430 kdev_t ram_device;
431 int nblocks, i;
432 char *buf;
433 unsigned short rotate = 0;
434 char rotator[4] = { '|' , '/' , '-' , '\\' };
435
436 ram_device = MKDEV(MAJOR_NR, 0);
437
438 memset(&infile, 0, sizeof(infile));
439 memset(&inode, 0, sizeof(inode));
440 inode.i_rdev = device;
441 infile.f_mode = 1;
442 infile.f_inode = &inode;
443
444 memset(&outfile, 0, sizeof(outfile));
445 memset(&out_inode, 0, sizeof(out_inode));
446 out_inode.i_rdev = ram_device;
447 outfile.f_mode = 3;
448 outfile.f_inode = &out_inode;
449
450 if (blkdev_open(&inode, &infile) != 0) return;
451 if (blkdev_open(&out_inode, &outfile) != 0) return;
452
453 fs = get_fs();
454 set_fs(KERNEL_DS);
455
456 nblocks = identify_ramdisk_image(device, &infile, offset);
457 if (nblocks < 0)
458 goto done;
459
460 if (nblocks == 0) {
461 #ifdef BUILD_CRAMDISK
462 if (crd_load(&infile, &outfile) == 0)
463 goto successful_load;
464 #else
465 printk(KERN_NOTICE
466 "RAMDISK: Kernel does not support compressed "
467 "ramdisk images\n");
468 #endif
469 goto done;
470 }
471
472 if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
473 printk("RAMDISK: image too big! (%d/%d blocks)\n",
474 nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
475 goto done;
476 }
477
478
479
480
481 buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
482 if (buf == 0) {
483 printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
484 goto done;
485 }
486
487 printk(KERN_NOTICE "RAMDISK: Loading %d blocks into ram disk... ", nblocks);
488 for (i=0; i < nblocks; i++) {
489 infile.f_op->read(infile.f_inode, &infile, buf,
490 BLOCK_SIZE);
491 outfile.f_op->write(outfile.f_inode, &outfile, buf,
492 BLOCK_SIZE);
493 if (!(i % 16)) {
494 printk("%c\b", rotator[rotate & 0x3]);
495 rotate++;
496 }
497 }
498 printk("done.\n");
499 kfree(buf);
500
501 successful_load:
502 invalidate_buffers(device);
503 ROOT_DEV = MKDEV(MAJOR_NR,0);
504
505 done:
506 if (infile.f_op->release)
507 infile.f_op->release(&inode, &infile);
508 set_fs(fs);
509 }
510
511
512 void rd_load()
513 {
514 if (rd_doload == 0)
515 return;
516
517 if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
518
519 if (rd_prompt) {
520 #ifdef CONFIG_BLK_DEV_FD
521 floppy_eject();
522 #endif
523 printk(KERN_NOTICE
524 "VFS: Insert root floppy disk to be loaded into ramdisk and press ENTER\n");
525 wait_for_keypress();
526 }
527
528 rd_load_image(ROOT_DEV,rd_image_start);
529
530 }
531
532
533 #ifdef CONFIG_BLK_DEV_INITRD
534 void initrd_load(void)
535 {
536 rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0);
537 }
538 #endif
539
540 #endif
541
542 #ifdef BUILD_CRAMDISK
543
544
545
546
547
548 #define OF(args) args
549
550 #define memzero(s, n) memset ((s), 0, (n))
551
552
553 typedef unsigned char uch;
554 typedef unsigned short ush;
555 typedef unsigned long ulg;
556
557 #define INBUFSIZ 4096
558 #define WSIZE 0x8000
559
560
561 static uch *inbuf;
562 static uch *window;
563
564 static unsigned insize = 0;
565 static unsigned inptr = 0;
566 static unsigned outcnt = 0;
567 static exit_code = 0;
568 static long bytes_out = 0;
569 static struct file *crd_infp, *crd_outfp;
570
571 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
572
573
574 #define Assert(cond,msg)
575 #define Trace(x)
576 #define Tracev(x)
577 #define Tracevv(x)
578 #define Tracec(c,x)
579 #define Tracecv(c,x)
580
581 #define STATIC static
582
583 static int fill_inbuf(void);
584 static void flush_window(void);
585 static void *malloc(int size);
586 static void free(void *where);
587 static void error(char *m);
588 static void gzip_mark(void **);
589 static void gzip_release(void **);
590
591 #include "../../lib/inflate.c"
592
593 static void *malloc(int size)
594 {
595 return kmalloc(size, GFP_KERNEL);
596 }
597
598 static void free(void *where)
599 {
600 kfree(where);
601 }
602
603 static void gzip_mark(void **ptr)
604 {
605 }
606
607 static void gzip_release(void **ptr)
608 {
609 }
610
611
612
613
614
615
616 static int fill_inbuf()
617 {
618 if (exit_code) return -1;
619
620 insize = crd_infp->f_op->read(crd_infp->f_inode, crd_infp,
621 inbuf, INBUFSIZ);
622 if (insize == 0) return -1;
623
624 inptr = 1;
625
626 return inbuf[0];
627 }
628
629
630
631
632
633 static void flush_window()
634 {
635 ulg c = crc;
636 unsigned n;
637 uch *in, ch;
638
639 crd_outfp->f_op->write(crd_outfp->f_inode, crd_outfp, window,
640 outcnt);
641 in = window;
642 for (n = 0; n < outcnt; n++) {
643 ch = *in++;
644 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
645 }
646 crc = c;
647 bytes_out += (ulg)outcnt;
648 outcnt = 0;
649 }
650
651 static void error(char *x)
652 {
653 printk(KERN_ERR "%s", x);
654 exit_code = 1;
655 }
656
657 static int
658 crd_load(struct file * fp, struct file *outfp)
659 {
660 int result;
661
662 crd_infp = fp;
663 crd_outfp = outfp;
664 inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
665 if (inbuf == 0) {
666 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
667 return -1;
668 }
669 window = kmalloc(WSIZE, GFP_KERNEL);
670 if (window == 0) {
671 printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
672 kfree(inbuf);
673 return -1;
674 }
675 makecrc();
676 result = gunzip();
677 kfree(inbuf);
678 kfree(window);
679 return result;
680 }
681
682 #endif
683