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