OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [init/] [do_mounts.c] - Blame information for rev 1766

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#define __KERNEL_SYSCALLS__
2
#include <linux/config.h>
3
#include <linux/slab.h>
4
#include <linux/devfs_fs_kernel.h>
5
#include <linux/unistd.h>
6
#include <linux/ctype.h>
7
#include <linux/blk.h>
8
#include <linux/fd.h>
9
#include <linux/tty.h>
10
#include <linux/init.h>
11
 
12
#include <linux/nfs_fs.h>
13
#include <linux/nfs_fs_sb.h>
14
#include <linux/nfs_mount.h>
15
#include <linux/minix_fs.h>
16
#include <linux/ext2_fs.h>
17
#include <linux/romfs_fs.h>
18
#include <linux/cramfs_fs.h>
19
 
20
#define BUILD_CRAMDISK
21
 
22
extern int get_filesystem_list(char * buf);
23
 
24
extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
25
         unsigned long flags, void *data);
26
extern asmlinkage long sys_mkdir(const char *name, int mode);
27
extern asmlinkage long sys_chdir(const char *name);
28
extern asmlinkage long sys_fchdir(int fd);
29
extern asmlinkage long sys_chroot(const char *name);
30
extern asmlinkage long sys_unlink(const char *name);
31
extern asmlinkage long sys_symlink(const char *old, const char *new);
32
extern asmlinkage long sys_mknod(const char *name, int mode, dev_t dev);
33
extern asmlinkage long sys_umount(char *name, int flags);
34
extern asmlinkage long sys_ioctl(int fd, int cmd, unsigned long arg);
35
 
36
#ifdef CONFIG_BLK_DEV_INITRD
37
unsigned int real_root_dev;     /* do_proc_dointvec cannot handle kdev_t */
38
static int __initdata mount_initrd = 1;
39
 
40
static int __init no_initrd(char *str)
41
{
42
        mount_initrd = 0;
43
        return 1;
44
}
45
 
46
__setup("noinitrd", no_initrd);
47
#else
48
static int __initdata mount_initrd = 0;
49
#endif
50
 
51
int __initdata rd_doload;       /* 1 = load RAM disk, 0 = don't load */
52
 
53
int root_mountflags = MS_RDONLY | MS_VERBOSE;
54
static char root_device_name[64];
55
 
56
/* this is initialized in init/main.c */
57
kdev_t ROOT_DEV;
58
 
59
static int do_devfs = 0;
60
 
61
static int __init load_ramdisk(char *str)
62
{
63
        rd_doload = simple_strtol(str,NULL,0) & 3;
64
        return 1;
65
}
66
__setup("load_ramdisk=", load_ramdisk);
67
 
68
static int __init readonly(char *str)
69
{
70
        if (*str)
71
                return 0;
72
        root_mountflags |= MS_RDONLY;
73
        return 1;
74
}
75
 
76
static int __init readwrite(char *str)
77
{
78
        if (*str)
79
                return 0;
80
        root_mountflags &= ~MS_RDONLY;
81
        return 1;
82
}
83
 
84
__setup("ro", readonly);
85
__setup("rw", readwrite);
86
 
87
static struct dev_name_struct {
88
        const char *name;
89
        const int num;
90
} root_dev_names[] __initdata = {
91
        { "nfs",     MKDEV(NFS_MAJOR, NFS_MINOR) },
92
        { "hda",     0x0300 },
93
        { "hdb",     0x0340 },
94
        { "loop",    0x0700 },
95
        { "hdc",     0x1600 },
96
        { "hdd",     0x1640 },
97
        { "hde",     0x2100 },
98
        { "hdf",     0x2140 },
99
        { "hdg",     0x2200 },
100
        { "hdh",     0x2240 },
101
        { "hdi",     0x3800 },
102
        { "hdj",     0x3840 },
103
        { "hdk",     0x3900 },
104
        { "hdl",     0x3940 },
105
        { "hdm",     0x5800 },
106
        { "hdn",     0x5840 },
107
        { "hdo",     0x5900 },
108
        { "hdp",     0x5940 },
109
        { "hdq",     0x5A00 },
110
        { "hdr",     0x5A40 },
111
        { "hds",     0x5B00 },
112
        { "hdt",     0x5B40 },
113
        { "sda",     0x0800 },
114
        { "sdb",     0x0810 },
115
        { "sdc",     0x0820 },
116
        { "sdd",     0x0830 },
117
        { "sde",     0x0840 },
118
        { "sdf",     0x0850 },
119
        { "sdg",     0x0860 },
120
        { "sdh",     0x0870 },
121
        { "sdi",     0x0880 },
122
        { "sdj",     0x0890 },
123
        { "sdk",     0x08a0 },
124
        { "sdl",     0x08b0 },
125
        { "sdm",     0x08c0 },
126
        { "sdn",     0x08d0 },
127
        { "sdo",     0x08e0 },
128
        { "sdp",     0x08f0 },
129
        { "ada",     0x1c00 },
130
        { "adb",     0x1c10 },
131
        { "adc",     0x1c20 },
132
        { "add",     0x1c30 },
133
        { "ade",     0x1c40 },
134
        { "fd",      0x0200 },
135
        { "md",      0x0900 },
136
        { "xda",     0x0d00 },
137
        { "xdb",     0x0d40 },
138
        { "ram",     0x0100 },
139
        { "scd",     0x0b00 },
140
        { "mcd",     0x1700 },
141
        { "cdu535",  0x1800 },
142
        { "sonycd",  0x1800 },
143
        { "aztcd",   0x1d00 },
144
        { "cm206cd", 0x2000 },
145
        { "gscd",    0x1000 },
146
        { "sbpcd",   0x1900 },
147
        { "eda",     0x2400 },
148
        { "edb",     0x2440 },
149
        { "pda",        0x2d00 },
150
        { "pdb",        0x2d10 },
151
        { "pdc",        0x2d20 },
152
        { "pdd",        0x2d30 },
153
        { "pcd",        0x2e00 },
154
        { "pf",         0x2f00 },
155
        { "apblock", APBLOCK_MAJOR << 8},
156
        { "ddv", DDV_MAJOR << 8},
157
        { "jsfd",    JSFD_MAJOR << 8},
158
#if defined(CONFIG_ARCH_S390)
159
        { "dasda", (DASD_MAJOR << MINORBITS) },
160
        { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
161
        { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
162
        { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
163
        { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
164
        { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
165
        { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
166
        { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
167
#endif
168
        { "ida/c0d0p",0x4800 },
169
        { "ida/c0d1p",0x4810 },
170
        { "ida/c0d2p",0x4820 },
171
        { "ida/c0d3p",0x4830 },
172
        { "ida/c0d4p",0x4840 },
173
        { "ida/c0d5p",0x4850 },
174
        { "ida/c0d6p",0x4860 },
175
        { "ida/c0d7p",0x4870 },
176
        { "ida/c0d8p",0x4880 },
177
        { "ida/c0d9p",0x4890 },
178
        { "ida/c0d10p",0x48A0 },
179
        { "ida/c0d11p",0x48B0 },
180
        { "ida/c0d12p",0x48C0 },
181
        { "ida/c0d13p",0x48D0 },
182
        { "ida/c0d14p",0x48E0 },
183
        { "ida/c0d15p",0x48F0 },
184
        { "ida/c1d0p",0x4900 },
185
        { "ida/c2d0p",0x4A00 },
186
        { "ida/c3d0p",0x4B00 },
187
        { "ida/c4d0p",0x4C00 },
188
        { "ida/c5d0p",0x4D00 },
189
        { "ida/c6d0p",0x4E00 },
190
        { "ida/c7d0p",0x4F00 },
191
        { "cciss/c0d0p",0x6800 },
192
        { "cciss/c0d1p",0x6810 },
193
        { "cciss/c0d2p",0x6820 },
194
        { "cciss/c0d3p",0x6830 },
195
        { "cciss/c0d4p",0x6840 },
196
        { "cciss/c0d5p",0x6850 },
197
        { "cciss/c0d6p",0x6860 },
198
        { "cciss/c0d7p",0x6870 },
199
        { "cciss/c0d8p",0x6880 },
200
        { "cciss/c0d9p",0x6890 },
201
        { "cciss/c0d10p",0x68A0 },
202
        { "cciss/c0d11p",0x68B0 },
203
        { "cciss/c0d12p",0x68C0 },
204
        { "cciss/c0d13p",0x68D0 },
205
        { "cciss/c0d14p",0x68E0 },
206
        { "cciss/c0d15p",0x68F0 },
207
        { "cciss/c1d0p",0x6900 },
208
        { "cciss/c2d0p",0x6A00 },
209
        { "cciss/c3d0p",0x6B00 },
210
        { "cciss/c4d0p",0x6C00 },
211
        { "cciss/c5d0p",0x6D00 },
212
        { "cciss/c6d0p",0x6E00 },
213
        { "cciss/c7d0p",0x6F00 },
214
        { "ataraid/d0p",0x7200 },
215
        { "ataraid/d1p",0x7210 },
216
        { "ataraid/d2p",0x7220 },
217
        { "ataraid/d3p",0x7230 },
218
        { "ataraid/d4p",0x7240 },
219
        { "ataraid/d5p",0x7250 },
220
        { "ataraid/d6p",0x7260 },
221
        { "ataraid/d7p",0x7270 },
222
        { "ataraid/d8p",0x7280 },
223
        { "ataraid/d9p",0x7290 },
224
        { "ataraid/d10p",0x72A0 },
225
        { "ataraid/d11p",0x72B0 },
226
        { "ataraid/d12p",0x72C0 },
227
        { "ataraid/d13p",0x72D0 },
228
        { "ataraid/d14p",0x72E0 },
229
        { "ataraid/d15p",0x72F0 },
230
        { "rd/c0d0p",0x3000 },
231
        { "rd/c0d0p1",0x3001 },
232
        { "rd/c0d0p2",0x3002 },
233
        { "rd/c0d0p3",0x3003 },
234
        { "rd/c0d0p4",0x3004 },
235
        { "rd/c0d0p5",0x3005 },
236
        { "rd/c0d0p6",0x3006 },
237
        { "rd/c0d0p7",0x3007 },
238
        { "rd/c0d0p8",0x3008 },
239
        { "rd/c0d1p",0x3008 },
240
        { "rd/c0d1p1",0x3009 },
241
        { "rd/c0d1p2",0x300a },
242
        { "rd/c0d1p3",0x300b },
243
        { "rd/c0d1p4",0x300c },
244
        { "rd/c0d1p5",0x300d },
245
        { "rd/c0d1p6",0x300e },
246
        { "rd/c0d1p7",0x300f },
247
        { "rd/c0d1p8",0x3010 },
248
        { "nftla", 0x5d00 },
249
        { "nftlb", 0x5d10 },
250
        { "nftlc", 0x5d20 },
251
        { "nftld", 0x5d30 },
252
        { "ftla", 0x2c00 },
253
        { "ftlb", 0x2c08 },
254
        { "ftlc", 0x2c10 },
255
        { "ftld", 0x2c18 },
256
        { "mtdblock", 0x1f00 },
257
        { "nb", 0x2b00 },
258
        { NULL, 0 }
259
};
260
 
261
kdev_t __init name_to_kdev_t(char *line)
262
{
263
        int base = 0, offs;
264
        char *end;
265
 
266
        if (strncmp(line,"/dev/",5) == 0) {
267
                struct dev_name_struct *dev = root_dev_names;
268
                line += 5;
269
                do {
270
                        int len = strlen(dev->name);
271
                        if (strncmp(line,dev->name,len) == 0) {
272
                                line += len;
273
                                base = dev->num;
274
                                break;
275
                        }
276
                        dev++;
277
                } while (dev->name);
278
        }
279
        offs = simple_strtoul(line, &end, base?10:16);
280
        if (*end)
281
                offs = 0;
282
        return to_kdev_t(base + offs);
283
}
284
 
285
static int __init root_dev_setup(char *line)
286
{
287
        int i;
288
        char ch;
289
 
290
        ROOT_DEV = name_to_kdev_t(line);
291
        memset (root_device_name, 0, sizeof root_device_name);
292
        if (strncmp (line, "/dev/", 5) == 0) line += 5;
293
        for (i = 0; i < sizeof root_device_name - 1; ++i)
294
        {
295
            ch = line[i];
296
            if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
297
            root_device_name[i] = ch;
298
        }
299
        return 1;
300
}
301
 
302
__setup("root=", root_dev_setup);
303
 
304
static char * __initdata root_mount_data;
305
static int __init root_data_setup(char *str)
306
{
307
        root_mount_data = str;
308
        return 1;
309
}
310
 
311
static char * __initdata root_fs_names;
312
static int __init fs_names_setup(char *str)
313
{
314
        root_fs_names = str;
315
        return 1;
316
}
317
 
318
__setup("rootflags=", root_data_setup);
319
__setup("rootfstype=", fs_names_setup);
320
 
321
static void __init get_fs_names(char *page)
322
{
323
        char *s = page;
324
 
325
        if (root_fs_names) {
326
                strcpy(page, root_fs_names);
327
                while (*s++) {
328
                        if (s[-1] == ',')
329
                                s[-1] = '\0';
330
                }
331
        } else {
332
                int len = get_filesystem_list(page);
333
                char *p, *next;
334
 
335
                page[len] = '\0';
336
                for (p = page-1; p; p = next) {
337
                        next = strchr(++p, '\n');
338
                        if (*p++ != '\t')
339
                                continue;
340
                        while ((*s++ = *p++) != '\n')
341
                                ;
342
                        s[-1] = '\0';
343
                }
344
        }
345
        *s = '\0';
346
}
347
static void __init mount_block_root(char *name, int flags)
348
{
349
        char *fs_names = __getname();
350
        char *p;
351
 
352
        get_fs_names(fs_names);
353
retry:
354
        for (p = fs_names; *p; p += strlen(p)+1) {
355
                int err = sys_mount(name, "/root", p, flags, root_mount_data);
356
                switch (err) {
357
                        case 0:
358
                                goto out;
359
                        case -EACCES:
360
                                flags |= MS_RDONLY;
361
                                goto retry;
362
                        case -EINVAL:
363
                        case -EBUSY:
364
                                continue;
365
                }
366
                /*
367
                 * Allow the user to distinguish between failed open
368
                 * and bad superblock on root device.
369
                 */
370
                printk ("VFS: Cannot open root device \"%s\" or %s\n",
371
                        root_device_name, kdevname (ROOT_DEV));
372
                printk ("Please append a correct \"root=\" boot option\n");
373
                panic("VFS: Unable to mount root fs on %s",
374
                        kdevname(ROOT_DEV));
375
        }
376
        panic("VFS: Unable to mount root fs on %s", kdevname(ROOT_DEV));
377
out:
378
        putname(fs_names);
379
        sys_chdir("/root");
380
        ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
381
        printk("VFS: Mounted root (%s filesystem)%s.\n",
382
                current->fs->pwdmnt->mnt_sb->s_type->name,
383
                (current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY) ? " readonly" : "");
384
}
385
 
386
#ifdef CONFIG_ROOT_NFS
387
static int __init mount_nfs_root(void)
388
{
389
        void *data = nfs_root_data();
390
 
391
        if (data && sys_mount("/dev/root","/root","nfs",root_mountflags,data) == 0)
392
                return 1;
393
        return 0;
394
}
395
#endif
396
 
397
static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
398
{
399
        void *handle;
400
        char path[64];
401
        int n;
402
 
403
        sys_unlink(name);
404
        if (!do_devfs)
405
                return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));
406
 
407
        handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
408
                                MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
409
        if (!handle)
410
                return -1;
411
        n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
412
        if (n < 0)
413
                return -1;
414
        return sys_symlink(path + n + 5, name);
415
}
416
 
417
#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
418
static void __init change_floppy(char *fmt, ...)
419
{
420
        struct termios termios;
421
        char buf[80];
422
        char c;
423
        int fd;
424
        va_list args;
425
        va_start(args, fmt);
426
        vsprintf(buf, fmt, args);
427
        va_end(args);
428
        fd = open("/dev/root", O_RDWR | O_NDELAY, 0);
429
        if (fd >= 0) {
430
                sys_ioctl(fd, FDEJECT, 0);
431
                close(fd);
432
        }
433
        printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
434
        fd = open("/dev/console", O_RDWR, 0);
435
        if (fd >= 0) {
436
                sys_ioctl(fd, TCGETS, (long)&termios);
437
                termios.c_lflag &= ~ICANON;
438
                sys_ioctl(fd, TCSETSF, (long)&termios);
439
                read(fd, &c, 1);
440
                termios.c_lflag |= ICANON;
441
                sys_ioctl(fd, TCSETSF, (long)&termios);
442
                close(fd);
443
        }
444
}
445
#endif
446
 
447
#ifdef CONFIG_BLK_DEV_RAM
448
 
449
int __initdata rd_prompt = 1;   /* 1 = prompt for RAM disk, 0 = don't prompt */
450
 
451
static int __init prompt_ramdisk(char *str)
452
{
453
        rd_prompt = simple_strtol(str,NULL,0) & 1;
454
        return 1;
455
}
456
__setup("prompt_ramdisk=", prompt_ramdisk);
457
 
458
int __initdata rd_image_start;          /* starting block # of image */
459
 
460
static int __init ramdisk_start_setup(char *str)
461
{
462
        rd_image_start = simple_strtol(str,NULL,0);
463
        return 1;
464
}
465
__setup("ramdisk_start=", ramdisk_start_setup);
466
 
467
static int __init crd_load(int in_fd, int out_fd);
468
 
469
/*
470
 * This routine tries to find a RAM disk image to load, and returns the
471
 * number of blocks to read for a non-compressed image, 0 if the image
472
 * is a compressed image, and -1 if an image with the right magic
473
 * numbers could not be found.
474
 *
475
 * We currently check for the following magic numbers:
476
 *      minix
477
 *      ext2
478
 *      romfs
479
 *      cramfs
480
 *      gzip
481
 */
482
static int __init
483
identify_ramdisk_image(int fd, int start_block)
484
{
485
        const int size = 512;
486
        struct minix_super_block *minixsb;
487
        struct ext2_super_block *ext2sb;
488
        struct romfs_super_block *romfsb;
489
        struct cramfs_super *cramfsb;
490
        int nblocks = -1;
491
        unsigned char *buf;
492
 
493
        buf = kmalloc(size, GFP_KERNEL);
494
        if (buf == 0)
495
                return -1;
496
 
497
        minixsb = (struct minix_super_block *) buf;
498
        ext2sb = (struct ext2_super_block *) buf;
499
        romfsb = (struct romfs_super_block *) buf;
500
        cramfsb = (struct cramfs_super *) buf;
501
        memset(buf, 0xe5, size);
502
 
503
        /*
504
         * Read block 0 to test for gzipped kernel
505
         */
506
        lseek(fd, start_block * BLOCK_SIZE, 0);
507
        read(fd, buf, size);
508
 
509
        /*
510
         * If it matches the gzip magic numbers, return -1
511
         */
512
        if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
513
                printk(KERN_NOTICE
514
                       "RAMDISK: Compressed image found at block %d\n",
515
                       start_block);
516
                nblocks = 0;
517
                goto done;
518
        }
519
 
520
        /* romfs is at block zero too */
521
        if (romfsb->word0 == ROMSB_WORD0 &&
522
            romfsb->word1 == ROMSB_WORD1) {
523
                printk(KERN_NOTICE
524
                       "RAMDISK: romfs filesystem found at block %d\n",
525
                       start_block);
526
                nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
527
                goto done;
528
        }
529
 
530
        if (cramfsb->magic == CRAMFS_MAGIC) {
531
                printk(KERN_NOTICE
532
                       "RAMDISK: cramfs filesystem found at block %d\n",
533
                       start_block);
534
                nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
535
                goto done;
536
        }
537
 
538
        /*
539
         * Read block 1 to test for minix and ext2 superblock
540
         */
541
        lseek(fd, (start_block+1) * BLOCK_SIZE, 0);
542
        read(fd, buf, size);
543
 
544
        /* Try minix */
545
        if (minixsb->s_magic == MINIX_SUPER_MAGIC ||
546
            minixsb->s_magic == MINIX_SUPER_MAGIC2) {
547
                printk(KERN_NOTICE
548
                       "RAMDISK: Minix filesystem found at block %d\n",
549
                       start_block);
550
                nblocks = minixsb->s_nzones << minixsb->s_log_zone_size;
551
                goto done;
552
        }
553
 
554
        /* Try ext2 */
555
        if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) {
556
                printk(KERN_NOTICE
557
                       "RAMDISK: ext2 filesystem found at block %d\n",
558
                       start_block);
559
                nblocks = le32_to_cpu(ext2sb->s_blocks_count);
560
                goto done;
561
        }
562
 
563
        printk(KERN_NOTICE
564
               "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",
565
               start_block);
566
 
567
done:
568
        lseek(fd, start_block * BLOCK_SIZE, 0);
569
        kfree(buf);
570
        return nblocks;
571
}
572
#endif
573
 
574
static int __init rd_load_image(char *from)
575
{
576
        int res = 0;
577
 
578
#ifdef CONFIG_BLK_DEV_RAM
579
        int in_fd, out_fd;
580
        unsigned long rd_blocks, devblocks;
581
        int nblocks, i;
582
        char *buf;
583
        unsigned short rotate = 0;
584
#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
585
        char rotator[4] = { '|' , '/' , '-' , '\\' };
586
#endif
587
 
588
        out_fd = open("/dev/ram", O_RDWR, 0);
589
        if (out_fd < 0)
590
                goto out;
591
 
592
        in_fd = open(from, O_RDONLY, 0);
593
        if (in_fd < 0)
594
                goto noclose_input;
595
 
596
        nblocks = identify_ramdisk_image(in_fd, rd_image_start);
597
        if (nblocks < 0)
598
                goto done;
599
 
600
        if (nblocks == 0) {
601
#ifdef BUILD_CRAMDISK
602
                if (crd_load(in_fd, out_fd) == 0)
603
                        goto successful_load;
604
#else
605
                printk(KERN_NOTICE
606
                       "RAMDISK: Kernel does not support compressed "
607
                       "RAM disk images\n");
608
#endif
609
                goto done;
610
        }
611
 
612
        /*
613
         * NOTE NOTE: nblocks suppose that the blocksize is BLOCK_SIZE, so
614
         * rd_load_image will work only with filesystem BLOCK_SIZE wide!
615
         * So make sure to use 1k blocksize while generating ext2fs
616
         * ramdisk-images.
617
         */
618
        if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0)
619
                rd_blocks = 0;
620
        else
621
                rd_blocks >>= 1;
622
 
623
        if (nblocks > rd_blocks) {
624
                printk("RAMDISK: image too big! (%d/%lu blocks)\n",
625
                       nblocks, rd_blocks);
626
                goto done;
627
        }
628
 
629
        /*
630
         * OK, time to copy in the data
631
         */
632
        buf = kmalloc(BLOCK_SIZE, GFP_KERNEL);
633
        if (buf == 0) {
634
                printk(KERN_ERR "RAMDISK: could not allocate buffer\n");
635
                goto done;
636
        }
637
 
638
        if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0)
639
                devblocks = 0;
640
        else
641
                devblocks >>= 1;
642
 
643
        if (strcmp(from, "/dev/initrd") == 0)
644
                devblocks = nblocks;
645
 
646
        if (devblocks == 0) {
647
                printk(KERN_ERR "RAMDISK: could not determine device size\n");
648
                goto done;
649
        }
650
 
651
        printk(KERN_NOTICE "RAMDISK: Loading %d blocks [%ld disk%s] into ram disk... ",
652
                nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : "");
653
        for (i=0; i < nblocks; i++) {
654
                if (i && (i % devblocks == 0)) {
655
                        printk("done disk #%ld.\n", i/devblocks);
656
                        rotate = 0;
657
                        if (close(in_fd)) {
658
                                printk("Error closing the disk.\n");
659
                                goto noclose_input;
660
                        }
661
                        change_floppy("disk #%d", i/devblocks+1);
662
                        in_fd = open(from, O_RDONLY, 0);
663
                        if (in_fd < 0)  {
664
                                printk("Error opening disk.\n");
665
                                goto noclose_input;
666
                        }
667
                        printk("Loading disk #%ld... ", i/devblocks+1);
668
                }
669
                read(in_fd, buf, BLOCK_SIZE);
670
                write(out_fd, buf, BLOCK_SIZE);
671
#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
672
                if (!(i % 16)) {
673
                        printk("%c\b", rotator[rotate & 0x3]);
674
                        rotate++;
675
                }
676
#endif
677
        }
678
        printk("done.\n");
679
        kfree(buf);
680
 
681
successful_load:
682
        res = 1;
683
done:
684
        close(in_fd);
685
noclose_input:
686
        close(out_fd);
687
out:
688
        sys_unlink("/dev/ram");
689
#endif
690
        return res;
691
}
692
 
693
static int __init rd_load_disk(int n)
694
{
695
#ifdef CONFIG_BLK_DEV_RAM
696
        if (rd_prompt)
697
                change_floppy("root floppy disk to be loaded into RAM disk");
698
        create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
699
#endif
700
        return rd_load_image("/dev/root");
701
}
702
 
703
#ifdef CONFIG_DEVFS_FS
704
 
705
static void __init convert_name(char *prefix, char *name, char *p, int part)
706
{
707
        int host, bus, target, lun;
708
        char dest[64];
709
        char src[64];
710
        char *base = p - 1;
711
 
712
        /*  Decode "c#b#t#u#"  */
713
        if (*p++ != 'c')
714
                return;
715
        host = simple_strtol(p, &p, 10);
716
        if (*p++ != 'b')
717
                return;
718
        bus = simple_strtol(p, &p, 10);
719
        if (*p++ != 't')
720
                return;
721
        target = simple_strtol(p, &p, 10);
722
        if (*p++ != 'u')
723
                return;
724
        lun = simple_strtol(p, &p, 10);
725
        if (!part)
726
                sprintf(dest, "%s/host%d/bus%d/target%d/lun%d",
727
                                prefix, host, bus, target, lun);
728
        else if (*p++ == 'p')
729
                sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/part%s",
730
                                prefix, host, bus, target, lun, p);
731
        else
732
                sprintf(dest, "%s/host%d/bus%d/target%d/lun%d/disc",
733
                                prefix, host, bus, target, lun);
734
        *base = '\0';
735
        sprintf(src, "/dev/%s", name);
736
        sys_mkdir(src, 0755);
737
        *base = '/';
738
        sprintf(src, "/dev/%s", name);
739
        sys_symlink(dest, src);
740
}
741
 
742
static void __init devfs_make_root(char *name)
743
{
744
 
745
        if (!strncmp(name, "sd/", 3))
746
                convert_name("../scsi", name, name+3, 1);
747
        else if (!strncmp(name, "sr/", 3))
748
                convert_name("../scsi", name, name+3, 0);
749
        else if (!strncmp(name, "ide/hd/", 7))
750
                convert_name("..", name, name + 7, 1);
751
        else if (!strncmp(name, "ide/cd/", 7))
752
                convert_name("..", name, name + 7, 0);
753
}
754
#else
755
static void __init devfs_make_root(char *name)
756
{
757
}
758
#endif
759
 
760
static void __init mount_root(void)
761
{
762
#ifdef CONFIG_ROOT_NFS
763
       if (MAJOR(ROOT_DEV) == NFS_MAJOR
764
           && MINOR(ROOT_DEV) == NFS_MINOR) {
765
                if (mount_nfs_root()) {
766
                        sys_chdir("/root");
767
                        ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
768
                        printk("VFS: Mounted root (nfs filesystem).\n");
769
                        return;
770
                }
771
                printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
772
                ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
773
        }
774
#endif
775
        devfs_make_root(root_device_name);
776
        create_dev("/dev/root", ROOT_DEV, root_device_name);
777
#ifdef CONFIG_BLK_DEV_FD
778
        if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
779
                /* rd_doload is 2 for a dual initrd/ramload setup */
780
                if (rd_doload==2) {
781
                        if (rd_load_disk(1)) {
782
                                ROOT_DEV = MKDEV(RAMDISK_MAJOR, 1);
783
                                create_dev("/dev/root", ROOT_DEV, NULL);
784
                        }
785
                } else
786
                        change_floppy("root floppy");
787
        }
788
#endif
789
        mount_block_root("/dev/root", root_mountflags);
790
}
791
 
792
#ifdef CONFIG_BLK_DEV_INITRD
793
static int old_fd, root_fd;
794
static int do_linuxrc(void * shell)
795
{
796
        static char *argv[] = { "linuxrc", NULL, };
797
        extern char * envp_init[];
798
 
799
        close(old_fd);
800
        close(root_fd);
801
        close(0);
802
        close(1);
803
        close(2);
804
        setsid();
805
        (void) open("/dev/console",O_RDWR,0);
806
        (void) dup(0);
807
        (void) dup(0);
808
        return execve(shell, argv, envp_init);
809
}
810
 
811
#endif
812
 
813
static void __init handle_initrd(void)
814
{
815
#ifdef CONFIG_BLK_DEV_INITRD
816
        int ram0 = kdev_t_to_nr(MKDEV(RAMDISK_MAJOR,0));
817
        int error;
818
        int i, pid;
819
 
820
        create_dev("/dev/root.old", ram0, NULL);
821
        /* mount initrd on rootfs' /root */
822
        mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
823
        sys_mkdir("/old", 0700);
824
        root_fd = open("/", 0, 0);
825
        old_fd = open("/old", 0, 0);
826
        /* move initrd over / and chdir/chroot in initrd root */
827
        sys_chdir("/root");
828
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
829
        sys_chroot(".");
830
        mount_devfs_fs ();
831
 
832
        pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
833
        if (pid > 0) {
834
                while (pid != wait(&i))
835
                        yield();
836
        }
837
 
838
        /* move initrd to rootfs' /old */
839
        sys_fchdir(old_fd);
840
        sys_mount("/", ".", NULL, MS_MOVE, NULL);
841
        /* switch root and cwd back to / of rootfs */
842
        sys_fchdir(root_fd);
843
        sys_chroot(".");
844
        sys_umount("/old/dev", 0);
845
        close(old_fd);
846
        close(root_fd);
847
 
848
        if (real_root_dev == ram0) {
849
                sys_chdir("/old");
850
                return;
851
        }
852
 
853
        ROOT_DEV = real_root_dev;
854
        mount_root();
855
 
856
        printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
857
        error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
858
        if (!error)
859
                printk("okay\n");
860
        else {
861
                int fd = open("/dev/root.old", O_RDWR, 0);
862
                printk("failed\n");
863
                printk(KERN_NOTICE "Unmounting old root\n");
864
                sys_umount("/old", MNT_DETACH);
865
                printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
866
                if (fd < 0) {
867
                        error = fd;
868
                } else {
869
                        error = sys_ioctl(fd, BLKFLSBUF, 0);
870
                        close(fd);
871
                }
872
                printk(!error ? "okay\n" : "failed\n");
873
        }
874
#endif
875
}
876
 
877
static int __init initrd_load(void)
878
{
879
#ifdef CONFIG_BLK_DEV_INITRD
880
        create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL);
881
        create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL);
882
#endif
883
        return rd_load_image("/dev/initrd");
884
}
885
 
886
/*
887
 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
888
 */
889
void prepare_namespace(void)
890
{
891
        int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
892
#ifdef CONFIG_ALL_PPC
893
        extern void arch_discover_root(void);
894
        arch_discover_root();
895
#endif /* CONFIG_ALL_PPC */
896
#ifdef CONFIG_BLK_DEV_INITRD
897
        if (!initrd_start)
898
                mount_initrd = 0;
899
        real_root_dev = ROOT_DEV;
900
#endif
901
        sys_mkdir("/dev", 0700);
902
        sys_mkdir("/root", 0700);
903
        sys_mknod("/dev/console", S_IFCHR|0600, MKDEV(TTYAUX_MAJOR, 1));
904
#ifdef CONFIG_DEVFS_FS
905
        sys_mount("devfs", "/dev", "devfs", 0, NULL);
906
        do_devfs = 1;
907
#endif
908
 
909
        create_dev("/dev/root", ROOT_DEV, NULL);
910
        if (mount_initrd) {
911
                if (initrd_load() && ROOT_DEV != MKDEV(RAMDISK_MAJOR, 0)) {
912
                        handle_initrd();
913
                        goto out;
914
                }
915
        } else if (is_floppy && rd_doload && rd_load_disk(0))
916
                ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
917
        mount_root();
918
out:
919
        sys_umount("/dev", 0);
920
        sys_mount(".", "/", NULL, MS_MOVE, NULL);
921
        sys_chroot(".");
922
        mount_devfs_fs ();
923
}
924
 
925
#ifdef CONFIG_BLK_DEV_RAM
926
 
927
#if defined(BUILD_CRAMDISK) && defined(CONFIG_BLK_DEV_RAM)
928
 
929
/*
930
 * gzip declarations
931
 */
932
 
933
#define OF(args)  args
934
 
935
#ifndef memzero
936
#define memzero(s, n)     memset ((s), 0, (n))
937
#endif
938
 
939
typedef unsigned char  uch;
940
typedef unsigned short ush;
941
typedef unsigned long  ulg;
942
 
943
#define INBUFSIZ 4096
944
#define WSIZE 0x8000    /* window size--must be a power of two, and */
945
                        /*  at least 32K for zip's deflate method */
946
 
947
static uch *inbuf;
948
static uch *window;
949
 
950
static unsigned insize;  /* valid bytes in inbuf */
951
static unsigned inptr;   /* index of next byte to be processed in inbuf */
952
static unsigned outcnt;  /* bytes in output buffer */
953
static int exit_code;
954
static long bytes_out;
955
static int crd_infd, crd_outfd;
956
 
957
#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
958
 
959
/* Diagnostic functions (stubbed out) */
960
#define Assert(cond,msg)
961
#define Trace(x)
962
#define Tracev(x)
963
#define Tracevv(x)
964
#define Tracec(c,x)
965
#define Tracecv(c,x)
966
 
967
#define STATIC static
968
 
969
static int  fill_inbuf(void);
970
static void flush_window(void);
971
static void *malloc(int size);
972
static void free(void *where);
973
static void error(char *m);
974
static void gzip_mark(void **);
975
static void gzip_release(void **);
976
 
977
#include "../lib/inflate.c"
978
 
979
static void __init *malloc(int size)
980
{
981
        return kmalloc(size, GFP_KERNEL);
982
}
983
 
984
static void __init free(void *where)
985
{
986
        kfree(where);
987
}
988
 
989
static void __init gzip_mark(void **ptr)
990
{
991
}
992
 
993
static void __init gzip_release(void **ptr)
994
{
995
}
996
 
997
 
998
/* ===========================================================================
999
 * Fill the input buffer. This is called only when the buffer is empty
1000
 * and at least one byte is really needed.
1001
 */
1002
static int __init fill_inbuf(void)
1003
{
1004
        if (exit_code) return -1;
1005
 
1006
        insize = read(crd_infd, inbuf, INBUFSIZ);
1007
        if (insize == 0) return -1;
1008
 
1009
        inptr = 1;
1010
 
1011
        return inbuf[0];
1012
}
1013
 
1014
/* ===========================================================================
1015
 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
1016
 * (Used for the decompressed data only.)
1017
 */
1018
static void __init flush_window(void)
1019
{
1020
    ulg c = crc;         /* temporary variable */
1021
    unsigned n;
1022
    uch *in, ch;
1023
 
1024
    write(crd_outfd, window, outcnt);
1025
    in = window;
1026
    for (n = 0; n < outcnt; n++) {
1027
            ch = *in++;
1028
            c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
1029
    }
1030
    crc = c;
1031
    bytes_out += (ulg)outcnt;
1032
    outcnt = 0;
1033
}
1034
 
1035
static void __init error(char *x)
1036
{
1037
        printk(KERN_ERR "%s", x);
1038
        exit_code = 1;
1039
}
1040
 
1041
static int __init crd_load(int in_fd, int out_fd)
1042
{
1043
        int result;
1044
 
1045
        insize = 0;              /* valid bytes in inbuf */
1046
        inptr = 0;               /* index of next byte to be processed in inbuf */
1047
        outcnt = 0;              /* bytes in output buffer */
1048
        exit_code = 0;
1049
        bytes_out = 0;
1050
        crc = (ulg)0xffffffffL; /* shift register contents */
1051
 
1052
        crd_infd = in_fd;
1053
        crd_outfd = out_fd;
1054
        inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
1055
        if (inbuf == 0) {
1056
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n");
1057
                return -1;
1058
        }
1059
        window = kmalloc(WSIZE, GFP_KERNEL);
1060
        if (window == 0) {
1061
                printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n");
1062
                kfree(inbuf);
1063
                return -1;
1064
        }
1065
        makecrc();
1066
        result = gunzip();
1067
        kfree(inbuf);
1068
        kfree(window);
1069
        return result;
1070
}
1071
 
1072
#endif  /* BUILD_CRAMDISK && CONFIG_BLK_DEV_RAM */
1073
#endif  /* CONFIG_BLK_DEV_RAM */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.