linux-old/init/main.c
<<
>>
Prefs
   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
  64extern int irda_proto_init(void);
  65extern 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
  82extern char _stext, _etext;
  83extern char *linux_banner;
  84
  85static int init(void *);
  86
  87extern void init_IRQ(void);
  88extern void init_modules(void);
  89extern void sock_init(void);
  90extern void fork_init(unsigned long);
  91extern void mca_init(void);
  92extern void sbus_init(void);
  93extern void ppc_init(void);
  94extern void sysctl_init(void);
  95extern void signals_init(void);
  96extern int init_pcmcia_ds(void);
  97
  98extern void free_initmem(void);
  99
 100#ifdef CONFIG_TC
 101extern void tc_init(void);
 102#endif
 103
 104extern void ecard_init(void);
 105
 106#if defined(CONFIG_SYSVIPC)
 107extern 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
 116extern void time_init(void);
 117extern void softirq_init(void);
 118
 119int rows, cols;
 120
 121char *execute_command;
 122
 123static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
 124char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 125
 126static int __init profile_setup(char *str)
 127{
 128    int par;
 129    if (get_option(&str,&par)) prof_shift = par;
 130        return 1;
 131}
 132
 133__setup("profile=", profile_setup);
 134
 135static int __init checksetup(char *line)
 136{
 137        struct kernel_param *p;
 138
 139        p = &__setup_start;
 140        do {
 141                int n = strlen(p->str);
 142                if (!strncmp(line,p->str,n)) {
 143                        if (p->setup_func(line+n))
 144                                return 1;
 145                }
 146                p++;
 147        } while (p < &__setup_end);
 148        return 0;
 149}
 150
 151/* this should be approx 2 Bo*oMips to start (note initial shift), and will
 152   still work even if initially too large, it will just take slightly longer */
 153unsigned long loops_per_jiffy = (1<<12);
 154
 155/* This is the number of bits of precision for the loops_per_jiffy.  Each
 156   bit takes on average 1.5/HZ seconds.  This (like the original) is a little
 157   better than 1% */
 158#define LPS_PREC 8
 159
 160void __init calibrate_delay(void)
 161{
 162        unsigned long ticks, loopbit;
 163        int lps_precision = LPS_PREC;
 164
 165        loops_per_jiffy = (1<<12);
 166
 167        printk("Calibrating delay loop... ");
 168        while (loops_per_jiffy <<= 1) {
 169                /* wait for "start of" clock tick */
 170                ticks = jiffies;
 171                while (ticks == jiffies)
 172                        /* nothing */;
 173                /* Go .. */
 174                ticks = jiffies;
 175                __delay(loops_per_jiffy);
 176                ticks = jiffies - ticks;
 177                if (ticks)
 178                        break;
 179        }
 180
 181/* Do a binary approximation to get loops_per_jiffy set to equal one clock
 182   (up to lps_precision bits) */
 183        loops_per_jiffy >>= 1;
 184        loopbit = loops_per_jiffy;
 185        while ( lps_precision-- && (loopbit >>= 1) ) {
 186                loops_per_jiffy |= loopbit;
 187                ticks = jiffies;
 188                while (ticks == jiffies);
 189                ticks = jiffies;
 190                __delay(loops_per_jiffy);
 191                if (jiffies != ticks)   /* longer than 1 tick */
 192                        loops_per_jiffy &= ~loopbit;
 193        }
 194
 195/* Round the value and print it */      
 196        printk("%lu.%02lu BogoMIPS\n",
 197                loops_per_jiffy/(500000/HZ),
 198                (loops_per_jiffy/(5000/HZ)) % 100);
 199}
 200
 201static int __init debug_kernel(char *str)
 202{
 203        if (*str)
 204                return 0;
 205        console_loglevel = 10;
 206        return 1;
 207}
 208
 209static int __init quiet_kernel(char *str)
 210{
 211        if (*str)
 212                return 0;
 213        console_loglevel = 4;
 214        return 1;
 215}
 216
 217__setup("debug", debug_kernel);
 218__setup("quiet", quiet_kernel);
 219
 220/*
 221 * This is a simple kernel command line parsing function: it parses
 222 * the command line, and fills in the arguments/environment to init
 223 * as appropriate. Any cmd-line option is taken to be an environment
 224 * variable if it contains the character '='.
 225 *
 226 * This routine also checks for options meant for the kernel.
 227 * These options are not given to init - they are for internal kernel use only.
 228 */
 229static void __init parse_options(char *line)
 230{
 231        char *next,*quote;
 232        int args, envs;
 233
 234        if (!*line)
 235                return;
 236        args = 0;
 237        envs = 1;       /* TERM is set to 'linux' by default */
 238        next = line;
 239        while ((line = next) != NULL) {
 240                quote = strchr(line,'"');
 241                next = strchr(line, ' ');
 242                while (next != NULL && quote != NULL && quote < next) {
 243                        /* we found a left quote before the next blank
 244                         * now we have to find the matching right quote
 245                         */
 246                        next = strchr(quote+1, '"');
 247                        if (next != NULL) {
 248                                quote = strchr(next+1, '"');
 249                                next = strchr(next+1, ' ');
 250                        }
 251                }
 252                if (next != NULL)
 253                        *next++ = 0;
 254                if (!strncmp(line,"init=",5)) {
 255                        line += 5;
 256                        execute_command = line;
 257                        /* In case LILO is going to boot us with default command line,
 258                         * it prepends "auto" before the whole cmdline which makes
 259                         * the shell think it should execute a script with such name.
 260                         * So we ignore all arguments entered _before_ init=... [MJ]
 261                         */
 262                        args = 0;
 263                        continue;
 264                }
 265                if (checksetup(line))
 266                        continue;
 267                
 268                /*
 269                 * Then check if it's an environment variable or
 270                 * an option.
 271                 */
 272                if (strchr(line,'=')) {
 273                        if (envs >= MAX_INIT_ENVS)
 274                                break;
 275                        envp_init[++envs] = line;
 276                } else {
 277                        if (args >= MAX_INIT_ARGS)
 278                                break;
 279                        if (*line)
 280                                argv_init[++args] = line;
 281                }
 282        }
 283        argv_init[args+1] = NULL;
 284        envp_init[envs+1] = NULL;
 285}
 286
 287
 288extern void setup_arch(char **);
 289extern void cpu_idle(void);
 290
 291unsigned long wait_init_idle;
 292
 293#ifndef CONFIG_SMP
 294
 295#ifdef CONFIG_X86_LOCAL_APIC
 296static void __init smp_init(void)
 297{
 298        APIC_init_uniprocessor();
 299}
 300#else
 301#define smp_init()      do { } while (0)
 302#endif
 303
 304#else
 305
 306
 307/* Called by boot processor to activate the rest. */
 308static void __init smp_init(void)
 309{
 310        /* Get other processors into their bootup holding patterns. */
 311        smp_boot_cpus();
 312        wait_init_idle = cpu_online_map;
 313        clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
 314
 315        smp_threads_ready=1;
 316        smp_commence();
 317
 318        /* Wait for the other cpus to set up their idle processes */
 319        printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle);
 320        while (wait_init_idle) {
 321                cpu_relax();
 322                barrier();
 323        }
 324        printk("All processors have done init_idle\n");
 325}
 326
 327#endif
 328
 329/*
 330 * We need to finalize in a non-__init function or else race conditions
 331 * between the root thread and the init thread may cause start_kernel to
 332 * be reaped by free_initmem before the root thread has proceeded to
 333 * cpu_idle.
 334 */
 335
 336static void rest_init(void)
 337{
 338        kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
 339        unlock_kernel();
 340        current->need_resched = 1;
 341        cpu_idle();
 342} 
 343
 344/*
 345 *      Activate the first processor.
 346 */
 347
 348asmlinkage void __init start_kernel(void)
 349{
 350        char * command_line;
 351        extern char saved_command_line[];
 352/*
 353 * Interrupts are still disabled. Do necessary setups, then
 354 * enable them
 355 */
 356        lock_kernel();
 357        printk(linux_banner);
 358        setup_arch(&command_line);
 359        printk("Kernel command line: %s\n", saved_command_line);
 360        parse_options(command_line);
 361        trap_init();
 362        init_IRQ();
 363        sched_init();
 364        softirq_init();
 365        time_init();
 366
 367        /*
 368         * HACK ALERT! This is early. We're enabling the console before
 369         * we've done PCI setups etc, and console_init() must be aware of
 370         * this. But we do want output early, in case something goes wrong.
 371         */
 372        console_init();
 373#ifdef CONFIG_MODULES
 374        init_modules();
 375#endif
 376        if (prof_shift) {
 377                unsigned int size;
 378                /* only text is profiled */
 379                prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
 380                prof_len >>= prof_shift;
 381                
 382                size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
 383                prof_buffer = (unsigned int *) alloc_bootmem(size);
 384        }
 385
 386        kmem_cache_init();
 387        sti();
 388        calibrate_delay();
 389#ifdef CONFIG_BLK_DEV_INITRD
 390        if (initrd_start && !initrd_below_start_ok &&
 391                        initrd_start < min_low_pfn << PAGE_SHIFT) {
 392                printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
 393                    "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
 394                initrd_start = 0;
 395        }
 396#endif
 397        mem_init();
 398        kmem_cache_sizes_init();
 399        pgtable_cache_init();
 400
 401        /*
 402         * For architectures that have highmem, num_mappedpages represents
 403         * the amount of memory the kernel can use.  For other architectures
 404         * it's the same as the total pages.  We need both numbers because
 405         * some subsystems need to initialize based on how much memory the
 406         * kernel can use.
 407         */
 408        if (num_mappedpages == 0)
 409                num_mappedpages = num_physpages;
 410  
 411        fork_init(num_mappedpages);
 412        proc_caches_init();
 413        vfs_caches_init(num_physpages);
 414        buffer_init(num_physpages);
 415        page_cache_init(num_physpages);
 416#if defined(CONFIG_ARCH_S390)
 417        ccwcache_init();
 418#endif
 419        signals_init();
 420#ifdef CONFIG_PROC_FS
 421        proc_root_init();
 422#endif
 423#if defined(CONFIG_SYSVIPC)
 424        ipc_init();
 425#endif
 426        check_bugs();
 427        printk("POSIX conformance testing by UNIFIX\n");
 428
 429        /* 
 430         *      We count on the initial thread going ok 
 431         *      Like idlers init is an unlocked kernel thread, which will
 432         *      make syscalls (and thus be locked).
 433         */
 434        smp_init();
 435        rest_init();
 436}
 437
 438struct task_struct *child_reaper = &init_task;
 439
 440static void __init do_initcalls(void)
 441{
 442        initcall_t *call;
 443
 444        call = &__initcall_start;
 445        do {
 446                (*call)();
 447                call++;
 448        } while (call < &__initcall_end);
 449
 450        /* Make sure there is no pending stuff from the initcall sequence */
 451        flush_scheduled_tasks();
 452}
 453
 454/*
 455 * Ok, the machine is now initialized. None of the devices
 456 * have been touched yet, but the CPU subsystem is up and
 457 * running, and memory and process management works.
 458 *
 459 * Now we can finally start doing some real work..
 460 */
 461static void __init do_basic_setup(void)
 462{
 463
 464        /*
 465         * Tell the world that we're going to be the grim
 466         * reaper of innocent orphaned children.
 467         *
 468         * We don't want people to have to make incorrect
 469         * assumptions about where in the task array this
 470         * can be found.
 471         */
 472        child_reaper = current;
 473
 474#if defined(CONFIG_MTRR)        /* Do this after SMP initialization */
 475/*
 476 * We should probably create some architecture-dependent "fixup after
 477 * everything is up" style function where this would belong better
 478 * than in init/main.c..
 479 */
 480        mtrr_init();
 481#endif
 482
 483#ifdef CONFIG_SYSCTL
 484        sysctl_init();
 485#endif
 486
 487        /*
 488         * Ok, at this point all CPU's should be initialized, so
 489         * we can start looking into devices..
 490         */
 491#if defined(CONFIG_ARCH_S390)
 492        s390_init_machine_check();
 493#endif
 494
 495#ifdef CONFIG_PCI
 496        pci_init();
 497#endif
 498#ifdef CONFIG_SBUS
 499        sbus_init();
 500#endif
 501#if defined(CONFIG_PPC)
 502        ppc_init();
 503#endif
 504#ifdef CONFIG_MCA
 505        mca_init();
 506#endif
 507#ifdef CONFIG_ARCH_ACORN
 508        ecard_init();
 509#endif
 510#ifdef CONFIG_ZORRO
 511        zorro_init();
 512#endif
 513#ifdef CONFIG_DIO
 514        dio_init();
 515#endif
 516#ifdef CONFIG_NUBUS
 517        nubus_init();
 518#endif
 519#ifdef CONFIG_ISAPNP
 520        isapnp_init();
 521#endif
 522#ifdef CONFIG_TC
 523        tc_init();
 524#endif
 525
 526        /* Networking initialization needs a process context */ 
 527        sock_init();
 528
 529        start_context_thread();
 530        do_initcalls();
 531
 532#ifdef CONFIG_IRDA
 533        irda_proto_init();
 534        irda_device_init(); /* Must be done after protocol initialization */
 535#endif
 536#ifdef CONFIG_PCMCIA
 537        init_pcmcia_ds();               /* Do this last */
 538#endif
 539}
 540
 541extern void prepare_namespace(void);
 542
 543static int init(void * unused)
 544{
 545        lock_kernel();
 546        do_basic_setup();
 547
 548        prepare_namespace();
 549
 550        /*
 551         * Ok, we have completed the initial bootup, and
 552         * we're essentially up and running. Get rid of the
 553         * initmem segments and start the user-mode stuff..
 554         */
 555        free_initmem();
 556        unlock_kernel();
 557
 558        if (open("/dev/console", O_RDWR, 0) < 0)
 559                printk("Warning: unable to open an initial console.\n");
 560
 561        (void) dup(0);
 562        (void) dup(0);
 563        
 564        /*
 565         * We try each of these until one succeeds.
 566         *
 567         * The Bourne shell can be used instead of init if we are 
 568         * trying to recover a really broken machine.
 569         */
 570
 571        if (execute_command)
 572                execve(execute_command,argv_init,envp_init);
 573        execve("/sbin/init",argv_init,envp_init);
 574        execve("/etc/init",argv_init,envp_init);
 575        execve("/bin/init",argv_init,envp_init);
 576        execve("/bin/sh",argv_init,envp_init);
 577        panic("No init found.  Try passing init= option to kernel.");
 578}
 579
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.