Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
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/raid/md.h>
25 #include <linux/smp_lock.h>
26 #include <linux/blk.h>
27 #include <linux/hdreg.h>
28 #include <linux/iobuf.h>
29 #include <linux/bootmem.h>
30
31 #include <asm/io.h>
32 #include <asm/bugs.h>
33
34 #ifdef CONFIG_PCI
35 #include <linux/pci.h>
36 #endif
37
38 #ifdef CONFIG_DIO
39 #include <linux/dio.h>
40 #endif
41
42 #ifdef CONFIG_ZORRO
43 #include <linux/zorro.h>
44 #endif
45
46 #ifdef CONFIG_MTRR
47 # include <asm/mtrr.h>
48 #endif
49
50 #ifdef CONFIG_MAC
51 extern void nubus_init(void);
52 #endif
53
54 #ifdef CONFIG_ISAPNP
55 #include <linux/isapnp.h>
56 #endif
57
58 #ifdef CONFIG_IRDA
59 #include <net/irda/irda_device.h>
60 #endif
61
62 #ifdef CONFIG_X86_IO_APIC
63 #include <asm/smp.h>
64 #endif
65
66 /*
67 * Versions of gcc older than that listed below may actually compile
68 * and link okay, but the end product can have subtle run time bugs.
69 * To avoid associated bogus bug reports, we flatly refuse to compile
70 * with a gcc that is known to be too old from the very beginning.
71 */
72 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
73 #error sorry, your GCC is too old. It builds incorrect kernels.
74 #endif
75
76 extern char _stext, _etext;
77 extern char *linux_banner;
78
79 extern int console_loglevel;
80
81 static int init(void *);
82
83 extern void init_IRQ(void);
84 extern void init_modules(void);
85 extern void sock_init(void);
86 extern void fork_init(unsigned long);
87 extern void mca_init(void);
88 extern void sbus_init(void);
89 extern void ppc_init(void);
90 extern void sysctl_init(void);
91 extern void filescache_init(void);
92 extern void signals_init(void);
93 extern void bdev_init(void);
94 extern int init_pcmcia_ds(void);
95 extern int usb_init(void);
96
97 extern void free_initmem(void);
98 extern void filesystem_setup(void);
99
100 extern void ecard_init(void);
101
102 #if defined(CONFIG_SYSVIPC)
103 extern void ipc_init(void);
104 #endif
105 #if defined(CONFIG_QUOTA)
106 extern void dquot_init_hash(void);
107 #endif
108
109 /*
110 * Boot command-line arguments
111 */
112 #define MAX_INIT_ARGS 8
113 #define MAX_INIT_ENVS 8
114
115 extern void time_init(void);
116 extern void softirq_init(void);
117
118 int rows, cols;
119
120 #ifdef CONFIG_BLK_DEV_INITRD
121 kdev_t real_root_dev;
122 #endif
123
124 int root_mountflags = MS_RDONLY;
125 char *execute_command = NULL;
126 char root_device_name[64];
127
128
129 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
130 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
131
132 /*
133 * Read an int from an option string; if available accept a subsequent
134 * comma as well.
135 *
136 * Return values:
137 * 0 : no int in string
138 * 1 : int found, no subsequent comma
139 * 2 : int found including a subsequent comma
140 */
141 int get_option(char **str, int *pint)
142 {
143 char *cur = *str;
144
145 if (!cur || !(*cur)) return 0;
146 *pint = simple_strtol(cur,str,0);
147 if (cur==*str) return 0;
148 if (**str==',') {
149 (*str)++;
150 return 2;
151 }
152
153 return 1;
154 }
155
156 char *get_options(char *str, int nints, int *ints)
157 {
158 int res,i=1;
159
160 while (i<nints) {
161 res = get_option(&str, ints+i);
162 if (res==0) break;
163 i++;
164 if (res==1) break;
165 }
166 ints[0] = i-1;
167 return(str);
168 }
169
170 static int __init profile_setup(char *str)
171 {
172 int par;
173 if (get_option(&str,&par)) prof_shift = par;
174 return 1;
175 }
176
177 __setup("profile=", profile_setup);
178
179
180 static struct dev_name_struct {
181 const char *name;
182 const int num;
183 } root_dev_names[] __initdata = {
184 { "nfs", 0x00ff },
185 { "hda", 0x0300 },
186 { "hdb", 0x0340 },
187 { "hdc", 0x1600 },
188 { "hdd", 0x1640 },
189 { "hde", 0x2100 },
190 { "hdf", 0x2140 },
191 { "hdg", 0x2200 },
192 { "hdh", 0x2240 },
193 { "hdi", 0x3800 },
194 { "hdj", 0x3840 },
195 { "hdk", 0x3900 },
196 { "hdl", 0x3940 },
197 { "hdm", 0x5800 },
198 { "hdn", 0x5840 },
199 { "hdo", 0x5900 },
200 { "hdp", 0x5940 },
201 { "hdq", 0x5A00 },
202 { "hdr", 0x5A40 },
203 { "hds", 0x5B00 },
204 { "hdt", 0x5B40 },
205 { "sda", 0x0800 },
206 { "sdb", 0x0810 },
207 { "sdc", 0x0820 },
208 { "sdd", 0x0830 },
209 { "sde", 0x0840 },
210 { "sdf", 0x0850 },
211 { "sdg", 0x0860 },
212 { "sdh", 0x0870 },
213 { "sdi", 0x0880 },
214 { "sdj", 0x0890 },
215 { "sdk", 0x08a0 },
216 { "sdl", 0x08b0 },
217 { "sdm", 0x08c0 },
218 { "sdn", 0x08d0 },
219 { "sdo", 0x08e0 },
220 { "sdp", 0x08f0 },
221 { "ada", 0x1c00 },
222 { "adb", 0x1c10 },
223 { "adc", 0x1c20 },
224 { "add", 0x1c30 },
225 { "ade", 0x1c40 },
226 { "fd", 0x0200 },
227 { "md", 0x0900 },
228 { "xda", 0x0d00 },
229 { "xdb", 0x0d40 },
230 { "ram", 0x0100 },
231 { "scd", 0x0b00 },
232 { "mcd", 0x1700 },
233 { "cdu535", 0x1800 },
234 { "sonycd", 0x1800 },
235 { "aztcd", 0x1d00 },
236 { "cm206cd", 0x2000 },
237 { "gscd", 0x1000 },
238 { "sbpcd", 0x1900 },
239 { "eda", 0x2400 },
240 { "edb", 0x2440 },
241 { "pda", 0x2d00 },
242 { "pdb", 0x2d10 },
243 { "pdc", 0x2d20 },
244 { "pdd", 0x2d30 },
245 { "pcd", 0x2e00 },
246 { "pf", 0x2f00 },
247 { "apblock", APBLOCK_MAJOR << 8},
248 { "ddv", DDV_MAJOR << 8},
249 { "fhd", 0x3e00 },
250 { NULL, 0 }
251 };
252
253 kdev_t __init name_to_kdev_t(char *line)
254 {
255 int base = 0;
256
257 if (strncmp(line,"/dev/",5) == 0) {
258 struct dev_name_struct *dev = root_dev_names;
259 line += 5;
260 do {
261 int len = strlen(dev->name);
262 if (strncmp(line,dev->name,len) == 0) {
263 line += len;
264 base = dev->num;
265 break;
266 }
267 dev++;
268 } while (dev->name);
269 }
270 return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
271 }
272
273 static int __init root_dev_setup(char *line)
274 {
275 int i;
276 char ch;
277
278 ROOT_DEV = name_to_kdev_t(line);
279 memset (root_device_name, 0, sizeof root_device_name);
280 if (strncmp (line, "/dev/", 5) == 0) line += 5;
281 for (i = 0; i < sizeof root_device_name - 1; ++i)
282 {
283 ch = line[i];
284 if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
285 root_device_name[i] = ch;
286 }
287 return 1;
288 }
289
290 __setup("root=", root_dev_setup);
291
292 static int __init checksetup(char *line)
293 {
294 struct kernel_param *p;
295
296 p = &__setup_start;
297 do {
298 int n = strlen(p->str);
299 if (!strncmp(line,p->str,n)) {
300 if (p->setup_func(line+n))
301 return 1;
302 }
303 p++;
304 } while (p < &__setup_end);
305 return 0;
306 }
307
308 /* this should be approx 2 Bo*oMips to start (note initial shift), and will
309 still work even if initially too large, it will just take slightly longer */
310 unsigned long loops_per_sec = (1<<12);
311
312 /* This is the number of bits of precision for the loops_per_second. Each
313 bit takes on average 1.5/HZ seconds. This (like the original) is a little
314 better than 1% */
315 #define LPS_PREC 8
316
317 void __init calibrate_delay(void)
318 {
319 unsigned long ticks, loopbit;
320 int lps_precision = LPS_PREC;
321
322 loops_per_sec = (1<<12);
323
324 printk("Calibrating delay loop... ");
325 while (loops_per_sec <<= 1) {
326 /* wait for "start of" clock tick */
327 ticks = jiffies;
328 while (ticks == jiffies)
329 /* nothing */;
330 /* Go .. */
331 ticks = jiffies;
332 __delay(loops_per_sec);
333 ticks = jiffies - ticks;
334 if (ticks)
335 break;
336 }
337
338 /* Do a binary approximation to get loops_per_second set to equal one clock
339 (up to lps_precision bits) */
340 loops_per_sec >>= 1;
341 loopbit = loops_per_sec;
342 while ( lps_precision-- && (loopbit >>= 1) ) {
343 loops_per_sec |= loopbit;
344 ticks = jiffies;
345 while (ticks == jiffies);
346 ticks = jiffies;
347 __delay(loops_per_sec);
348 if (jiffies != ticks) /* longer than 1 tick */
349 loops_per_sec &= ~loopbit;
350 }
351
352 /* finally, adjust loops per second in terms of seconds instead of clocks */
353 loops_per_sec *= HZ;
354 /* Round the value and print it */
355 printk("%lu.%02lu BogoMIPS\n",
356 (loops_per_sec+2500)/500000,
357 ((loops_per_sec+2500)/5000) % 100);
358 }
359
360 static int __init readonly(char *str)
361 {
362 if (*str)
363 return 0;
364 root_mountflags |= MS_RDONLY;
365 return 1;
366 }
367
368 static int __init readwrite(char *str)
369 {
370 if (*str)
371 return 0;
372 root_mountflags &= ~MS_RDONLY;
373 return 1;
374 }
375
376 static int __init debug_kernel(char *str)
377 {
378 if (*str)
379 return 0;
380 console_loglevel = 10;
381 return 1;
382 }
383
384 __setup("ro", readonly);
385 __setup("rw", readwrite);
386 __setup("debug", debug_kernel);
387
388 /*
389 * This is a simple kernel command line parsing function: it parses
390 * the command line, and fills in the arguments/environment to init
391 * as appropriate. Any cmd-line option is taken to be an environment
392 * variable if it contains the character '='.
393 *
394 * This routine also checks for options meant for the kernel.
395 * These options are not given to init - they are for internal kernel use only.
396 */
397 static void __init parse_options(char *line)
398 {
399 char *next;
400 int args, envs;
401
402 if (!*line)
403 return;
404 args = 0;
405 envs = 1; /* TERM is set to 'linux' by default */
406 next = line;
407 while ((line = next) != NULL) {
408 if ((next = strchr(line,' ')) != NULL)
409 *next++ = 0;
410 if (!strncmp(line,"init=",5)) {
411 line += 5;
412 execute_command = line;
413 /* In case LILO is going to boot us with default command line,
414 * it prepends "auto" before the whole cmdline which makes
415 * the shell think it should execute a script with such name.
416 * So we ignore all arguments entered _before_ init=... [MJ]
417 */
418 args = 0;
419 continue;
420 }
421 if (checksetup(line))
422 continue;
423
424 /*
425 * Then check if it's an environment variable or
426 * an option.
427 */
428 if (strchr(line,'=')) {
429 if (envs >= MAX_INIT_ENVS)
430 break;
431 envp_init[++envs] = line;
432 } else {
433 if (args >= MAX_INIT_ARGS)
434 break;
435 argv_init[++args] = line;
436 }
437 }
438 argv_init[args+1] = NULL;
439 envp_init[envs+1] = NULL;
440 }
441
442
443 extern void setup_arch(char **);
444 extern void cpu_idle(void);
445
446 #ifndef __SMP__
447
448 #ifdef CONFIG_X86_IO_APIC
449 static void __init smp_init(void)
450 {
451 IO_APIC_init_uniprocessor();
452 }
453 #else
454 #define smp_init() do { } while (0)
455 #endif
456
457 #else
458
459 /* Called by boot processor to activate the rest. */
460 static void __init smp_init(void)
461 {
462 /* Get other processors into their bootup holding patterns. */
463 smp_boot_cpus();
464 smp_threads_ready=1;
465 smp_commence();
466 }
467
468 #endif
469
470 /*
471 * Activate the first processor.
472 */
473
474 asmlinkage void __init start_kernel(void)
475 {
476 char * command_line;
477 unsigned long mempages;
478 /*
479 * Interrupts are still disabled. Do necessary setups, then
480 * enable them
481 */
482 lock_kernel();
483 printk(linux_banner);
484 setup_arch(&command_line);
485 paging_init();
486 trap_init();
487 init_IRQ();
488 sched_init();
489 time_init();
490 softirq_init();
491 parse_options(command_line);
492
493 /*
494 * HACK ALERT! This is early. We're enabling the console before
495 * we've done PCI setups etc, and console_init() must be aware of
496 * this. But we do want output early, in case something goes wrong.
497 */
498 console_init();
499 #ifdef CONFIG_MODULES
500 init_modules();
501 #endif
502 if (prof_shift) {
503 unsigned int size;
504 /* only text is profiled */
505 prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
506 prof_len >>= prof_shift;
507
508 size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
509 prof_buffer = (unsigned int *) alloc_bootmem(size);
510 }
511
512 kmem_cache_init();
513 sti();
514 calibrate_delay();
515 #if 0000
516 #ifdef CONFIG_BLK_DEV_INITRD
517 // FIXME, use the bootmem.h interface.
518 if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
519 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
520 "disabling it.\n",initrd_start,memory_start);
521 initrd_start = 0;
522 }
523 #endif
524 #endif /* 0000 */
525 mem_init();
526 kmem_cache_sizes_init();
527 #ifdef CONFIG_PROC_FS
528 proc_root_init();
529 #endif
530 mempages = num_physpages;
531
532 fork_init(mempages);
533 filescache_init();
534 dcache_init();
535 vma_init();
536 buffer_init(mempages);
537 page_cache_init(mempages);
538 kiobuf_init();
539 signals_init();
540 bdev_init();
541 inode_init();
542 file_table_init();
543 #if defined(CONFIG_SYSVIPC)
544 ipc_init();
545 #endif
546 #if defined(CONFIG_QUOTA)
547 dquot_init_hash();
548 #endif
549 check_bugs();
550 printk("POSIX conformance testing by UNIFIX\n");
551
552 /*
553 * We count on the initial thread going ok
554 * Like idlers init is an unlocked kernel thread, which will
555 * make syscalls (and thus be locked).
556 */
557 smp_init();
558 kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
559 unlock_kernel();
560 current->need_resched = 1;
561 cpu_idle();
562 }
563
564 #ifdef CONFIG_BLK_DEV_INITRD
565 static int do_linuxrc(void * shell)
566 {
567 static char *argv[] = { "linuxrc", NULL, };
568
569 close(0);close(1);close(2);
570 setsid();
571 (void) open("/dev/console",O_RDWR,0);
572 (void) dup(0);
573 (void) dup(0);
574 return execve(shell, argv, envp_init);
575 }
576
577 static int __init no_initrd(char *s)
578 {
579 mount_initrd = 0;
580 return 1;
581 }
582
583 __setup("noinitrd", no_initrd);
584
585 #endif
586
587 struct task_struct *child_reaper = &init_task;
588
589 static void __init do_initcalls(void)
590 {
591 initcall_t *call;
592
593 call = &__initcall_start;
594 do {
595 (*call)();
596 call++;
597 } while (call < &__initcall_end);
598 }
599
600 /*
601 * Ok, the machine is now initialized. None of the devices
602 * have been touched yet, but the CPU subsystem is up and
603 * running, and memory and process management works.
604 *
605 * Now we can finally start doing some real work..
606 */
607 static void __init do_basic_setup(void)
608 {
609 #ifdef CONFIG_BLK_DEV_INITRD
610 int real_root_mountflags;
611 #endif
612
613 /*
614 * Tell the world that we're going to be the grim
615 * reaper of innocent orphaned children.
616 *
617 * We don't want people to have to make incorrect
618 * assumptions about where in the task array this
619 * can be found.
620 */
621 child_reaper = current;
622
623 #if defined(CONFIG_MTRR) /* Do this after SMP initialization */
624 /*
625 * We should probably create some architecture-dependent "fixup after
626 * everything is up" style function where this would belong better
627 * than in init/main.c..
628 */
629 mtrr_init();
630 #endif
631
632 #ifdef CONFIG_SYSCTL
633 sysctl_init();
634 #endif
635
636 /*
637 * Ok, at this point all CPU's should be initialized, so
638 * we can start looking into devices..
639 */
640 #ifdef CONFIG_PCI
641 pci_init();
642 #endif
643 #ifdef CONFIG_SBUS
644 sbus_init();
645 #endif
646 #if defined(CONFIG_PPC)
647 ppc_init();
648 #endif
649 #ifdef CONFIG_MCA
650 mca_init();
651 #endif
652 #ifdef CONFIG_ARCH_ACORN
653 ecard_init();
654 #endif
655 #ifdef CONFIG_ZORRO
656 zorro_init();
657 #endif
658 #ifdef CONFIG_DIO
659 dio_init();
660 #endif
661 #ifdef CONFIG_MAC
662 nubus_init();
663 #endif
664 #ifdef CONFIG_ISAPNP
665 isapnp_init();
666 #endif
667 #ifdef CONFIG_USB
668 usb_init(); /* Do this before doing initcalls, so that we can make
669 usbcore initialize here, and all drivers initialize later */
670 #endif
671
672 /* Networking initialization needs a process context */
673 sock_init();
674
675 #ifdef CONFIG_BLK_DEV_INITRD
676 real_root_dev = ROOT_DEV;
677 real_root_mountflags = root_mountflags;
678 if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY;
679 else mount_initrd =0;
680 #endif
681
682 do_initcalls();
683
684 /* .. filesystems .. */
685 filesystem_setup();
686
687 #ifdef CONFIG_IRDA
688 irda_device_init(); /* Must be done after protocol initialization */
689 #endif
690 #ifdef CONFIG_PCMCIA
691 init_pcmcia_ds(); /* Do this last */
692 #endif
693 /* Mount the root filesystem.. */
694 mount_root();
695
696 mount_devfs_fs ();
697
698 #ifdef CONFIG_BLK_DEV_INITRD
699 root_mountflags = real_root_mountflags;
700 if (mount_initrd && ROOT_DEV != real_root_dev
701 && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
702 int error;
703 int i, pid;
704
705 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
706 if (pid>0)
707 while (pid != wait(&i));
708 if (MAJOR(real_root_dev) != RAMDISK_MAJOR
709 || MINOR(real_root_dev) != 0) {
710 #ifdef CONFIG_BLK_DEV_MD
711 autodetect_raid();
712 #endif
713 error = change_root(real_root_dev,"/initrd");
714 if (error)
715 printk(KERN_ERR "Change root to /initrd: "
716 "error %d\n",error);
717 }
718 }
719 #endif
720 }
721
722 static int init(void * unused)
723 {
724 lock_kernel();
725 do_basic_setup();
726
727 /*
728 * Ok, we have completed the initial bootup, and
729 * we're essentially up and running. Get rid of the
730 * initmem segments and start the user-mode stuff..
731 */
732 free_initmem();
733 unlock_kernel();
734
735 if (open("/dev/console", O_RDWR, 0) < 0)
736 printk("Warning: unable to open an initial console.\n");
737
738 (void) dup(0);
739 (void) dup(0);
740
741 /*
742 * We try each of these until one succeeds.
743 *
744 * The Bourne shell can be used instead of init if we are
745 * trying to recover a really broken machine.
746 */
747
748 if (execute_command)
749 execve(execute_command,argv_init,envp_init);
750 execve("/sbin/init",argv_init,envp_init);
751 execve("/etc/init",argv_init,envp_init);
752 execve("/bin/init",argv_init,envp_init);
753 execve("/bin/sh",argv_init,envp_init);
754 panic("No init found. Try passing init= option to kernel.");
755 }
756
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.