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