diff --git a/include/linux/init.h b/include/linux/init.h index c65f5107d512c4a2df0e3373616772849c9e383b..e290a010e3f2dec2555f7c2f243b20702a86e5fe 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -67,7 +67,8 @@ extern initcall_t __con_initcall_start[], __con_initcall_end[]; extern initcall_t __security_initcall_start[], __security_initcall_end[]; /* Defined in init/main.c */ -extern char saved_command_line[]; +extern char __initdata boot_command_line[]; +extern char *saved_command_line; extern unsigned int reset_devices; /* used by init/main.c */ @@ -164,7 +165,7 @@ struct obs_kernel_param { #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) -/* Relies on saved_command_line being set */ +/* Relies on boot_command_line being set */ void __init parse_early_param(void); #endif /* __ASSEMBLY__ */ diff --git a/init/main.c b/init/main.c index 4e88bddfbebfd03fe5fb6359179b8ef690c750f7..4e9e92bb2b89623507e1c145a6c9a275da7686a6 100644 --- a/init/main.c +++ b/init/main.c @@ -121,8 +121,12 @@ 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]; +/* Untouched command line saved by arch-specific code. */ +char __initdata boot_command_line[COMMAND_LINE_SIZE]; +/* Untouched saved command line (eg. for /proc) */ +char *saved_command_line; +/* Command line for parameter parsing */ +static char *static_command_line; static char *execute_command; static char *ramdisk_execute_command; @@ -399,6 +403,20 @@ static void __init smp_init(void) #endif +/* + * We need to store the untouched command line for future reference. + * We also need to store the touched command line since the parameter + * parsing is performed in place, and we should allow a component to + * store reference of name/value for future reference. + */ +static void __init setup_command_line(char *command_line) +{ + saved_command_line = alloc_bootmem(strlen (boot_command_line)+1); + static_command_line = alloc_bootmem(strlen (command_line)+1); + strcpy (saved_command_line, boot_command_line); + strcpy (static_command_line, command_line); +} + /* * We need to finalize in a non-__init function or else race conditions * between the root thread and the init thread may cause start_kernel to @@ -453,7 +471,7 @@ void __init parse_early_param(void) return; /* All fall through to do_early_param. */ - strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE); + strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE); parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); done = 1; } @@ -503,6 +521,7 @@ asmlinkage void __init start_kernel(void) printk(KERN_NOTICE); printk(linux_banner); setup_arch(&command_line); + setup_command_line(command_line); unwind_setup(); setup_per_cpu_areas(); smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */ @@ -520,9 +539,9 @@ asmlinkage void __init start_kernel(void) preempt_disable(); build_all_zonelists(); page_alloc_init(); - printk(KERN_NOTICE "Kernel command line: %s\n", saved_command_line); + printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); parse_early_param(); - parse_args("Booting kernel", command_line, __start___param, + parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); if (!irqs_disabled()) {