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