diff options
Diffstat (limited to 'init/main.c')
-rw-r--r-- | init/main.c | 79 |
1 files changed, 70 insertions, 9 deletions
diff --git a/init/main.c b/init/main.c index f715b9b8975..0766e69712b 100644 --- a/init/main.c +++ b/init/main.c @@ -11,11 +11,9 @@ #define __KERNEL_SYSCALLS__ -#include <linux/config.h> #include <linux/types.h> #include <linux/module.h> #include <linux/proc_fs.h> -#include <linux/devfs_fs_kernel.h> #include <linux/kernel.h> #include <linux/syscalls.h> #include <linux/string.h> @@ -43,10 +41,16 @@ #include <linux/cpu.h> #include <linux/cpuset.h> #include <linux/efi.h> +#include <linux/taskstats_kern.h> +#include <linux/delayacct.h> #include <linux/unistd.h> #include <linux/rmap.h> #include <linux/mempolicy.h> #include <linux/key.h> +#include <linux/unwind.h> +#include <linux/buffer_head.h> +#include <linux/debug_locks.h> +#include <linux/lockdep.h> #include <asm/io.h> #include <asm/bugs.h> @@ -79,7 +83,6 @@ extern void mca_init(void); extern void sbus_init(void); extern void sysctl_init(void); extern void signals_init(void); -extern void buffer_init(void); extern void pidhash_init(void); extern void pidmap_init(void); extern void prio_tree_init(void); @@ -125,6 +128,18 @@ static char *ramdisk_execute_command; static unsigned int max_cpus = NR_CPUS; /* + * If set, this is an indication to the drivers that reset the underlying + * device before going ahead with the initialization otherwise driver might + * rely on the BIOS and skip the reset operation. + * + * This is useful if kernel is booting in an unreliable environment. + * For ex. kdump situaiton where previous kernel has crashed, BIOS has been + * skipped and devices will be in unknown state. + */ +unsigned int reset_devices; +EXPORT_SYMBOL(reset_devices); + +/* * Setup routine for controlling SMP activation * * Command-line option of "nosmp" or "maxcpus=0" will disable SMP @@ -150,6 +165,14 @@ static int __init maxcpus(char *str) __setup("maxcpus=", maxcpus); +static int __init set_reset_devices(char *str) +{ + reset_devices = 1; + return 1; +} + +__setup("reset_devices", set_reset_devices); + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; static const char *panic_later, *panic_param; @@ -159,16 +182,19 @@ extern struct obs_kernel_param __setup_start[], __setup_end[]; static int __init obsolete_checksetup(char *line) { struct obs_kernel_param *p; + int had_early_param = 0; p = __setup_start; do { int n = strlen(p->str); if (!strncmp(line, p->str, n)) { if (p->early) { - /* Already done in parse_early_param? (Needs - * exact match on param part) */ + /* Already done in parse_early_param? + * (Needs exact match on param part). + * Keep iterating, as we can have early + * params and __setups of same names 8( */ if (line[n] == '\0' || line[n] == '=') - return 1; + had_early_param = 1; } else if (!p->setup_func) { printk(KERN_WARNING "Parameter %s is obsolete," " ignored\n", p->str); @@ -178,7 +204,8 @@ static int __init obsolete_checksetup(char *line) } p++; } while (p < __setup_end); - return 0; + + return had_early_param; } /* @@ -446,10 +473,28 @@ static void __init boot_cpu_init(void) cpu_set(cpu, cpu_possible_map); } +void __init __attribute__((weak)) smp_setup_processor_id(void) +{ +} + asmlinkage void __init start_kernel(void) { char * command_line; extern struct kernel_param __start___param[], __stop___param[]; + + smp_setup_processor_id(); + + /* + * Need to run as early as possible, to initialize the + * lockdep hash: + */ + unwind_init(); + lockdep_init(); + + local_irq_disable(); + early_boot_irqs_off(); + early_init_irq_lock_class(); + /* * Interrupts are still disabled. Do necessary setups, then * enable them @@ -489,7 +534,13 @@ asmlinkage void __init start_kernel(void) init_timers(); hrtimers_init(); softirq_init(); + timekeeping_init(); time_init(); + profile_init(); + if (!irqs_disabled()) + printk("start_kernel(): bug: interrupts were enabled early\n"); + early_boot_irqs_on(); + local_irq_enable(); /* * HACK ALERT! This is early. We're enabling the console before @@ -499,8 +550,16 @@ asmlinkage void __init start_kernel(void) console_init(); if (panic_later) panic(panic_later, panic_param); - profile_init(); - local_irq_enable(); + + lockdep_info(); + + /* + * Need to run this when irqs are enabled, because it wants + * to self-test [hard/soft]-irqs on/off lock inversion bugs + * too: + */ + locking_selftest(); + #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start < min_low_pfn << PAGE_SHIFT) { @@ -541,6 +600,8 @@ asmlinkage void __init start_kernel(void) proc_root_init(); #endif cpuset_init(); + taskstats_init_early(); + delayacct_init(); check_bugs(); |