CTC++ Coverage Report - Execution Profile    #2/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: init/main.c
Instrumentation mode: function-decision-multicondition
TER: 37 % ( 58/157)

Start/ End/    
True False - Line Source

  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/types.h>
  16 #include <linux/module.h>
  17 #include <linux/proc_fs.h>
  18 #include <linux/devfs_fs_kernel.h>
  19 #include <linux/kernel.h>
  20 #include <linux/syscalls.h>
  21 #include <linux/string.h>
  22 #include <linux/ctype.h>
  23 #include <linux/delay.h>
  24 #include <linux/utsname.h>
  25 #include <linux/ioport.h>
  26 #include <linux/init.h>
  27 #include <linux/smp_lock.h>
  28 #include <linux/initrd.h>
  29 #include <linux/hdreg.h>
  30 #include <linux/bootmem.h>
  31 #include <linux/tty.h>
  32 #include <linux/gfp.h>
  33 #include <linux/percpu.h>
  34 #include <linux/kmod.h>
  35 #include <linux/kernel_stat.h>
  36 #include <linux/security.h>
  37 #include <linux/workqueue.h>
  38 #include <linux/profile.h>
  39 #include <linux/rcupdate.h>
  40 #include <linux/moduleparam.h>
  41 #include <linux/kallsyms.h>
  42 #include <linux/writeback.h>
  43 #include <linux/cpu.h>
  44 #include <linux/cpuset.h>
  45 #include <linux/efi.h>
  46 #include <linux/unistd.h>
  47 #include <linux/rmap.h>
  48 #include <linux/mempolicy.h>
  49 #include <linux/key.h>
  50 
  51 #include <asm/io.h>
  52 #include <asm/bugs.h>
  53 #include <asm/setup.h>
  54 #include <asm/sections.h>
  55 #include <asm/cacheflush.h>
  56 
  57 #ifdef CONFIG_X86_LOCAL_APIC
  58 #include <asm/smp.h>
  59 #endif
  60 
  61 /*
  62  * This is one of the first .c files built. Error out early if we have compiler
  63  * trouble.
  64  *
  65  * Versions of gcc older than that listed below may actually compile and link
  66  * okay, but the end product can have subtle run time bugs.  To avoid associated
  67  * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
  68  * too old from the very beginning.
  69  */
  70 #if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
  71 #error Sorry, your GCC is too old. It builds incorrect kernels.
  72 #endif
  73 
  74 static int init(void *);
  75 
  76 extern void init_IRQ(void);
  77 extern void fork_init(unsigned long);
  78 extern void mca_init(void);
  79 extern void sbus_init(void);
  80 extern void sysctl_init(void);
  81 extern void signals_init(void);
  82 extern void buffer_init(void);
  83 extern void pidhash_init(void);
  84 extern void pidmap_init(void);
  85 extern void prio_tree_init(void);
  86 extern void radix_tree_init(void);
  87 extern void free_initmem(void);
  88 extern void populate_rootfs(void);
  89 extern void driver_init(void);
  90 extern void prepare_namespace(void);
  91 #ifdef   CONFIG_ACPI
  92 extern void acpi_early_init(void);
  93 #else
  94 static inline void acpi_early_init(void) { }
  95 #endif
  96 #ifndef CONFIG_DEBUG_RODATA
 
  97 static inline void mark_rodata_ro(void) { }
  98 #endif
  99 
  100 #ifdef CONFIG_TC
  101 extern void tc_init(void);
  102 #endif
  103 
  104 enum system_states system_state;
  105 EXPORT_SYMBOL(system_state);
  106 
  107 /*
  108  * Boot command-line arguments
  109  */
  110 #define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
  111 #define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
  112 
  113 extern void time_init(void);
  114 /* Default late time init is NULL. archs can override this later. */
  115 void (*late_time_init)(void);
  116 extern void softirq_init(void);
  117 
  118 /* Untouched command line (eg. for /proc) saved by arch-specific code. */
  119 char saved_command_line[COMMAND_LINE_SIZE];
  120 
  121 static char *execute_command;
  122 static char *ramdisk_execute_command;
  123 
  124 /* Setup configured maximum number of CPUs to activate */
  125 static unsigned int max_cpus = NR_CPUS;
  126 
  127 /*
  128  * Setup routine for controlling SMP activation
  129  *
  130  * Command-line option of "nosmp" or "maxcpus=0" will disable SMP
  131  * activation entirely (the MPS table probe still happens, though).
  132  *
  133  * Command-line option of "maxcpus=<NUM>", where <NUM> is an integer
  134  * greater than 0, limits the maximum number of CPUs activated in
  135  * SMP mode to <NUM>.
  136  */
 
- 137 static int __init nosmp(char *str)
  138 {
  139    max_cpus = 0;
 - 140    return 1;
  141 }
  142 
  143 __setup("nosmp", nosmp);
  144 
 
- 145 static int __init maxcpus(char *str)
  146 {
  147    get_option(&str, &max_cpus);
 - 148    return 1;
  149 }
  150 
  151 __setup("maxcpus=", maxcpus);
  152 
  153 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
  154 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
  155 static const char *panic_later, *panic_param;
  156 
  157 extern struct obs_kernel_param __setup_start[], __setup_end[];
  158 
 
  159 static int __init obsolete_checksetup(char *line)
  160 {
  161    struct obs_kernel_param *p;
  162 
  163    p = __setup_start;
    164    do {
  165       int n = strlen(p->str);
33   166       if (!strncmp(line, p->str, n)) {
- 167          if (p->early) {
  168             /* Already done in parse_early_param?  (Needs
  169              * exact match on param part) */
- 170             if (line[n] == '\0' || line[n] == '=')
 - 170         T || _
 - 170         F || T
 - 170         F || F
 - 171                return 1;
- 172          } else if (!p->setup_func) {
  173             printk(KERN_WARNING "Parameter %s is obsolete,"
  174                    " ignored\n", p->str);
 - 175             return 1;
- 176          } else if (p->setup_func(line + n))
   177             return 1;
  178       }
  179       p++;
33 - 180    } while (p < __setup_end);
 - 181    return 0;
  182 }
  183 
  184 /*
  185  * This should be approx 2 Bo*oMips to start (note initial shift), and will
  186  * still work even if initially too large, it will just take slightly longer
  187  */
  188 unsigned long loops_per_jiffy = (1<<12);
  189 
  190 EXPORT_SYMBOL(loops_per_jiffy);
  191 
 
- 192 static int __init debug_kernel(char *str)
  193 {
- 194    if (*str)
 - 195       return 0;
  196    console_loglevel = 10;
 - 197    return 1;
  198 }
  199 
 
- 200 static int __init quiet_kernel(char *str)
  201 {
- 202    if (*str)
 - 203       return 0;
  204    console_loglevel = 4;
 - 205    return 1;
  206 }
  207 
  208 __setup("debug", debug_kernel);
  209 __setup("quiet", quiet_kernel);
  210 
 
- 211 static int __init loglevel(char *str)
  212 {
  213    get_option(&str, &console_loglevel);
 - 214    return 1;
  215 }
  216 
  217 __setup("loglevel=", loglevel);
  218 
  219 /*
  220  * Unknown boot options get handed to init, unless they look like
  221  * failed parameters
  222  */
 
  223 static int __init unknown_bootoption(char *param, char *val)
  224 {
  225    /* Change NUL term back to "=", to make "param" the whole string. */
- 226    if (val) {
  227       /* param=val or param="val"? */
- 228       if (val == param+strlen(param)+1)
  229          val[-1] = '=';
- 230       else if (val == param+strlen(param)+2) {
  231          val[-2] = '=';
  232          memmove(val-1, val, strlen(val)+1);
  233          val--;
    234       } else
  235          BUG();
  236    }
  237 
  238    /* Handle obsolete-style parameters */
- 239    if (obsolete_checksetup(param))
   240       return 0;
  241 
  242    /*
  243     * Preemptive maintenance for "why didn't my mispelled command
  244     * line work?"
  245     */
- 246    if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
 - 246   T && (T || _)
 - 246   T && (F || T)
 - 246   T && (F || F)
 - 246   F && (_ || _)
  247       printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
 - 248       return 0;
  249    }
  250 
- 251    if (panic_later)
 - 252       return 0;
  253 
- 254    if (val) {
  255       /* Environment option */
  256       unsigned int i;
- 257       for (i = 0; envp_init[i]; i++) {
- 258          if (i == MAX_INIT_ENVS) {
  259             panic_later = "Too many boot env vars at `%s'";
  260             panic_param = param;
  261          }
- 262          if (!strncmp(param, envp_init[i], val - param))
 - 263             break;
  264       }
  265       envp_init[i] = param;
    266    } else {
  267       /* Command line option */
  268       unsigned int i;
- 269       for (i = 0; argv_init[i]; i++) {
- 270          if (i == MAX_INIT_ARGS) {
  271             panic_later = "Too many boot init vars at `%s'";
  272             panic_param = param;
  273          }
  274       }
  275       argv_init[i] = param;
  276    }
 - 277    return 0;
  278 }
  279 
 
- 280 static int __init init_setup(char *str)
  281 {
  282    unsigned int i;
  283 
  284    execute_command = str;
  285    /*
  286     * In case LILO is going to boot us with default command line,
  287     * it prepends "auto" before the whole cmdline which makes
  288     * the shell think it should execute a script with such name.
  289     * So we ignore all arguments entered _before_ init=... [MJ]
  290     */
- 291    for (i = 1; i < MAX_INIT_ARGS; i++)
  292       argv_init[i] = NULL;
 - 293    return 1;
  294 }
  295 __setup("init=", init_setup);
  296 
 
- 297 static int __init rdinit_setup(char *str)
  298 {
  299    unsigned int i;
  300 
  301    ramdisk_execute_command = str;
  302    /* See "auto" comment in init_setup */
- 303    for (i = 1; i < MAX_INIT_ARGS; i++)
  304       argv_init[i] = NULL;
 - 305    return 1;
  306 }
  307 __setup("rdinit=", rdinit_setup);
  308 
  309 extern void setup_arch(char **);
  310 
  311 #ifndef CONFIG_SMP
  312 
  313 #ifdef CONFIG_X86_LOCAL_APIC
 
  314 static void __init smp_init(void)
  315 {
  316    APIC_init_uniprocessor();
  317 }
  318 #else
  319 #define smp_init()   do { } while (0)
  320 #endif
  321 
 
  322 static inline void setup_per_cpu_areas(void) { }
 
  323 static inline void smp_prepare_cpus(unsigned int maxcpus) { }
  324 
  325 #else
  326 
  327 #ifdef __GENERIC_PER_CPU
  328 unsigned long __per_cpu_offset[NR_CPUS];
  329 
  330 EXPORT_SYMBOL(__per_cpu_offset);
  331 
  332 static void __init setup_per_cpu_areas(void)
  333 {
  334    unsigned long size, i;
  335    char *ptr;
  336 
  337    /* Copy section for each CPU (we discard the original) */
  338    size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
  339 #ifdef CONFIG_MODULES
  340    if (size < PERCPU_ENOUGH_ROOM)
  341       size = PERCPU_ENOUGH_ROOM;
  342 #endif
  343 
  344    ptr = alloc_bootmem(size * NR_CPUS);
  345 
  346    for (i = 0; i < NR_CPUS; i++, ptr += size) {
  347       __per_cpu_offset[i] = ptr - __per_cpu_start;
  348       memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
  349    }
  350 }
  351 #endif /* !__GENERIC_PER_CPU */
  352 
  353 /* Called by boot processor to activate the rest. */
  354 static void __init smp_init(void)
  355 {
  356    unsigned int i;
  357 
  358    /* FIXME: This should be done in userspace --RR */
  359    for_each_present_cpu(i) {
  360       if (num_online_cpus() >= max_cpus)
  361          break;
  362       if (!cpu_online(i))
  363          cpu_up(i);
  364    }
  365 
  366    /* Any cleanup work */
  367    printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
  368    smp_cpus_done(max_cpus);
  369 #if 0
  370    /* Get other processors into their bootup holding patterns. */
  371 
  372    smp_commence();
  373 #endif
  374 }
  375 
  376 #endif
  377 
  378 /*
  379  * We need to finalize in a non-__init function or else race conditions
  380  * between the root thread and the init thread may cause start_kernel to
  381  * be reaped by free_initmem before the root thread has proceeded to
  382  * cpu_idle.
  383  *
  384  * gcc-3.4 accidentally inlines this function, so use noinline.
  385  */
  386 
 
  387 static void noinline rest_init(void)
  388    __releases(kernel_lock)
  389 {
  390    kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
  391    numa_default_policy();
    392    unlock_kernel();
- 392 do-while (0)
  393 
  394    /*
  395     * The boot idle thread must execute schedule()
  396     * at least one to get things moving:
  397     */
    398    preempt_enable_no_resched();
- 398 do-while (0)
  399    schedule();
    400    preempt_disable();
- 400 do-while (0)
  401 
  402    /* Call into cpu_idle with preempt disabled */
  403    cpu_idle();
  404 
  405 
  406 /* Check for early params. */
 
  407 static int __init do_early_param(char *param, char *val)
  408 {
  409    struct obs_kernel_param *p;
  410 
297   411    for (p = __setup_start; p < __setup_end; p++) {
297 - 412       if (p->early && strcmp(param, p->str) == 0) {
 - 412     T && T
 - 412     T && F
 297   412     F && _
- 413          if (p->setup_func(val) != 0)
  414             printk(KERN_WARNING
  415                    "Malformed early option '%s'\n", param);
  416       }
  417    }
  418    /* We accept everything at this stage. */
   419    return 0;
  420 }
  421 
  422 /* Arch code calls this early on, or if not, just before other parsing. */
 
  423 void __init parse_early_param(void)
  424 {
  425    static __initdata int done = 0;
  426    static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
  427 
- 428    if (done)
 - 429       return;
  430 
  431    /* All fall through to do_early_param. */
  432    strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE);
  433    parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
  434    done = 1;
  435 }
  436 
  437 /*
  438  *   Activate the first processor.
  439  */
  440 
 
  441 asmlinkage void __init start_kernel(void)
  442 {
  443    char * command_line;
  444    extern struct kernel_param __start___param[], __stop___param[];
  445 /*
  446  * Interrupts are still disabled. Do necessary setups, then
  447  * enable them
  448  */
    449    lock_kernel();
- 449 do-while (0)
    450    page_address_init();
- 450 do-while (0)
  451    printk(KERN_NOTICE);
  452    printk(linux_banner);
  453    setup_arch(&command_line);
  454    setup_per_cpu_areas();
  455 
  456    /*
  457     * Mark the boot cpu "online" so that it can call console drivers in
  458     * printk() and can access its per-cpu storage.
  459     */
    460    smp_prepare_boot_cpu();
- 460 do-while (0)
  461 
  462    /*
  463     * Set up the scheduler prior starting any interrupts (such as the
  464     * timer interrupt). Full topology setup happens at smp_init()
  465     * time - but meanwhile we still have a functioning scheduler.
  466     */
  467    sched_init();
  468    /*
  469     * Disable preemption - early bootup scheduling is extremely
  470     * fragile until we cpu_idle() for the first time.
  471     */
    472    preempt_disable();
- 472 do-while (0)
  473    build_all_zonelists();
  474    page_alloc_init();
  475    printk(KERN_NOTICE "Kernel command line: %s\n", saved_command_line);
  476    parse_early_param();
  477    parse_args("Booting kernel", command_line, __start___param,
  478          __stop___param - __start___param,
  479          &unknown_bootoption);
  480    sort_main_extable();
  481    trap_init();
  482    rcu_init();
  483    init_IRQ();
  484    pidhash_init();
  485    init_timers();
  486    hrtimers_init();
  487    softirq_init();
  488    time_init();
  489 
  490    /*
  491     * HACK ALERT! This is early. We're enabling the console before
  492     * we've done PCI setups etc, and console_init() must be aware of
  493     * this. But we do want output early, in case something goes wrong.
  494     */
  495    console_init();
- 496    if (panic_later)
  497       panic(panic_later, panic_param);
  498    profile_init();
  499    local_irq_enable();
  500 #ifdef CONFIG_BLK_DEV_INITRD
  501    if (initrd_start && !initrd_below_start_ok &&
  502          initrd_start < min_low_pfn << PAGE_SHIFT) {
  503       printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
  504           "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
  505       initrd_start = 0;
  506    }
  507 #endif
  508    vfs_caches_init_early();
  509    cpuset_init_early();
  510    mem_init();
  511    kmem_cache_init();
  512    setup_per_cpu_pageset();
  513    numa_policy_init();
- 514    if (late_time_init)
  515       late_time_init();
  516    calibrate_delay();
  517    pidmap_init();
    518    pgtable_cache_init();
- 518 do-while (0)
  519    prio_tree_init();
  520    anon_vma_init();
  521 #ifdef CONFIG_X86
- 522    if (efi_enabled)
  523       efi_enter_virtual_mode();
  524 #endif
  525    fork_init(num_physpages);
  526    proc_caches_init();
  527    buffer_init();
  528    unnamed_dev_init();
    529    key_init();
- 529 do-while (0)
  530    security_init();
  531    vfs_caches_init(num_physpages);
  532    radix_tree_init();
  533    signals_init();
  534    /* rootfs populating might need page-writeback */
  535    page_writeback_init();
  536 #ifdef CONFIG_PROC_FS
  537    proc_root_init();
  538 #endif
  539    cpuset_init();
  540 
  541    check_bugs();
  542 
  543    acpi_early_init(); /* before LAPIC and SMP init */
  544 
  545    /* Do the rest non-__init'ed, we're now alive */
  546    rest_init();
  547 }
  548 
  549 static int __initdata initcall_debug;
  550 
 
- 551 static int __init initcall_debug_setup(char *str)
  552 {
  553    initcall_debug = 1;
 - 554    return 1;
  555 }
  556 __setup("initcall_debug", initcall_debug_setup);
  557 
  558 struct task_struct *child_reaper = &init_task;
  559 
  560 extern initcall_t __initcall_start[], __initcall_end[];
  561 
 
  562 static void __init do_initcalls(void)
  563 {
  564    initcall_t *call;
  565    int count = preempt_count();
  566 
654   567    for (call = __initcall_start; call < __initcall_end; call++) {
  568       char *msg;
  569 
654 -