Import 2.3.13
[davej-history.git] / init / main.c
blobcf5013ddf366aba90efd3810abf5dde73d555964
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>
28 #include <asm/io.h>
29 #include <asm/bugs.h>
31 #ifdef CONFIG_PCI
32 #include <linux/pci.h>
33 #endif
35 #ifdef CONFIG_DIO
36 #include <linux/dio.h>
37 #endif
39 #ifdef CONFIG_ZORRO
40 #include <linux/zorro.h>
41 #endif
43 #ifdef CONFIG_MTRR
44 # include <asm/mtrr.h>
45 #endif
47 #ifdef CONFIG_APM
48 #include <linux/apm_bios.h>
49 #endif
51 #ifdef CONFIG_MAC
52 extern void nubus_init(void);
53 #endif
56 * Versions of gcc older than that listed below may actually compile
57 * and link okay, but the end product can have subtle run time bugs.
58 * To avoid associated bogus bug reports, we flatly refuse to compile
59 * with a gcc that is known to be too old from the very beginning.
61 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6)
62 #error sorry, your GCC is too old. It builds incorrect kernels.
63 #endif
65 extern char _stext, _etext;
66 extern char *linux_banner;
68 extern int console_loglevel;
70 static int init(void *);
72 extern void init_IRQ(void);
73 extern void init_modules(void);
74 extern long console_init(long, long);
75 extern void sock_init(void);
76 extern void fork_init(unsigned long);
77 extern void mca_init(void);
78 extern void sbus_init(void);
79 extern void ppc_init(void);
80 extern void sysctl_init(void);
81 extern void filescache_init(void);
82 extern void signals_init(void);
84 extern void free_initmem(void);
85 extern void filesystem_setup(void);
87 #ifdef CONFIG_ARCH_ACORN
88 extern void ecard_init(void);
89 #endif
91 #if defined(CONFIG_SYSVIPC)
92 extern void ipc_init(void);
93 #endif
94 #if defined(CONFIG_QUOTA)
95 extern void dquot_init_hash(void);
96 #endif
99 * Boot command-line arguments
101 #define MAX_INIT_ARGS 8
102 #define MAX_INIT_ENVS 8
104 extern void time_init(void);
106 static unsigned long memory_start = 0;
107 static unsigned long memory_end = 0;
109 int rows, cols;
111 #ifdef CONFIG_BLK_DEV_INITRD
112 kdev_t real_root_dev;
113 #endif
115 int root_mountflags = MS_RDONLY;
116 char *execute_command = NULL;
118 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
119 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
122 * Read an int from an option string; if available accept a subsequent
123 * comma as well.
125 * Return values:
126 * 0 : no int in string
127 * 1 : int found, no subsequent comma
128 * 2 : int found including a subsequent comma
130 int get_option(char **str, int *pint)
132 char *cur = *str;
134 if (!cur || !(*cur)) return 0;
135 *pint = simple_strtol(cur,str,0);
136 if (cur==*str) return 0;
137 if (**str==',') {
138 (*str)++;
139 return 2;
142 return 1;
145 char *get_options(char *str, int nints, int *ints)
147 int res,i=1;
149 while (i<nints) {
150 res = get_option(&str, ints+i);
151 if (res==0) break;
152 i++;
153 if (res==1) break;
155 ints[0] = i-1;
156 return(str);
159 static int __init profile_setup(char *str)
161 int par;
162 if (get_option(&str,&par)) prof_shift = par;
163 return 1;
166 __setup("profile=", profile_setup);
169 static struct dev_name_struct {
170 const char *name;
171 const int num;
172 } root_dev_names[] __initdata = {
173 { "nfs", 0x00ff },
174 { "hda", 0x0300 },
175 { "hdb", 0x0340 },
176 { "hdc", 0x1600 },
177 { "hdd", 0x1640 },
178 { "hde", 0x2100 },
179 { "hdf", 0x2140 },
180 { "hdg", 0x2200 },
181 { "hdh", 0x2240 },
182 { "hdi", 0x3800 },
183 { "hdj", 0x3840 },
184 { "hdk", 0x3900 },
185 { "hdl", 0x3940 },
186 { "hdm", 0x5800 },
187 { "hdn", 0x5840 },
188 { "hdo", 0x5900 },
189 { "hdp", 0x5940 },
190 { "hdq", 0x5A00 },
191 { "hdr", 0x5A40 },
192 { "hds", 0x5B00 },
193 { "hdt", 0x5B40 },
194 { "sda", 0x0800 },
195 { "sdb", 0x0810 },
196 { "sdc", 0x0820 },
197 { "sdd", 0x0830 },
198 { "sde", 0x0840 },
199 { "sdf", 0x0850 },
200 { "sdg", 0x0860 },
201 { "sdh", 0x0870 },
202 { "sdi", 0x0880 },
203 { "sdj", 0x0890 },
204 { "sdk", 0x08a0 },
205 { "sdl", 0x08b0 },
206 { "sdm", 0x08c0 },
207 { "sdn", 0x08d0 },
208 { "sdo", 0x08e0 },
209 { "sdp", 0x08f0 },
210 { "ada", 0x1c00 },
211 { "adb", 0x1c10 },
212 { "adc", 0x1c20 },
213 { "add", 0x1c30 },
214 { "ade", 0x1c40 },
215 { "fd", 0x0200 },
216 { "md", 0x0900 },
217 { "xda", 0x0d00 },
218 { "xdb", 0x0d40 },
219 { "ram", 0x0100 },
220 { "scd", 0x0b00 },
221 { "mcd", 0x1700 },
222 { "cdu535", 0x1800 },
223 { "sonycd", 0x1800 },
224 { "aztcd", 0x1d00 },
225 { "cm206cd", 0x2000 },
226 { "gscd", 0x1000 },
227 { "sbpcd", 0x1900 },
228 { "eda", 0x2400 },
229 { "edb", 0x2440 },
230 { "pda", 0x2d00 },
231 { "pdb", 0x2d10 },
232 { "pdc", 0x2d20 },
233 { "pdd", 0x2d30 },
234 { "pcd", 0x2e00 },
235 { "pf", 0x2f00 },
236 { "apblock", APBLOCK_MAJOR << 8},
237 { "ddv", DDV_MAJOR << 8},
238 { NULL, 0 }
241 kdev_t __init name_to_kdev_t(char *line)
243 int base = 0;
244 if (strncmp(line,"/dev/",5) == 0) {
245 struct dev_name_struct *dev = root_dev_names;
246 line += 5;
247 do {
248 int len = strlen(dev->name);
249 if (strncmp(line,dev->name,len) == 0) {
250 line += len;
251 base = dev->num;
252 break;
254 dev++;
255 } while (dev->name);
257 return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
260 static int __init root_dev_setup(char *line)
262 ROOT_DEV = name_to_kdev_t(line);
263 return 1;
266 __setup("root=", root_dev_setup);
268 static int __init checksetup(char *line)
270 struct kernel_param *p;
272 p = &__setup_start;
273 do {
274 int n = strlen(p->str);
275 if (!strncmp(line,p->str,n)) {
276 if (p->setup_func(line+n))
277 return 1;
279 p++;
280 } while (p < &__setup_end);
281 return 0;
284 /* this should be approx 2 Bo*oMips to start (note initial shift), and will
285 still work even if initially too large, it will just take slightly longer */
286 unsigned long loops_per_sec = (1<<12);
288 /* This is the number of bits of precision for the loops_per_second. Each
289 bit takes on average 1.5/HZ seconds. This (like the original) is a little
290 better than 1% */
291 #define LPS_PREC 8
293 void __init calibrate_delay(void)
295 unsigned long ticks, loopbit;
296 int lps_precision = LPS_PREC;
298 loops_per_sec = (1<<12);
300 printk("Calibrating delay loop... ");
301 while (loops_per_sec <<= 1) {
302 /* wait for "start of" clock tick */
303 ticks = jiffies;
304 while (ticks == jiffies)
305 /* nothing */;
306 /* Go .. */
307 ticks = jiffies;
308 __delay(loops_per_sec);
309 ticks = jiffies - ticks;
310 if (ticks)
311 break;
314 /* Do a binary approximation to get loops_per_second set to equal one clock
315 (up to lps_precision bits) */
316 loops_per_sec >>= 1;
317 loopbit = loops_per_sec;
318 while ( lps_precision-- && (loopbit >>= 1) ) {
319 loops_per_sec |= loopbit;
320 ticks = jiffies;
321 while (ticks == jiffies);
322 ticks = jiffies;
323 __delay(loops_per_sec);
324 if (jiffies != ticks) /* longer than 1 tick */
325 loops_per_sec &= ~loopbit;
328 /* finally, adjust loops per second in terms of seconds instead of clocks */
329 loops_per_sec *= HZ;
330 /* Round the value and print it */
331 printk("%lu.%02lu BogoMIPS\n",
332 (loops_per_sec+2500)/500000,
333 ((loops_per_sec+2500)/5000) % 100);
336 static int __init readonly(char *str)
338 if (*str)
339 return 0;
340 root_mountflags |= MS_RDONLY;
341 return 1;
344 static int __init readwrite(char *str)
346 if (*str)
347 return 0;
348 root_mountflags &= ~MS_RDONLY;
349 return 1;
352 static int __init debug_kernel(char *str)
354 if (*str)
355 return 0;
356 console_loglevel = 10;
357 return 1;
360 __setup("ro", readonly);
361 __setup("rw", readwrite);
362 __setup("debug", debug_kernel);
365 * This is a simple kernel command line parsing function: it parses
366 * the command line, and fills in the arguments/environment to init
367 * as appropriate. Any cmd-line option is taken to be an environment
368 * variable if it contains the character '='.
370 * This routine also checks for options meant for the kernel.
371 * These options are not given to init - they are for internal kernel use only.
373 static void __init parse_options(char *line)
375 char *next;
376 int args, envs;
378 if (!*line)
379 return;
380 args = 0;
381 envs = 1; /* TERM is set to 'linux' by default */
382 next = line;
383 while ((line = next) != NULL) {
384 if ((next = strchr(line,' ')) != NULL)
385 *next++ = 0;
386 if (!strncmp(line,"init=",5)) {
387 line += 5;
388 execute_command = line;
389 /* In case LILO is going to boot us with default command line,
390 * it prepends "auto" before the whole cmdline which makes
391 * the shell think it should execute a script with such name.
392 * So we ignore all arguments entered _before_ init=... [MJ]
394 args = 0;
395 continue;
397 if (checksetup(line))
398 continue;
401 * Then check if it's an environment variable or
402 * an option.
404 if (strchr(line,'=')) {
405 if (envs >= MAX_INIT_ENVS)
406 break;
407 envp_init[++envs] = line;
408 } else {
409 if (args >= MAX_INIT_ARGS)
410 break;
411 argv_init[++args] = line;
414 argv_init[args+1] = NULL;
415 envp_init[envs+1] = NULL;
419 extern void setup_arch(char **, unsigned long *, unsigned long *);
420 extern void cpu_idle(void);
422 #ifndef __SMP__
424 #define smp_init() do { } while (0)
426 #else
428 /* Called by boot processor to activate the rest. */
429 static void __init smp_init(void)
431 /* Get other processors into their bootup holding patterns. */
432 smp_boot_cpus();
433 smp_threads_ready=1;
434 smp_commence();
437 #endif
439 extern void initialize_secondary(void);
442 * Activate the first processor.
445 asmlinkage void __init start_kernel(void)
447 char * command_line;
449 #ifdef __SMP__
450 static int boot_cpu = 1;
451 /* "current" has been set up, we need to load it now */
452 if (!boot_cpu)
453 initialize_secondary();
454 boot_cpu = 0;
455 #endif
458 * Interrupts are still disabled. Do necessary setups, then
459 * enable them
461 lock_kernel();
462 printk(linux_banner);
463 setup_arch(&command_line, &memory_start, &memory_end);
464 memory_start = paging_init(memory_start,memory_end);
465 trap_init();
466 init_IRQ();
467 sched_init();
468 time_init();
469 parse_options(command_line);
472 * HACK ALERT! This is early. We're enabling the console before
473 * we've done PCI setups etc, and console_init() must be aware of
474 * this. But we do want output early, in case something goes wrong.
476 memory_start = console_init(memory_start,memory_end);
477 #ifdef CONFIG_MODULES
478 init_modules();
479 #endif
480 if (prof_shift) {
481 prof_buffer = (unsigned int *) memory_start;
482 /* only text is profiled */
483 prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
484 prof_len >>= prof_shift;
485 memory_start += prof_len * sizeof(unsigned int);
486 memset(prof_buffer, 0, prof_len * sizeof(unsigned int));
489 memory_start = kmem_cache_init(memory_start, memory_end);
490 sti();
491 calibrate_delay();
492 #ifdef CONFIG_BLK_DEV_INITRD
493 if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
494 printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
495 "disabling it.\n",initrd_start,memory_start);
496 initrd_start = 0;
498 #endif
499 mem_init(memory_start,memory_end);
500 kmem_cache_sizes_init();
501 #ifdef CONFIG_PROC_FS
502 proc_root_init();
503 #endif
504 fork_init(memory_end-memory_start);
505 filescache_init();
506 dcache_init();
507 vma_init();
508 buffer_init(memory_end-memory_start);
509 page_cache_init(memory_end-memory_start);
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
636 /* Networking initialization needs a process context */
637 sock_init();
639 do_initcalls();
641 #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 /* .. filesystems .. */
650 filesystem_setup();
652 /* Mount the root filesystem.. */
653 mount_root();
655 #ifdef CONFIG_BLK_DEV_INITRD
656 root_mountflags = real_root_mountflags;
657 if (mount_initrd && ROOT_DEV != real_root_dev
658 && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) {
659 int error;
660 int i, pid;
662 pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
663 if (pid>0)
664 while (pid != wait(&i));
665 if (MAJOR(real_root_dev) != RAMDISK_MAJOR
666 || MINOR(real_root_dev) != 0) {
667 error = change_root(real_root_dev,"/initrd");
668 if (error)
669 printk(KERN_ERR "Change root to /initrd: "
670 "error %d\n",error);
673 #endif
676 static int init(void * unused)
678 lock_kernel();
679 do_basic_setup();
682 * Ok, we have completed the initial bootup, and
683 * we're essentially up and running. Get rid of the
684 * initmem segments and start the user-mode stuff..
686 free_initmem();
687 unlock_kernel();
689 if (open("/dev/console", O_RDWR, 0) < 0)
690 printk("Warning: unable to open an initial console.\n");
692 (void) dup(0);
693 (void) dup(0);
696 * We try each of these until one succeeds.
698 * The Bourne shell can be used instead of init if we are
699 * trying to recover a really broken machine.
702 if (execute_command)
703 execve(execute_command,argv_init,envp_init);
704 execve("/sbin/init",argv_init,envp_init);
705 execve("/etc/init",argv_init,envp_init);
706 execve("/bin/init",argv_init,envp_init);
707 execve("/bin/sh",argv_init,envp_init);
708 panic("No init found. Try passing init= option to kernel.");