X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=init%2Fmain.c;h=cafeaeb4e43624439ce1c3fa9a4bcaef776226b9;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=613aaaba89f8ffebb650ff02b72001a8f8154578;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/init/main.c b/init/main.c index 613aaaba8..cafeaeb4e 100644 --- a/init/main.c +++ b/init/main.c @@ -43,9 +43,11 @@ #include #include #include +#include #include #include +#include /* * This is one of the first .c files built. Error out early @@ -110,6 +112,9 @@ extern void time_init(void); void (*late_time_init)(void); extern void softirq_init(void); +/* Untouched command line (eg. for /proc) saved by arch-specific code. */ +char saved_command_line[COMMAND_LINE_SIZE]; + static char *execute_command; /* Setup configured maximum number of CPUs to activate */ @@ -156,8 +161,14 @@ static int __init obsolete_checksetup(char *line) do { int n = strlen(p->str); if (!strncmp(line, p->str, n)) { - if (!p->setup_func) { - printk(KERN_WARNING "Parameter %s is obsolete, ignored\n", p->str); + if (p->early) { + /* Already done in parse_early_param? (Needs + * exact match on param part) */ + if (line[n] == '\0' || line[n] == '=') + return 1; + } else if (!p->setup_func) { + printk(KERN_WARNING "Parameter %s is obsolete," + " ignored\n", p->str); return 1; } else if (p->setup_func(line + n)) return 1; @@ -268,6 +279,8 @@ static int __init unknown_bootoption(char *param, char *val) panic_later = "Too many boot env vars at `%s'"; panic_param = param; } + if (!strncmp(param, envp_init[i], val - param)) + break; } envp_init[i] = param; } else { @@ -385,10 +398,43 @@ static void __init smp_init(void) static void noinline rest_init(void) { kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); + numa_default_policy(); unlock_kernel(); cpu_idle(); } +/* Check for early params. */ +static int __init do_early_param(char *param, char *val) +{ + struct obs_kernel_param *p; + extern struct obs_kernel_param __setup_start, __setup_end; + + for (p = &__setup_start; p < &__setup_end; p++) { + if (p->early && strcmp(param, p->str) == 0) { + if (p->setup_func(val) != 0) + printk(KERN_WARNING + "Malformed early option '%s'\n", param); + } + } + /* We accept everything at this stage. */ + return 0; +} + +/* Arch code calls this early on, or if not, just before other parsing. */ +void __init parse_early_param(void) +{ + static __initdata int done = 0; + static __initdata char tmp_cmdline[COMMAND_LINE_SIZE]; + + if (done) + return; + + /* All fall through to do_early_param. */ + strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE); + parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); + done = 1; +} + /* * Activate the first processor. */ @@ -396,7 +442,6 @@ static void noinline rest_init(void) asmlinkage void __init start_kernel(void) { char * command_line; - extern char saved_command_line[]; extern struct kernel_param __start___param[], __stop___param[]; /* * Interrupts are still disabled. Do necessary setups, then @@ -424,6 +469,7 @@ asmlinkage void __init start_kernel(void) build_all_zonelists(); page_alloc_init(); printk("Kernel command line: %s\n", saved_command_line); + parse_early_param(); parse_args("Booting kernel", command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); @@ -454,8 +500,10 @@ asmlinkage void __init start_kernel(void) initrd_start = 0; } #endif + vfs_caches_init_early(); mem_init(); kmem_cache_init(); + numa_policy_init(); if (late_time_init) late_time_init(); calibrate_delay(); @@ -645,6 +693,7 @@ static int init(void * unused) free_initmem(); unlock_kernel(); system_state = SYSTEM_RUNNING; + numa_default_policy(); if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); @@ -669,3 +718,16 @@ static int init(void * unused) panic("No init found. Try passing init= option to kernel."); } + +static int early_param_test(char *rest) +{ + printk("early_parm_test: %s\n", rest ?: "(null)"); + return rest ? 0 : -EINVAL; +} +early_param("testsetup", early_param_test); +static int early_setup_test(char *rest) +{ + printk("early_setup_test: %s\n", rest ?: "(null)"); + return 0; +} +__setup("testsetup_long", early_setup_test);