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