8278bfc1507d19c0cbd49cef733892250a8b30d1
[linux-flexiantxendom0-3.2.10.git] / init / main.c
1 /*
2  *  linux/init/main.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *
6  *  GK 2/5/95  -  Changed to support mounting root fs via NFS
7  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
8  *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
9  *  Simplified starting of init:  Michael A. Griffith <grif@acm.org> 
10  */
11
12 #define __KERNEL_SYSCALLS__
13
14 #include <linux/config.h>
15 #include <linux/proc_fs.h>
16 #include <linux/devfs_fs_kernel.h>
17 #include <linux/unistd.h>
18 #include <linux/string.h>
19 #include <linux/ctype.h>
20 #include <linux/delay.h>
21 #include <linux/utsname.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/smp_lock.h>
25 #include <linux/blk.h>
26 #include <linux/hdreg.h>
27 #include <linux/iobuf.h>
28 #include <linux/bootmem.h>
29 #include <linux/tty.h>
30
31 #include <asm/io.h>
32 #include <asm/bugs.h>
33
34 #if defined(CONFIG_ARCH_S390)
35 #include <asm/s390mach.h>
36 #include <asm/ccwcache.h>
37 #endif
38
39 #ifdef CONFIG_PCI
40 #include <linux/pci.h>
41 #endif
42
43 #ifdef CONFIG_DIO
44 #include <linux/dio.h>
45 #endif
46
47 #ifdef CONFIG_ZORRO
48 #include <linux/zorro.h>
49 #endif
50
51 #ifdef CONFIG_MTRR
52 #  include <asm/mtrr.h>
53 #endif
54
55 #ifdef CONFIG_NUBUS
56 #include <linux/nubus.h>
57 #endif
58
59 #ifdef CONFIG_ISAPNP
60 #include <linux/isapnp.h>
61 #endif
62
63 #ifdef CONFIG_IRDA
64 extern int irda_proto_init(void);
65 extern int irda_device_init(void);
66 #endif
67
68 #ifdef CONFIG_X86_LOCAL_APIC
69 #include <asm/smp.h>
70 #endif
71
72 /*
73  * Versions of gcc older than that listed below may actually compile
74  * and link okay, but the end product can have subtle run time bugs.
75  * To avoid associated bogus bug reports, we flatly refuse to compile
76  * with a gcc that is known to be too old from the very beginning.
77  */
78 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)
79 #error Sorry, your GCC is too old. It builds incorrect kernels.
80 #endif
81
82 extern char _stext, _etext;
83 extern char *linux_banner;
84
85 static int init(void *);
86
87 extern void init_IRQ(void);
88 extern void init_modules(void);
89 extern void sock_init(void);
90 extern void fork_init(unsigned long);
91 extern void mca_init(void);
92 extern void sbus_init(void);
93 extern void ppc_init(void);
94 extern void sysctl_init(void);
95 extern void signals_init(void);
96 extern int init_pcmcia_ds(void);
97
98 extern void free_initmem(void);
99
100 #ifdef CONFIG_TC
101 extern void tc_init(void);
102 #endif
103
104 extern void ecard_init(void);
105
106 #if defined(CONFIG_SYSVIPC)
107 extern void ipc_init(void);
108 #endif
109
110 /*
111  * Boot command-line arguments
112  */
113 #define MAX_INIT_ARGS 8
114 #define MAX_INIT_ENVS 8
115
116 extern void time_init(void);
117 extern void softirq_init(void);
118
119 int rows, cols;
120
121 #ifdef CONFIG_BLK_DEV_INITRD
122 kdev_t real_root_dev;
123 #endif
124
125 int root_mountflags = MS_RDONLY;
126 char *execute_command;
127 char root_device_name[64];
128
129
130 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
131 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
132
133 static int __init profile_setup(char *str)
134 {
135     int par;
136     if (get_option(&str,&par)) prof_shift = par;
137         return 1;
138 }
139
140 __setup("profile=", profile_setup);
141
142
143 static struct dev_name_struct {
144         const char *name;
145         const int num;
146 } root_dev_names[] __initdata = {
147         { "nfs",     0x00ff },
148         { "hda",     0x0300 },
149         { "hdb",     0x0340 },
150         { "loop",    0x0700 },
151         { "hdc",     0x1600 },
152         { "hdd",     0x1640 },
153         { "hde",     0x2100 },
154         { "hdf",     0x2140 },
155         { "hdg",     0x2200 },
156         { "hdh",     0x2240 },
157         { "hdi",     0x3800 },
158         { "hdj",     0x3840 },
159         { "hdk",     0x3900 },
160         { "hdl",     0x3940 },
161         { "hdm",     0x5800 },
162         { "hdn",     0x5840 },
163         { "hdo",     0x5900 },
164         { "hdp",     0x5940 },
165         { "hdq",     0x5A00 },
166         { "hdr",     0x5A40 },
167         { "hds",     0x5B00 },
168         { "hdt",     0x5B40 },
169         { "sda",     0x0800 },
170         { "sdb",     0x0810 },
171         { "sdc",     0x0820 },
172         { "sdd",     0x0830 },
173         { "sde",     0x0840 },
174         { "sdf",     0x0850 },
175         { "sdg",     0x0860 },
176         { "sdh",     0x0870 },
177         { "sdi",     0x0880 },
178         { "sdj",     0x0890 },
179         { "sdk",     0x08a0 },
180         { "sdl",     0x08b0 },
181         { "sdm",     0x08c0 },
182         { "sdn",     0x08d0 },
183         { "sdo",     0x08e0 },
184         { "sdp",     0x08f0 },
185         { "ada",     0x1c00 },
186         { "adb",     0x1c10 },
187         { "adc",     0x1c20 },
188         { "add",     0x1c30 },
189         { "ade",     0x1c40 },
190         { "fd",      0x0200 },
191         { "md",      0x0900 },       
192         { "xda",     0x0d00 },
193         { "xdb",     0x0d40 },
194         { "ram",     0x0100 },
195         { "scd",     0x0b00 },
196         { "mcd",     0x1700 },
197         { "cdu535",  0x1800 },
198         { "sonycd",  0x1800 },
199         { "aztcd",   0x1d00 },
200         { "cm206cd", 0x2000 },
201         { "gscd",    0x1000 },
202         { "sbpcd",   0x1900 },
203         { "eda",     0x2400 },
204         { "edb",     0x2440 },
205         { "pda",        0x2d00 },
206         { "pdb",        0x2d10 },
207         { "pdc",        0x2d20 },
208         { "pdd",        0x2d30 },
209         { "pcd",        0x2e00 },
210         { "pf",         0x2f00 },
211         { "apblock", APBLOCK_MAJOR << 8},
212         { "ddv", DDV_MAJOR << 8},
213         { "jsfd",    JSFD_MAJOR << 8},
214 #if defined(CONFIG_ARCH_S390)
215         { "dasda", (DASD_MAJOR << MINORBITS) },
216         { "dasdb", (DASD_MAJOR << MINORBITS) + (1 << 2) },
217         { "dasdc", (DASD_MAJOR << MINORBITS) + (2 << 2) },
218         { "dasdd", (DASD_MAJOR << MINORBITS) + (3 << 2) },
219         { "dasde", (DASD_MAJOR << MINORBITS) + (4 << 2) },
220         { "dasdf", (DASD_MAJOR << MINORBITS) + (5 << 2) },
221         { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
222         { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
223 #endif
224 #if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
225         { "ida/c0d0p",0x4800 },
226         { "ida/c0d1p",0x4810 },
227         { "ida/c0d2p",0x4820 },
228         { "ida/c0d3p",0x4830 },
229         { "ida/c0d4p",0x4840 },
230         { "ida/c0d5p",0x4850 },
231         { "ida/c0d6p",0x4860 },
232         { "ida/c0d7p",0x4870 },
233         { "ida/c0d8p",0x4880 },
234         { "ida/c0d9p",0x4890 },
235         { "ida/c0d10p",0x48A0 },
236         { "ida/c0d11p",0x48B0 },
237         { "ida/c0d12p",0x48C0 },
238         { "ida/c0d13p",0x48D0 },
239         { "ida/c0d14p",0x48E0 },
240         { "ida/c0d15p",0x48F0 },
241 #endif
242 #if defined(CONFIG_BLK_CPQ_CISS_DA) || defined(CONFIG_BLK_CPQ_CISS_DA_MODULE)
243         { "cciss/c0d0p",0x6800 },
244         { "cciss/c0d1p",0x6810 },
245         { "cciss/c0d2p",0x6820 },
246         { "cciss/c0d3p",0x6830 },
247         { "cciss/c0d4p",0x6840 },
248         { "cciss/c0d5p",0x6850 },
249         { "cciss/c0d6p",0x6860 },
250         { "cciss/c0d7p",0x6870 },
251         { "cciss/c0d8p",0x6880 },
252         { "cciss/c0d9p",0x6890 },
253         { "cciss/c0d10p",0x68A0 },
254         { "cciss/c0d11p",0x68B0 },
255         { "cciss/c0d12p",0x68C0 },
256         { "cciss/c0d13p",0x68D0 },
257         { "cciss/c0d14p",0x68E0 },
258         { "cciss/c0d15p",0x68F0 },
259 #endif
260         { "nftla", 0x5d00 },
261         { "nftlb", 0x5d10 },
262         { "nftlc", 0x5d20 },
263         { "nftld", 0x5d30 },
264         { "ftla", 0x2c00 },
265         { "ftlb", 0x2c08 },
266         { "ftlc", 0x2c10 },
267         { "ftld", 0x2c18 },
268         { "mtdblock", 0x1f00 },
269         { NULL, 0 }
270 };
271
272 kdev_t __init name_to_kdev_t(char *line)
273 {
274         int base = 0;
275
276         if (strncmp(line,"/dev/",5) == 0) {
277                 struct dev_name_struct *dev = root_dev_names;
278                 line += 5;
279                 do {
280                         int len = strlen(dev->name);
281                         if (strncmp(line,dev->name,len) == 0) {
282                                 line += len;
283                                 base = dev->num;
284                                 break;
285                         }
286                         dev++;
287                 } while (dev->name);
288         }
289         return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
290 }
291
292 static int __init root_dev_setup(char *line)
293 {
294         int i;
295         char ch;
296
297         ROOT_DEV = name_to_kdev_t(line);
298         memset (root_device_name, 0, sizeof root_device_name);
299         if (strncmp (line, "/dev/", 5) == 0) line += 5;
300         for (i = 0; i < sizeof root_device_name - 1; ++i)
301         {
302             ch = line[i];
303             if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
304             root_device_name[i] = ch;
305         }
306         return 1;
307 }
308
309 __setup("root=", root_dev_setup);
310
311 static int __init checksetup(char *line)
312 {
313         struct kernel_param *p;
314
315         p = &__setup_start;
316         do {
317                 int n = strlen(p->str);
318                 if (!strncmp(line,p->str,n)) {
319                         if (p->setup_func(line+n))
320                                 return 1;
321                 }
322                 p++;
323         } while (p < &__setup_end);
324         return 0;
325 }
326
327 /* this should be approx 2 Bo*oMips to start (note initial shift), and will
328    still work even if initially too large, it will just take slightly longer */
329 unsigned long loops_per_jiffy = (1<<12);
330
331 /* This is the number of bits of precision for the loops_per_jiffy.  Each
332    bit takes on average 1.5/HZ seconds.  This (like the original) is a little
333    better than 1% */
334 #define LPS_PREC 8
335
336 void __init calibrate_delay(void)
337 {
338         unsigned long ticks, loopbit;
339         int lps_precision = LPS_PREC;
340
341         loops_per_jiffy = (1<<12);
342
343         printk("Calibrating delay loop... ");
344         while (loops_per_jiffy <<= 1) {
345                 /* wait for "start of" clock tick */
346                 ticks = jiffies;
347                 while (ticks == jiffies)
348                         /* nothing */;
349                 /* Go .. */
350                 ticks = jiffies;
351                 __delay(loops_per_jiffy);
352                 ticks = jiffies - ticks;
353                 if (ticks)
354                         break;
355         }
356
357 /* Do a binary approximation to get loops_per_jiffy set to equal one clock
358    (up to lps_precision bits) */
359         loops_per_jiffy >>= 1;
360         loopbit = loops_per_jiffy;
361         while ( lps_precision-- && (loopbit >>= 1) ) {
362                 loops_per_jiffy |= loopbit;
363                 ticks = jiffies;
364                 while (ticks == jiffies);
365                 ticks = jiffies;
366                 __delay(loops_per_jiffy);
367                 if (jiffies != ticks)   /* longer than 1 tick */
368                         loops_per_jiffy &= ~loopbit;
369         }
370
371 /* Round the value and print it */      
372         printk("%lu.%02lu BogoMIPS\n",
373                 loops_per_jiffy/(500000/HZ),
374                 (loops_per_jiffy/(5000/HZ)) % 100);
375 }
376
377 static int __init readonly(char *str)
378 {
379         if (*str)
380                 return 0;
381         root_mountflags |= MS_RDONLY;
382         return 1;
383 }
384
385 static int __init readwrite(char *str)
386 {
387         if (*str)
388                 return 0;
389         root_mountflags &= ~MS_RDONLY;
390         return 1;
391 }
392
393 static int __init debug_kernel(char *str)
394 {
395         if (*str)
396                 return 0;
397         console_loglevel = 10;
398         return 1;
399 }
400
401 static int __init quiet_kernel(char *str)
402 {
403         if (*str)
404                 return 0;
405         console_loglevel = 4;
406         return 1;
407 }
408
409 __setup("ro", readonly);
410 __setup("rw", readwrite);
411 __setup("debug", debug_kernel);
412 __setup("quiet", quiet_kernel);
413
414 /*
415  * This is a simple kernel command line parsing function: it parses
416  * the command line, and fills in the arguments/environment to init
417  * as appropriate. Any cmd-line option is taken to be an environment
418  * variable if it contains the character '='.
419  *
420  * This routine also checks for options meant for the kernel.
421  * These options are not given to init - they are for internal kernel use only.
422  */
423 static void __init parse_options(char *line)
424 {
425         char *next,*quote;
426         int args, envs;
427
428         if (!*line)
429                 return;
430         args = 0;
431         envs = 1;       /* TERM is set to 'linux' by default */
432         next = line;
433         while ((line = next) != NULL) {
434                 quote = strchr(line,'"');
435                 next = strchr(line, ' ');
436                 while (next != NULL && quote != NULL && quote < next) {
437                         /* we found a left quote before the next blank
438                          * now we have to find the matching right quote
439                          */
440                         next = strchr(quote+1, '"');
441                         if (next != NULL) {
442                                 quote = strchr(next+1, '"');
443                                 next = strchr(next+1, ' ');
444                         }
445                 }
446                 if (next != NULL)
447                         *next++ = 0;
448                 if (!strncmp(line,"init=",5)) {
449                         line += 5;
450                         execute_command = line;
451                         /* In case LILO is going to boot us with default command line,
452                          * it prepends "auto" before the whole cmdline which makes
453                          * the shell think it should execute a script with such name.
454                          * So we ignore all arguments entered _before_ init=... [MJ]
455                          */
456                         args = 0;
457                         continue;
458                 }
459                 if (checksetup(line))
460                         continue;
461                 
462                 /*
463                  * Then check if it's an environment variable or
464                  * an option.
465                  */
466                 if (strchr(line,'=')) {
467                         if (envs >= MAX_INIT_ENVS)
468                                 break;
469                         envp_init[++envs] = line;
470                 } else {
471                         if (args >= MAX_INIT_ARGS)
472                                 break;
473                         if (*line)
474                                 argv_init[++args] = line;
475                 }
476         }
477         argv_init[args+1] = NULL;
478         envp_init[envs+1] = NULL;
479 }
480
481
482 extern void setup_arch(char **);
483 extern void cpu_idle(void);
484
485 volatile unsigned long wait_init_idle = 0UL;
486
487 #ifndef CONFIG_SMP
488
489 #ifdef CONFIG_X86_LOCAL_APIC
490 static void __init smp_init(void)
491 {
492         APIC_init_uniprocessor();
493 }
494 #else
495 #define smp_init()      do { } while (0)
496 #endif
497
498 #else
499
500
501 /* Called by boot processor to activate the rest. */
502 static void __init smp_init(void)
503 {
504         /* Get other processors into their bootup holding patterns. */
505         smp_boot_cpus();
506         wait_init_idle = cpu_online_map;
507         clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
508         printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle);
509         smp_threads_ready=1;
510         smp_commence();
511
512         /* Wait for the other cpus to set up their idle processes */
513         while (1) {
514                 if (!wait_init_idle)
515                         break;
516                 rep_nop();
517         }
518         printk("All processors have done init_idle\n");
519 }               
520
521 #endif
522
523 /*
524  * We need to finalize in a non-__init function or else race conditions
525  * between the root thread and the init thread may cause start_kernel to
526  * be reaped by free_initmem before the root thread has proceeded to
527  * cpu_idle.
528  */
529
530 static void rest_init(void)
531 {
532         kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
533         unlock_kernel();
534         current->need_resched = 1;
535         cpu_idle();
536
537
538 /*
539  *      Activate the first processor.
540  */
541
542 asmlinkage void __init start_kernel(void)
543 {
544         char * command_line;
545         unsigned long mempages;
546         extern char saved_command_line[];
547 /*
548  * Interrupts are still disabled. Do necessary setups, then
549  * enable them
550  */
551         lock_kernel();
552         printk(linux_banner);
553         setup_arch(&command_line);
554         printk("Kernel command line: %s\n", saved_command_line);
555         parse_options(command_line);
556         trap_init();
557         init_IRQ();
558         sched_init();
559         softirq_init();
560         time_init();
561
562         /*
563          * HACK ALERT! This is early. We're enabling the console before
564          * we've done PCI setups etc, and console_init() must be aware of
565          * this. But we do want output early, in case something goes wrong.
566          */
567         console_init();
568 #ifdef CONFIG_MODULES
569         init_modules();
570 #endif
571         if (prof_shift) {
572                 unsigned int size;
573                 /* only text is profiled */
574                 prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
575                 prof_len >>= prof_shift;
576                 
577                 size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
578                 prof_buffer = (unsigned int *) alloc_bootmem(size);
579         }
580
581         kmem_cache_init();
582         sti();
583         calibrate_delay();
584 #ifdef CONFIG_BLK_DEV_INITRD
585         if (initrd_start && !initrd_below_start_ok &&
586                         initrd_start < min_low_pfn << PAGE_SHIFT) {
587                 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
588                     "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
589                 initrd_start = 0;
590         }
591 #endif
592         mem_init();
593         kmem_cache_sizes_init();
594         mempages = num_physpages;
595
596         fork_init(mempages);
597         proc_caches_init();
598         vfs_caches_init(mempages);
599         buffer_init(mempages);
600         page_cache_init(mempages);
601 #if defined(CONFIG_ARCH_S390)
602         ccwcache_init();
603 #endif
604         signals_init();
605 #ifdef CONFIG_PROC_FS
606         proc_root_init();
607 #endif
608 #if defined(CONFIG_SYSVIPC)
609         ipc_init();
610 #endif
611         check_bugs();
612         printk("POSIX conformance testing by UNIFIX\n");
613
614         /* 
615          *      We count on the initial thread going ok 
616          *      Like idlers init is an unlocked kernel thread, which will
617          *      make syscalls (and thus be locked).
618          */
619         smp_init();
620         rest_init();
621 }
622
623 #ifdef CONFIG_BLK_DEV_INITRD
624 static int do_linuxrc(void * shell)
625 {
626         static char *argv[] = { "linuxrc", NULL, };
627
628         close(0);close(1);close(2);
629         setsid();
630         (void) open("/dev/console",O_RDWR,0);
631         (void) dup(0);
632         (void) dup(0);
633         return execve(shell, argv, envp_init);
634 }
635
636 #endif
637
638 struct task_struct *child_reaper = &init_task;
639
640 static void __init do_initcalls(void)
641 {
642         initcall_t *call;
643
644         call = &__initcall_start;
645         do {
646                 (*call)();
647                 call++;
648         } while (call < &__initcall_end);
649
650         /* Make sure there is no pending stuff from the initcall sequence */
651         flush_scheduled_tasks();
652 }
653
654 /*
655  * Ok, the machine is now initialized. None of the devices
656  * have been touched yet, but the CPU subsystem is up and
657  * running, and memory and process management works.
658  *
659  * Now we can finally start doing some real work..
660  */
661 static void __init do_basic_setup(void)
662 {
663
664         /*
665          * Tell the world that we're going to be the grim
666          * reaper of innocent orphaned children.
667          *
668          * We don't want people to have to make incorrect
669          * assumptions about where in the task array this
670          * can be found.
671          */
672         child_reaper = current;
673
674 #if defined(CONFIG_MTRR)        /* Do this after SMP initialization */
675 /*
676  * We should probably create some architecture-dependent "fixup after
677  * everything is up" style function where this would belong better
678  * than in init/main.c..
679  */
680         mtrr_init();
681 #endif
682
683 #ifdef CONFIG_SYSCTL
684         sysctl_init();
685 #endif
686
687         /*
688          * Ok, at this point all CPU's should be initialized, so
689          * we can start looking into devices..
690          */
691 #if defined(CONFIG_ARCH_S390)
692         s390_init_machine_check();
693 #endif
694
695 #ifdef CONFIG_PCI
696         pci_init();
697 #endif
698 #ifdef CONFIG_SBUS
699         sbus_init();
700 #endif
701 #if defined(CONFIG_PPC)
702         ppc_init();
703 #endif
704 #ifdef CONFIG_MCA
705         mca_init();
706 #endif
707 #ifdef CONFIG_ARCH_ACORN
708         ecard_init();
709 #endif
710 #ifdef CONFIG_ZORRO
711         zorro_init();
712 #endif
713 #ifdef CONFIG_DIO
714         dio_init();
715 #endif
716 #ifdef CONFIG_NUBUS
717         nubus_init();
718 #endif
719 #ifdef CONFIG_ISAPNP
720         isapnp_init();
721 #endif
722 #ifdef CONFIG_TC
723         tc_init();
724 #endif
725
726         /* Networking initialization needs a process context */ 
727         sock_init();
728
729         start_context_thread();
730         do_initcalls();
731
732 #ifdef CONFIG_IRDA
733         irda_proto_init();
734         irda_device_init(); /* Must be done after protocol initialization */
735 #endif
736 #ifdef CONFIG_PCMCIA
737         init_pcmcia_ds();               /* Do this last */
738 #endif
739 }
740
741 extern void rd_load(void);
742 extern void initrd_load(void);
743
744 /*
745  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
746  */
747 static void prepare_namespace(void)
748 {
749 #ifdef CONFIG_BLK_DEV_INITRD
750         int real_root_mountflags = root_mountflags;
751         if (!initrd_start)
752                 mount_initrd = 0;
753         if (mount_initrd)
754                 root_mountflags &= ~MS_RDONLY;
755         real_root_dev = ROOT_DEV;
756 #endif
757
758 #ifdef CONFIG_BLK_DEV_RAM
759 #ifdef CONFIG_BLK_DEV_INITRD
760         if (mount_initrd)
761                 initrd_load();
762         else
763 #endif
764         rd_load();
765 #endif
766
767         /* Mount the root filesystem.. */
768         mount_root();
769
770         mount_devfs_fs ();
771
772 #ifdef CONFIG_BLK_DEV_INITRD
773         root_mountflags = real_root_mountflags;
774         if (mount_initrd && ROOT_DEV != real_root_dev
775             && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
776                 int error;
777                 int i, pid;
778
779                 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
780                 if (pid>0)
781                         while (pid != wait(&i));
782                 if (MAJOR(real_root_dev) != RAMDISK_MAJOR
783                      || MINOR(real_root_dev) != 0) {
784                         error = change_root(real_root_dev,"/initrd");
785                         if (error)
786                                 printk(KERN_ERR "Change root to /initrd: "
787                                     "error %d\n",error);
788                 }
789         }
790 #endif
791 }
792
793 static int init(void * unused)
794 {
795         lock_kernel();
796         do_basic_setup();
797
798         prepare_namespace();
799
800         /*
801          * Ok, we have completed the initial bootup, and
802          * we're essentially up and running. Get rid of the
803          * initmem segments and start the user-mode stuff..
804          */
805         free_initmem();
806         unlock_kernel();
807
808         if (open("/dev/console", O_RDWR, 0) < 0)
809                 printk("Warning: unable to open an initial console.\n");
810
811         (void) dup(0);
812         (void) dup(0);
813         
814         /*
815          * We try each of these until one succeeds.
816          *
817          * The Bourne shell can be used instead of init if we are 
818          * trying to recover a really broken machine.
819          */
820
821         if (execute_command)
822                 execve(execute_command,argv_init,envp_init);
823         execve("/sbin/init",argv_init,envp_init);
824         execve("/etc/init",argv_init,envp_init);
825         execve("/bin/init",argv_init,envp_init);
826         execve("/bin/sh",argv_init,envp_init);
827         panic("No init found.  Try passing init= option to kernel.");
828 }