diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-12-31 23:06:39 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2008-12-31 23:06:39 +1100 |
commit | 45ff2beda53a8a2edf43a29e8d4d9282b43b83a9 (patch) | |
tree | 9cfc6ddd7e05a9bd0bf72006c7f0c5254f782e9d | |
parent | fd70d10173487db8c68385fc83710e45cfe52af5 (diff) | |
parent | 25bf48b74b9fb23b347d00656b604f9e55c72183 (diff) |
Merge commit 'boot-params/master'
Conflicts:
arch/arm/kernel/setup.c
arch/parisc/kernel/setup.c
arch/sh/boards/mach-microdev/setup.c
arch/sh/boards/mach-migor/setup.c
arch/x86/kernel/cpu/common.c
81 files changed, 629 insertions, 516 deletions
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 02bee6983ce2..fda7c7c23d93 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -496,8 +496,27 @@ register_cpus(void) arch_initcall(register_cpus); +void arch_get_boot_command_line(void) +{ + /* + * Locate the command line. + */ + /* Hack for Jensen... since we're restricted to 8 or 16 chars for + boot flags depending on the boot mode, we need some shorthand. + This should do for installation. */ + if (strcmp(COMMAND_LINE, "INSTALL") == 0) { + strlcpy(command_line, "root=/dev/fd0 load_ramdisk=1", + sizeof command_line); + } else { + strlcpy(command_line, COMMAND_LINE, sizeof command_line); + } + + /* FIXME: Can we skip command_line and just use boot_command_line? */ + strcpy(boot_command_line, command_line); +} + void __init -setup_arch(char **cmdline_p) +setup_arch(void) { extern char _end[]; @@ -542,21 +561,8 @@ setup_arch(char **cmdline_p) kernel_end = callback_init(kernel_end); /* - * Locate the command line. - */ - /* Hack for Jensen... since we're restricted to 8 or 16 chars for - boot flags depending on the boot mode, we need some shorthand. - This should do for installation. */ - if (strcmp(COMMAND_LINE, "INSTALL") == 0) { - strlcpy(command_line, "root=/dev/fd0 load_ramdisk=1", sizeof command_line); - } else { - strlcpy(command_line, COMMAND_LINE, sizeof command_line); - } - strcpy(boot_command_line, command_line); - *cmdline_p = command_line; - - /* * Process command-line arguments. + * FIXME: Use core_param. */ while ((p = strsep(&args, " \t")) != NULL) { if (!*p) continue; diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 7049815d66d5..02ba2267c1ca 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -114,7 +114,6 @@ EXPORT_SYMBOL(elf_platform); static const char *cpu_name; static const char *machine_name; -static char __initdata command_line[COMMAND_LINE_SIZE]; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; @@ -426,10 +425,12 @@ __early_param("mem=", early_mem); /* * Initial parsing of the command line. + * FIXME: Use generic core_param. This actually removes args from the + * cmdline as seen in /proc! */ -static void __init parse_cmdline(char **cmdline_p, char *from) +static void __init parse_cmdline(char *from) { - char c = ' ', *to = command_line; + char c = ' ', *to = boot_command_line; int len = 0; for (;;) { @@ -441,7 +442,7 @@ static void __init parse_cmdline(char **cmdline_p, char *from) int arglen = strlen(p->arg); if (memcmp(from, p->arg, arglen) == 0) { - if (to != command_line) + if (to != boot_command_line) to -= 1; from += arglen; p->fn(&from); @@ -460,7 +461,6 @@ static void __init parse_cmdline(char **cmdline_p, char *from) *to++ = c; } *to = '\0'; - *cmdline_p = command_line; } static void __init @@ -678,7 +678,8 @@ static int __init customize_machine(void) } arch_initcall(customize_machine); -void __init setup_arch(char **cmdline_p) +/* We not only get the command line here, we parse the tags as well. */ +void __init arch_get_boot_command_line(void) { struct tag *tags = (struct tag *)&init_tags; struct machine_desc *mdesc; @@ -686,10 +687,6 @@ void __init setup_arch(char **cmdline_p) setup_processor(); mdesc = setup_machine(machine_arch_type); - machine_name = mdesc->name; - - if (mdesc->soft_reboot) - reboot_setup("s"); if (__atags_pointer) tags = phys_to_virt(__atags_pointer); @@ -708,21 +705,29 @@ void __init setup_arch(char **cmdline_p) if (mdesc->fixup) mdesc->fixup(mdesc, tags, &from, &meminfo); - if (tags->hdr.tag == ATAG_CORE) { - if (meminfo.nr_banks != 0) - squash_mem_tags(tags); - save_atags(tags); - parse_tags(tags); - } + if (meminfo.nr_banks != 0) + squash_mem_tags(tags); + save_atags(tags); + parse_tags(tags); + + /* This copies into boot_command_line */ + parse_cmdline(from); +} + +void __init setup_arch(void) +{ + struct machine_desc *mdesc = setup_machine(machine_arch_type); + + machine_name = mdesc->name; + + if (mdesc->soft_reboot) + reboot_setup("s"); init_mm.start_code = (unsigned long) _text; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; init_mm.brk = (unsigned long) _end; - memcpy(boot_command_line, from, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; - parse_cmdline(cmdline_p, from); paging_init(mdesc); request_standard_resources(&meminfo, mdesc); diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index 5c7083916c33..7b4c0ebbe1ac 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -40,8 +40,6 @@ struct avr32_cpuinfo boot_cpu_data = { }; EXPORT_SYMBOL(boot_cpu_data); -static char __initdata command_line[COMMAND_LINE_SIZE]; - /* * Standard memory resources */ @@ -536,7 +534,12 @@ static void __init setup_bootmem(void) } } -void __init setup_arch (char **cmdline_p) +void __init arch_get_boot_command_line(void) +{ + parse_tags(bootloader_tags); +} + +void __init setup_arch(void) { struct clk *cpu_clk; @@ -554,8 +557,6 @@ void __init setup_arch (char **cmdline_p) kernel_data.start = __pa(init_mm.end_code); kernel_data.end = __pa(init_mm.brk - 1); - parse_tags(bootloader_tags); - setup_processor(); setup_platform(); setup_board(); @@ -579,10 +580,6 @@ void __init setup_arch (char **cmdline_p) ((cpu_hz + 500) / 1000) % 1000); } - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - parse_early_param(); - setup_bootmem(); #ifdef CONFIG_VT diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 71a9a8c53cea..4470bb5ed920 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -710,7 +710,17 @@ static inline int __init get_mem_size(void) BUG(); } -void __init setup_arch(char **cmdline_p) +void arch_get_boot_command_line(void) +{ +#if defined(CONFIG_CMDLINE_BOOL) + strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); +#endif + + /* FIXME: Get rid of command_line and just use boot_command_line? */ + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +} + +void __init setup_arch(void) { unsigned long sclk, cclk; @@ -718,16 +728,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif -#if defined(CONFIG_CMDLINE_BOOL) - strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); - command_line[sizeof(command_line) - 1] = 0; -#endif - - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; - /* setup memory defaults from the user config */ physical_mem_end = 0; _ramend = get_mem_size() * 1024 * 1024; diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index 04d48dd91ddf..d6d161737331 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c @@ -40,6 +40,20 @@ static struct cpu cpu_devices[NR_CPUS]; extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ +void __init arch_get_boot_command_line(void) +{ +#ifdef CONFIG_ETRAX_CMDLINE + if (!strcmp(cris_command_line, "")) { + strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, + COMMAND_LINE_SIZE); + cris_command_line[COMMAND_LINE_SIZE - 1] = '\0'; + } +#endif + + /* FIXME: Do we need cris_command_line at all? */ + strlcpy(boot_command_line, cris_command_line, COMMAND_LINE_SIZE); +} + /* This mainly sets up the memory area, and can be really confusing. * * The physical DRAM is virtually mapped into dram_start to dram_end @@ -56,7 +70,7 @@ extern void show_etrax_copyright(void); /* arch-vX/kernel/setup.c */ * */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { extern void init_etrax_debug(void); unsigned long bootmap_size; @@ -144,19 +158,6 @@ void __init setup_arch(char **cmdline_p) paging_init(); - *cmdline_p = cris_command_line; - -#ifdef CONFIG_ETRAX_CMDLINE - if (!strcmp(cris_command_line, "")) { - strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE); - cris_command_line[COMMAND_LINE_SIZE - 1] = '\0'; - } -#endif - - /* Save command line for future references. */ - memcpy(boot_command_line, cris_command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; - /* give credit for the CRIS port */ show_etrax_copyright(); diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index 0669e1382383..2f1506d63d32 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -718,40 +718,35 @@ void __cpuinit calibrate_delay(void) } /* end calibrate_delay() */ -/*****************************************************************************/ /* - * look through the command line for some things we need to know immediately + * handle a specific memory limit handed over the kernel command line */ -static void __init parse_cmdline_early(char *cmdline) +static int __init mem_parameter(char *data) { - if (!cmdline) - return; - - while (*cmdline) { - if (*cmdline == ' ') - cmdline++; - - /* "mem=XXX[kKmM]" sets SDRAM size to <mem>, overriding the value we worked - * out from the SDRAM controller mask register - */ - if (!memcmp(cmdline, "mem=", 4)) { - unsigned long long mem_size; - - mem_size = memparse(cmdline + 4, &cmdline); - memory_end = memory_start + mem_size; - } + unsigned long long mem_size; - while (*cmdline && *cmdline != ' ') - cmdline++; - } + if (!data || !*data) + return 0; + mem_size = memparse(data, NULL); + memory_end = memory_start + mem_size; + return 0; +} +early_param("mem", mem_parameter); -} /* end parse_cmdline_early() */ +/* + * retrieve the boot command line from RedBoot and stash it somewhere more + * appropriate + */ +void __init arch_get_boot_command_line(void) +{ + memcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE); +} /*****************************************************************************/ /* * */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { #ifdef CONFIG_MMU printk("Linux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); @@ -759,8 +754,6 @@ void __init setup_arch(char **cmdline_p) printk("uClinux FR-V port done by Red Hat Inc <dhowells@redhat.com>\n"); #endif - memcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE); - determine_cpu(); determine_clocks(1); @@ -792,11 +785,6 @@ void __init setup_arch(char **cmdline_p) #endif #endif - /* deal with the command line - RedBoot may have passed one to the kernel */ - memcpy(command_line, boot_command_line, sizeof(command_line)); - *cmdline_p = &command_line[0]; - parse_cmdline_early(command_line); - /* set up the memory description * - by now the stack is part of the init task */ printk("Memory %08lx-%08lx\n", memory_start, memory_end); diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 7fda657110eb..d97d66c850ee 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -91,7 +91,18 @@ static const struct console gdb_console = { }; #endif -void __init setup_arch(char **cmdline_p) +/* FIXME: Can we avoid command_line temporary? */ +void __init arch_get_boot_command_line(void) +{ +#ifdef CONFIG_DEFAULT_CMDLINE + /* set from default command line */ + if (*command_line == '\0') + strcpy(command_line, CONFIG_KERNEL_COMMAND); +#endif + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +} + +void __init setup_arch(void) { int bootmap_size; @@ -145,19 +156,9 @@ void __init setup_arch(char **cmdline_p) (int) memory_end, (int) &_ramend); #endif -#ifdef CONFIG_DEFAULT_CMDLINE - /* set from default command line */ - if (*command_line == '\0') - strcpy(command_line,CONFIG_KERNEL_COMMAND); -#endif - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = 0; - #ifdef DEBUG - if (strlen(*cmdline_p)) - printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p); + if (strlen(command_line)) + printk(KERN_DEBUG "Command line: '%s'\n", command_line); #endif /* diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c index 9196b330ff7f..25fc868d228a 100644 --- a/arch/ia64/dig/setup.c +++ b/arch/ia64/dig/setup.c @@ -25,7 +25,7 @@ #include <asm/system.h> void __init -dig_setup (char **cmdline_p) +dig_setup(void) { unsigned int orig_x, orig_y, num_cols, num_rows, font_height; diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c index f629e903ebc7..a605fba4c93b 100644 --- a/arch/ia64/hp/sim/hpsim_setup.c +++ b/arch/ia64/hp/sim/hpsim_setup.c @@ -38,7 +38,7 @@ ia64_ctl_trace (long on) } void __init -hpsim_setup (char **cmdline_p) +hpsim_setup(void) { ROOT_DEV = Root_SDA1; /* default to first SCSI drive */ diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h index 59c17e446683..4cb8156fea52 100644 --- a/arch/ia64/include/asm/machvec.h +++ b/arch/ia64/include/asm/machvec.h @@ -25,7 +25,7 @@ struct pci_dev; struct msi_desc; struct dma_attrs; -typedef void ia64_mv_setup_t (char **); +typedef void ia64_mv_setup_t (void); typedef void ia64_mv_cpu_init_t (void); typedef void ia64_mv_irq_init_t (void); typedef void ia64_mv_send_ipi_t (int, int, int, int); @@ -111,7 +111,7 @@ machvec_noop_bus (struct pci_bus *bus) { } -extern void machvec_setup (char **); +extern void machvec_setup(void); extern void machvec_timer_interrupt (int, void *); extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int); extern void machvec_dma_sync_sg (struct device *, struct scatterlist *, int, int); diff --git a/arch/ia64/include/asm/paravirt.h b/arch/ia64/include/asm/paravirt.h index 2bf3636473fe..d347b0d5e62b 100644 --- a/arch/ia64/include/asm/paravirt.h +++ b/arch/ia64/include/asm/paravirt.h @@ -64,7 +64,7 @@ struct pv_init_ops { int (*reserve_memory)(struct rsvd_region *region); void (*arch_setup_early)(void); - void (*arch_setup_console)(char **cmdline_p); + void (*arch_setup_console)(void); int (*arch_setup_nomca)(void); void (*post_smp_prepare_boot_cpu)(void); @@ -91,10 +91,10 @@ static inline void paravirt_arch_setup_early(void) pv_init_ops.arch_setup_early(); } -static inline void paravirt_arch_setup_console(char **cmdline_p) +static inline void paravirt_arch_setup_console(void) { if (pv_init_ops.arch_setup_console) - pv_init_ops.arch_setup_console(cmdline_p); + pv_init_ops.arch_setup_console(); } static inline int paravirt_arch_setup_nomca(void) @@ -238,7 +238,7 @@ paravirt_do_steal_accounting(unsigned long *new_itm) #define paravirt_reserve_memory(region) 0 #define paravirt_arch_setup_early() do { } while (0) -#define paravirt_arch_setup_console(cmdline_p) do { } while (0) +#define paravirt_arch_setup_console() do { } while (0) #define paravirt_arch_setup_nomca() 0 #define paravirt_post_smp_prepare_boot_cpu() do { } while (0) diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c index 7ccb228ceedc..2b30f5509da1 100644 --- a/arch/ia64/kernel/machvec.c +++ b/arch/ia64/kernel/machvec.c @@ -60,10 +60,16 @@ machvec_init_from_cmdline(const char *cmdline) return machvec_init(str); } +/* Just make sure 'machvec' param is ignored during general parsing. */ +static int __init ignore_machvec(char *p) +{ + return 0; +} +early_param("machvec", ignore_machvec); #endif /* CONFIG_IA64_GENERIC */ void -machvec_setup (char **arg) +machvec_setup(void) { } EXPORT_SYMBOL(machvec_setup); diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 865af27c7737..09519715e012 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -447,7 +447,7 @@ io_port_init (void) * Returns non-zero if a console couldn't be setup. */ static inline int __init -early_console_setup (char *cmdline) +early_console_setup(char *cmdline) { int earlycons = 0; @@ -529,17 +529,10 @@ int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end) #endif /* CONFIG_PROC_VMCORE */ -void __init -setup_arch (char **cmdline_p) +void __init arch_get_boot_command_line(void) { - unw_init(); - - paravirt_arch_setup_early(); - - ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); - - *cmdline_p = __va(ia64_boot_param->command_line); - strlcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); + strlcpy(boot_command_line, __va(ia64_boot_param->command_line), + COMMAND_LINE_SIZE); efi_init(); io_port_init(); @@ -550,12 +543,19 @@ setup_arch (char **cmdline_p) * that ia64_mv is initialised before any command line * settings may cause console setup to occur */ - machvec_init_from_cmdline(*cmdline_p); + machvec_init_from_cmdline(boot_command_line); #endif +} + +void __init setup_arch(void) +{ + unw_init(); - parse_early_param(); + paravirt_arch_setup_early(); + + ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end___vtop_patchlist); - if (early_console_setup(*cmdline_p) == 0) + if (early_console_setup(boot_command_line) == 0) mark_bsp_online(); #ifdef CONFIG_ACPI @@ -605,7 +605,7 @@ setup_arch (char **cmdline_p) #endif paravirt_banner(); - paravirt_arch_setup_console(cmdline_p); + paravirt_arch_setup_console(); #ifdef CONFIG_VT if (!conswitchp) { @@ -631,7 +631,7 @@ setup_arch (char **cmdline_p) if (!nomca) ia64_mca_init(); - platform_setup(cmdline_p); + platform_setup(); #ifndef CONFIG_IA64_HP_SIM check_sal_cache_flush(); #endif diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 02c5b8a9fb60..a2fffaf1459b 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -100,7 +100,7 @@ EXPORT_SYMBOL(physical_node_map); int num_cnodes; -static void sn_init_pdas(char **); +static void sn_init_pdas(void); static void build_cnode_tables(void); static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; @@ -361,13 +361,12 @@ static unsigned long sn2_rtc_initial; /** * sn_setup - SN platform setup routine - * @cmdline_p: kernel command line * * Handles platform setup for SN machines. This includes determining * the RTC frequency (via a SAL call), initializing secondary CPUs, and * setting up per-node data areas. The console is also initialized here. */ -void __init sn_setup(char **cmdline_p) +void __init sn_setup(void) { long status, ticks_per_sec, drift; u32 version = sn_sal_rev(); @@ -425,11 +424,11 @@ void __init sn_setup(char **cmdline_p) if (vga_console_membase) { /* usable vga ... make tty0 the preferred default console */ - if (!strstr(*cmdline_p, "console=")) + if (!strstr(boot_command_line, "console=")) add_preferred_console("tty", 0, NULL); } else { printk(KERN_DEBUG "SGI: Disabling VGA console\n"); - if (!strstr(*cmdline_p, "console=")) + if (!strstr(boot_command_line, "console=")) add_preferred_console("ttySG", 0, NULL); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -470,7 +469,7 @@ void __init sn_setup(char **cmdline_p) /* * Create the PDAs and NODEPDAs for all the cpus. */ - sn_init_pdas(cmdline_p); + sn_init_pdas(); ia64_mark_idle = &snidle; @@ -502,7 +501,7 @@ void __init sn_setup(char **cmdline_p) * * One time setup for Node Data Area. Called by sn_setup(). */ -static void __init sn_init_pdas(char **cmdline_p) +static void __init sn_init_pdas(void) { cnodeid_t cnode; diff --git a/arch/ia64/uv/kernel/setup.c b/arch/ia64/uv/kernel/setup.c index 7a5ae633198b..fbe20babf955 100644 --- a/arch/ia64/uv/kernel/setup.c +++ b/arch/ia64/uv/kernel/setup.c @@ -58,7 +58,7 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size) BUG(); } -void __init uv_setup(char **cmdline_p) +void __init uv_setup(void) { union uvh_si_addr_map_config_u m_n_config; union uvh_node_id_u node_id; diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c index 04cd12350455..303697d1bab4 100644 --- a/arch/ia64/xen/xen_pv_ops.c +++ b/arch/ia64/xen/xen_pv_ops.c @@ -129,7 +129,7 @@ xen_arch_setup_early(void) } static void __init -xen_arch_setup_console(char **cmdline_p) +xen_arch_setup_console(void) { add_preferred_console("xenboot", 0, NULL); add_preferred_console("tty", 0, NULL); diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 0392112a5d70..109e79b555ae 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -83,10 +83,15 @@ static struct resource code_resource = { unsigned long memory_start; unsigned long memory_end; -void __init setup_arch(char **); int get_cpuinfo(char *); -static __inline__ void parse_mem_cmdline(char ** cmdline_p) +void __init arch_get_boot_command_line(void) +{ + strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); +} + +/* FIXME: use core_param/early_param here. */ +static inline void parse_mem_cmdline(void) { char c = ' '; char *to = command_line; @@ -94,10 +99,6 @@ static __inline__ void parse_mem_cmdline(char ** cmdline_p) int len = 0; int usermem = 0; - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; - memory_start = (unsigned long)CONFIG_MEMORY_START+PAGE_OFFSET; memory_end = memory_start+(unsigned long)CONFIG_MEMORY_SIZE; @@ -124,7 +125,6 @@ static __inline__ void parse_mem_cmdline(char ** cmdline_p) *(to++) = c; } *to = '\0'; - *cmdline_p = command_line; if (usermem) printk(KERN_INFO "user-defined physical RAM map:\n"); } @@ -220,7 +220,7 @@ static unsigned long __init setup_memory(void) extern unsigned long setup_memory(void); #endif /* CONFIG_DISCONTIGMEM */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 4d97bd2bd573..4467c39982c6 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c @@ -26,6 +26,7 @@ #include <linux/initrd.h> #include <asm/bootinfo.h> +#include <asm/sections.h> #include <asm/setup.h> #include <asm/fpu.h> #include <asm/irq.h> @@ -62,7 +63,6 @@ EXPORT_SYMBOL(vme_brdtype); int m68k_is040or060; EXPORT_SYMBOL(m68k_is040or060); -extern int end; extern unsigned long availmem; int m68k_num_memory; @@ -75,8 +75,6 @@ EXPORT_SYMBOL(m68k_memory); struct mem_info m68k_ramdisk; -static char m68k_command_line[CL_SIZE]; - void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; /* machine dependent irq functions */ void (*mach_init_IRQ) (void) __initdata = NULL; @@ -170,8 +168,7 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) break; case BI_COMMAND_LINE: - strlcpy(m68k_command_line, (const char *)data, - sizeof(m68k_command_line)); + /* Done in arch_get_boot_command_line */ break; default: @@ -213,13 +210,26 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) #endif } -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) +{ + /* The bootinfo is located right after the kernel bss */ + const struct bi_record *record = (const struct bi_record *)_end; + + while (record->tag != BI_LAST) { + if (record->tag == BI_COMMAND_LINE) + strlcpy(boot_command_line, (const char *)record->data, + COMMAND_LINE_SIZE); + + record = ((void *)record) + record->size; + } +} + +void __init setup_arch(void) { - extern int _etext, _edata, _end; int i; /* The bootinfo is located right after the kernel bss */ - m68k_parse_bootinfo((const struct bi_record *)&_end); + m68k_parse_bootinfo((const struct bi_record *)_end); if (CPU_IS_040) m68k_is040or060 = 4; @@ -252,14 +262,9 @@ void __init setup_arch(char **cmdline_p) } init_mm.start_code = PAGE_OFFSET; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = (unsigned long) &_edata; - init_mm.brk = (unsigned long) &_end; - - *cmdline_p = m68k_command_line; - memcpy(boot_command_line, *cmdline_p, CL_SIZE); - - parse_early_param(); + init_mm.end_code = (unsigned long)_etext; + init_mm.end_data = (unsigned long)_edata; + init_mm.brk = (unsigned long)_end; #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff --git a/arch/m68knommu/include/asm/machdep.h b/arch/m68knommu/include/asm/machdep.h index de9f47a51cc2..a2110f51635c 100644 --- a/arch/m68knommu/include/asm/machdep.h +++ b/arch/m68knommu/include/asm/machdep.h @@ -19,7 +19,7 @@ extern void (*mach_reset)( void ); extern void (*mach_halt)( void ); extern void (*mach_power_off)( void ); -extern void config_BSP(char *command, int len); +extern void config_BSP(void); extern void do_IRQ(int irq, struct pt_regs *fp); diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 5985f1989021..7891f601eb60 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -41,8 +41,6 @@ unsigned long memory_end; EXPORT_SYMBOL(memory_start); EXPORT_SYMBOL(memory_end); -char __initdata command_line[COMMAND_LINE_SIZE]; - /* machine dependent timer functions */ void (*mach_gettod)(int*, int*, int*, int*, int*, int*); int (*mach_set_clock_mmss)(unsigned long); @@ -111,7 +109,20 @@ void (*mach_power_off)(void); extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end; extern int _ramstart, _ramend; -void __init setup_arch(char **cmdline_p) +void __weak __init platform_get_boot_command_line(void) +{ +} + +void __init arch_get_boot_command_line(void) +{ +#if defined(CONFIG_BOOTPARAM) + strlcpy(boot_command_line, CONFIG_BOOTPARAM_STRING, COMMAND_LINE_SIZE); +#endif + + platform_get_boot_command_line(); +} + +void __init setup_arch(void) { int bootmap_size; @@ -123,12 +134,7 @@ void __init setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) 0; - config_BSP(&command_line[0], sizeof(command_line)); - -#if defined(CONFIG_BOOTPARAM) - strncpy(&command_line[0], CONFIG_BOOTPARAM_STRING, sizeof(command_line)); - command_line[sizeof(command_line) - 1] = 0; -#endif + config_BSP(); printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n"); @@ -176,14 +182,9 @@ void __init setup_arch(char **cmdline_p) (int) memory_start, (int) memory_end); #endif - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = 0; - #ifdef DEBUG - if (strlen(*cmdline_p)) - printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p); + if (strlen(boot_command_line)) + printk(KERN_DEBUG "Command line: '%s'\n", boot_command_line); #endif #if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE) diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c index 53a5920c2b71..f93314fdb7d1 100644 --- a/arch/m68knommu/platform/5206/config.c +++ b/arch/m68knommu/platform/5206/config.c @@ -109,7 +109,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c index d01a5d2b7557..8b4cd9711445 100644 --- a/arch/m68knommu/platform/5206e/config.c +++ b/arch/m68knommu/platform/5206e/config.c @@ -108,16 +108,18 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) -{ - mcf_setimr(MCFSIM_IMR_MASKALL); - #if defined(CONFIG_NETtel) +void __init platform_get_boot_command_line(void) +{ /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0004000, size); - commandp[size-1] = 0; + strlcpy(boot_command_line, (char *)0xf0004000, COMMAND_LINE_SIZE); +} #endif /* CONFIG_NETtel */ +void __init config_BSP(void) +{ + mcf_setimr(MCFSIM_IMR_MASKALL); + mach_reset = coldfire_reset; } diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c index 06d887cdcbfb..e2c5db15a2a9 100644 --- a/arch/m68knommu/platform/520x/config.c +++ b/arch/m68knommu/platform/520x/config.c @@ -114,7 +114,7 @@ void mcf_autovector(unsigned int vec) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mach_reset = coldfire_reset; m520x_uarts_init(); diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c index 13f02611ea23..8bf3e02bc5e6 100644 --- a/arch/m68knommu/platform/523x/config.c +++ b/arch/m68knommu/platform/523x/config.c @@ -98,7 +98,7 @@ void mcf_autovector(unsigned int vec) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_disableall(); mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c index d299f7b8768a..242bd6ede17a 100644 --- a/arch/m68knommu/platform/5249/config.c +++ b/arch/m68knommu/platform/5249/config.c @@ -105,7 +105,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_setimr(MCFSIM_IMR_MASKALL); mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/5272/config.c b/arch/m68knommu/platform/5272/config.c index 230bae691a7f..5e16194753a1 100644 --- a/arch/m68knommu/platform/5272/config.c +++ b/arch/m68knommu/platform/5272/config.c @@ -123,7 +123,18 @@ void mcf_settimericr(int timer, int level) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init platform_get_boot_command_line(void) +{ +#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES) + /* Copy command line from FLASH to local buffer... */ + strlcpy(boot_command_line, (char *)0xf0004000, COMMAND_LINE_SIZE); +#elif defined(CONFIG_CANCam) + /* Copy command line from FLASH to local buffer... */ + strlcpy(boot_command_line, (char *)0xf0010000, COMMAND_LINE_SIZE); +#endif +} + +void __init config_BSP(void) { #if defined (CONFIG_MOD5272) volatile unsigned char *pivrp; @@ -135,16 +146,6 @@ void __init config_BSP(char *commandp, int size) mcf_disableall(); -#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES) - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0004000, size); - commandp[size-1] = 0; -#elif defined(CONFIG_CANCam) - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0010000, size); - commandp[size-1] = 0; -#endif - mcf_timervector = 69; mcf_profilevector = 70; mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c index 73cd1aef4a90..6cd034cfa038 100644 --- a/arch/m68knommu/platform/527x/config.c +++ b/arch/m68knommu/platform/527x/config.c @@ -112,7 +112,7 @@ void mcf_autovector(unsigned int vec) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_disableall(); mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c index dfdb5c2ed8e6..18dcf209d620 100644 --- a/arch/m68knommu/platform/528x/config.c +++ b/arch/m68knommu/platform/528x/config.c @@ -369,7 +369,7 @@ void wildfiremod_halt(void) } #endif -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_disableall(); diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c index 11cff6625dcc..c14adc962815 100644 --- a/arch/m68knommu/platform/5307/config.c +++ b/arch/m68knommu/platform/5307/config.c @@ -118,16 +118,21 @@ void mcf_settimericr(unsigned int timer, unsigned int level) } /***************************************************************************/ +#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ + defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) +void __init platform_get_boot_command_line(void) +{ + /* Copy command line from FLASH to local buffer... */ + strlcpy(boot_command_line, (char *) 0xf0004000, COMMAND_LINE_SIZE); +} +#endif -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_setimr(MCFSIM_IMR_MASKALL); #if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0004000, size); - commandp[size-1] = 0; /* Different timer setup - to prevent device clash */ mcf_timervector = 30; mcf_profilevector = 31; diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c index 4f44b632045b..6dcc61bcdc55 100644 --- a/arch/m68knommu/platform/532x/config.c +++ b/arch/m68knommu/platform/532x/config.c @@ -115,22 +115,20 @@ void mcf_settimericr(unsigned int timer, unsigned int level) } /***************************************************************************/ - -void __init config_BSP(char *commandp, int size) -{ - mcf_setimr(MCFSIM_IMR_MASKALL); - #if !defined(CONFIG_BOOTPARAM) +void __init platform_get_boot_command_line(void) +{ /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0x4000, 4); - if(strncmp(commandp, "kcl ", 4) == 0){ - memcpy(commandp, (char *) 0x4004, size); - commandp[size-1] = 0; - } else { - memset(commandp, 0, size); - } + memcpy(boot_command_line, (char *)0x4000, 4); + if (strncmp(boot_command_line, "kcl ", 4) == 0) + strlcpy(boot_command_line, (char *)0x4004, COMMAND_LINE_SIZE); +} #endif +void __init config_BSP(void) +{ + mcf_setimr(MCFSIM_IMR_MASKALL); + mcf_timervector = 64+32; mcf_profilevector = 64+33; mach_reset = coldfire_reset; diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c index 648b8b778211..bf3c811cab7b 100644 --- a/arch/m68knommu/platform/5407/config.c +++ b/arch/m68knommu/platform/5407/config.c @@ -110,7 +110,7 @@ void mcf_settimericr(unsigned int timer, unsigned int level) /***************************************************************************/ -void __init config_BSP(char *commandp, int size) +void __init config_BSP(void) { mcf_setimr(MCFSIM_IMR_MASKALL); diff --git a/arch/m68knommu/platform/68328/config.c b/arch/m68knommu/platform/68328/config.c index a7bd21deb00f..707688311247 100644 --- a/arch/m68knommu/platform/68328/config.c +++ b/arch/m68knommu/platform/68328/config.c @@ -39,7 +39,7 @@ void m68328_reset (void) /***************************************************************************/ -void config_BSP(char *command, int len) +void config_BSP(void) { printk(KERN_INFO "\n68328 support D. Jeff Dionne <jeff@uclinux.org>\n"); printk(KERN_INFO "68328 support Kenneth Albanowski <kjahds@kjshds.com>\n"); diff --git a/arch/m68knommu/platform/68328/head-pilot.S b/arch/m68knommu/platform/68328/head-pilot.S index aecff532b343..56f3613f2ca4 100644 --- a/arch/m68knommu/platform/68328/head-pilot.S +++ b/arch/m68knommu/platform/68328/head-pilot.S @@ -163,7 +163,7 @@ L1: /* Copy command line from end of bss to command line */ moveal #_ebss, %a0 - moveal #command_line, %a1 + moveal #boot_command_line, %a1 lea %a1@(512), %a2 DBG_PUTC('G') diff --git a/arch/m68knommu/platform/68360/config.c b/arch/m68knommu/platform/68360/config.c index ac629fa30099..88b53bb3e218 100644 --- a/arch/m68knommu/platform/68360/config.c +++ b/arch/m68knommu/platform/68360/config.c @@ -142,8 +142,7 @@ _bsc1(unsigned char *, gethwaddr, int, a) _bsc1(char *, getbenv, char *, a) #endif - -void config_BSP(char *command, int len) +void config_BSP(void) { unsigned char *p; @@ -172,11 +171,14 @@ void config_BSP(char *command, int len) printk(KERN_INFO "uCquicc hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", p[0], p[1], p[2], p[3], p[4], p[5]); +#if 0 /* Did this ever work? Was strcpy supposed to be other way? */ p = getbenv("APPEND"); if (p) strcpy(p,command); else command[0] = 0; +#endif + #else scc1_hwaddr = "\00\01\02\03\04\05"; #endif diff --git a/arch/m68knommu/platform/68EZ328/config.c b/arch/m68knommu/platform/68EZ328/config.c index 1be1a16f6896..b8554794aed7 100644 --- a/arch/m68knommu/platform/68EZ328/config.c +++ b/arch/m68knommu/platform/68EZ328/config.c @@ -52,7 +52,7 @@ _bsc1(unsigned char *, gethwaddr, int, a) _bsc1(char *, getbenv, char *, a) #endif -void config_BSP(char *command, int len) +void config_BSP(void) { unsigned char *p; @@ -64,10 +64,12 @@ void config_BSP(char *command, int len) printk(KERN_INFO "uCsimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", p[0], p[1], p[2], p[3], p[4], p[5]); +#if 0 /* Did this ever work? strcpy wrong way? */ p = getbenv("APPEND"); if (p) strcpy(p,command); else command[0] = 0; #endif +#endif mach_gettod = m68328_timer_gettod; mach_reset = m68ez328_reset; diff --git a/arch/m68knommu/platform/68VZ328/config.c b/arch/m68knommu/platform/68VZ328/config.c index fc5c63054e98..5feae9a25bec 100644 --- a/arch/m68knommu/platform/68VZ328/config.c +++ b/arch/m68knommu/platform/68VZ328/config.c @@ -59,7 +59,7 @@ static void m68vz328_reset(void) ); } -static void init_hardware(char *command, int size) +static void init_hardware(void) { #ifdef CONFIG_DIRECT_IO_ACCESS SCR = 0x10; /* allow user access to internal registers */ @@ -150,7 +150,7 @@ _bsc0(char *, getserialnum) _bsc1(unsigned char *, gethwaddr, int, a) _bsc1(char *, getbenv, char *, a) -static void init_hardware(char *command, int size) +static void init_hardware(void) { char *p; @@ -158,11 +158,13 @@ static void init_hardware(char *command, int size) p = cs8900a_hwaddr = gethwaddr(0); printk(KERN_INFO "uCdimm hwaddr %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", p[0], p[1], p[2], p[3], p[4], p[5]); +#if 0 /* Did this ever work? strcpy wrong way? */ p = getbenv("APPEND"); if (p) strcpy(p, command); else command[0] = 0; +#endif } /***************************************************************************/ @@ -172,7 +174,7 @@ static void m68vz328_reset(void) { } -static void init_hardware(char *command, int size) +static void init_hardware(void) { } @@ -180,11 +182,11 @@ static void init_hardware(char *command, int size) #endif /***************************************************************************/ -void config_BSP(char *command, int size) +void config_BSP(void) { printk(KERN_INFO "68VZ328 DragonBallVZ support (c) 2001 Lineo, Inc.\n"); - init_hardware(command, size); + init_hardware(); mach_gettod = m68328_timer_gettod; mach_reset = m68vz328_reset; diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 4430a1f8fdf1..7c02f39c887e 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -465,7 +465,14 @@ static int __init early_parse_mem(char *p) } early_param("mem", early_parse_mem); -static void __init arch_mem_init(char **cmdline_p) +void arch_get_boot_command_line(void) +{ + /* FIXME: Just replace command_line with boot_command_line? */ + strlcpy(command_line, arcs_cmdline, sizeof(command_line)); + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +} + +static void __init arch_mem_init(void) { extern void plat_mem_setup(void); @@ -475,13 +482,6 @@ static void __init arch_mem_init(char **cmdline_p) pr_info("Determined physical RAM map:\n"); print_memory_map(); - strlcpy(command_line, arcs_cmdline, sizeof(command_line)); - strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - - *cmdline_p = command_line; - - parse_early_param(); - if (usermem) { pr_info("User-defined physical RAM map:\n"); print_memory_map(); @@ -545,7 +545,7 @@ static void __init resource_init(void) } } -void __init setup_arch(char **cmdline_p) +void __init setup_arch() { cpu_probe(); prom_init(); @@ -564,7 +564,7 @@ void __init setup_arch(char **cmdline_p) #endif #endif - arch_mem_init(cmdline_p); + arch_mem_init(); resource_init(); plat_smp_setup(); diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c index e1d88ab51008..310d54226213 100644 --- a/arch/mn10300/kernel/setup.c +++ b/arch/mn10300/kernel/setup.c @@ -60,6 +60,7 @@ static struct resource data_resource = { static unsigned long __initdata phys_memory_base; static unsigned long __initdata phys_memory_end; static unsigned long __initdata memory_end; +static unsigned long __initdata memory_param; unsigned long memory_size; struct thread_info *__current_ti = &init_thread_union.thread_info; @@ -73,58 +74,34 @@ static const char *const mn10300_cputypes[] = { "unknown" }; -/* - * - */ -static void __init parse_mem_cmdline(char **cmdline_p) +void __init arch_get_boot_command_line(void) { - char *from, *to, c; - - /* save unparsed command line copy for /proc/cmdline */ strcpy(boot_command_line, redboot_command_line); +} - /* see if there's an explicit memory size option */ - from = redboot_command_line; - to = redboot_command_line; - c = ' '; - - for (;;) { - if (c == ' ' && !memcmp(from, "mem=", 4)) { - if (to != redboot_command_line) - to--; - memory_size = memparse(from + 4, &from); - } - - c = *(from++); - if (!c) - break; - - *(to++) = c; - } - - *to = '\0'; - *cmdline_p = redboot_command_line; - - if (memory_size == 0) - panic("Memory size not known\n"); +/* + * handle a specific memory limit handed over the kernel command line + */ +static int __init mem_parameter(char *data) +{ + if (!data || !*data) + return 0; - memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS + - memory_size; - if (memory_end > phys_memory_end) - memory_end = phys_memory_end; + memory_param = memparse(data, NULL); + return 0; } +early_param("mem", mem_parameter); /* * architecture specific setup */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { unsigned long bootmap_size; unsigned long kstart_pfn, start_pfn, free_pfn, end_pfn; cpu_init(); unit_setup(); - parse_mem_cmdline(cmdline_p); init_mm.start_code = (unsigned long)&_text; init_mm.end_code = (unsigned long) &_etext; @@ -222,6 +199,16 @@ void __init cpu_init(void) phys_memory_end = phys_memory_base + memory_size; + if (memory_param) + memory_size = memory_param; + if (memory_size == 0) + panic("Memory size not known\n"); + + memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS + + memory_size; + if (memory_end > phys_memory_end) + memory_end = phys_memory_end; + #ifdef CONFIG_FPU fpu_init_state(); #endif diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 8d8b0248a4a9..46e79a606bbd 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -58,30 +58,17 @@ int parisc_bus_is_phys __read_mostly = 1; /* Assume no IOMMU is present */ EXPORT_SYMBOL(parisc_bus_is_phys); #endif -void __init setup_cmdline(char **cmdline_p) +void __init arch_get_boot_command_line(void) { extern unsigned int boot_args[]; /* Collect stuff passed in from the boot loader */ /* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */ - if (boot_args[0] < 64) { - /* called from hpux boot loader */ - boot_command_line[0] = '\0'; - } else { + if (boot_args[0] >= 64) { + /* not called from hpux boot loader */ strcpy(boot_command_line, (char *)__va(boot_args[1])); - -#ifdef CONFIG_BLK_DEV_INITRD - if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ - { - initrd_start = (unsigned long)__va(boot_args[2]); - initrd_end = (unsigned long)__va(boot_args[3]); - } -#endif } - - strcpy(command_line, boot_command_line); - *cmdline_p = command_line; } #ifdef CONFIG_PA11 @@ -114,8 +101,9 @@ void __init dma_ops_init(void) extern int init_per_cpu(int cpuid); extern void collect_boot_cpu_data(void); -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { + extern unsigned int boot_args[]; #ifdef CONFIG_64BIT extern int parisc_narrow_firmware; #endif @@ -137,7 +125,15 @@ void __init setup_arch(char **cmdline_p) } #endif setup_pdc(); - setup_cmdline(cmdline_p); + strcpy(command_line, boot_command_line); + +#ifdef CONFIG_BLK_DEV_INITRD + /* did palo pass us a ramdisk? */ + if (boot_args[0] >= 64 && boot_args[2] != 0) { + initrd_start = (unsigned long)__va(boot_args[2]); + initrd_end = (unsigned long)__va(boot_args[3]); + } +#endif collect_boot_cpu_data(); do_memory_inventory(); /* probe for physical memory */ parisc_cache_init(); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 6f73c739f1e2..8ffc2a00a901 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include <linux/debugfs.h> #include <linux/irq.h> #include <linux/lmb.h> +#include <linux/start_kernel.h> #include <asm/prom.h> #include <asm/rtas.h> @@ -1190,7 +1191,7 @@ void __init early_init_devtree(void *params) /* Save command line for /proc/cmdline and then parse parameters */ strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); - parse_early_param(); + parse_early_and_core_params(boot_command_line); /* Reserve LMB regions used by kernel, initrd, dt, etc... */ lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 9e1ca745d8f0..0b54813a5174 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -272,10 +272,8 @@ static void __init exc_lvl_early_init(void) #endif /* Warning, IO base is not yet inited */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { - *cmdline_p = cmd_line; - /* so udelay does something sensible, assume <= 1000 bogomips */ loops_per_jiffy = 500000000 / HZ; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d8bd2161e738..009b31add6d1 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -508,12 +508,10 @@ static void __init emergency_stack_init(void) * Initializes bootmem, which is unsed to manage page allocation until * mem_init is called. */ -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { ppc64_boot_msg(0x12, "Setup Arch"); - *cmdline_p = cmd_line; - /* * Set cache line size based on type of cpu as a default. * Systems with OF can look in the properties on the cpu node(s) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index d825f4950e4e..46dc71cddc89 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -753,7 +753,7 @@ static void __init setup_hwcaps(void) */ void __init -setup_arch(char **cmdline_p) +setup_arch(void) { /* set up preferred console */ add_preferred_console("ttyS", 0, NULL); @@ -785,10 +785,6 @@ setup_arch(char **cmdline_p) pr_info("Linux is running natively in 64-bit mode\n"); #endif /* CONFIG_64BIT */ - /* Have one command line that is parsed and saved in /proc/cmdline */ - /* boot_command_line has been already set up in early.c */ - *cmdline_p = boot_command_line; - ROOT_DEV = Root_RAM0; init_mm.start_code = PAGE_OFFSET; @@ -801,8 +797,6 @@ setup_arch(char **cmdline_p) else memcpy(&uaccess, &uaccess_std, sizeof(uaccess)); - parse_early_param(); - setup_ipl(); setup_memory_end(); setup_addressing_mode(); diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 3de22ccdeb7e..888fba8a53f3 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c @@ -202,7 +202,7 @@ static void __init setup_port_multiplexing(void) ctrl_outw(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ } -static void __init mpr2_setup(char **cmdline_p) +static void __init mpr2_setup(void) { __set_io_port_base(0xa0000000); diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c index 408bbddaf325..7fa76b858f71 100644 --- a/arch/sh/boards/board-sh7785lcr.c +++ b/arch/sh/boards/board-sh7785lcr.c @@ -278,7 +278,7 @@ static void sh7785lcr_power_off(void) } /* Initialize the board */ -static void __init sh7785lcr_setup(char **cmdline_p) +static void __init sh7785lcr_setup(void) { void __iomem *sm501_reg; diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c index d1bee4884cd6..ceb7b91d9613 100644 --- a/arch/sh/boards/mach-dreamcast/setup.c +++ b/arch/sh/boards/mach-dreamcast/setup.c @@ -33,7 +33,7 @@ extern void aica_time_init(void); extern int gapspci_init(void); extern int systemasic_irq_demux(int); -static void __init dreamcast_setup(char **cmdline_p) +static void __init dreamcast_setup(void) { int i; diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c index 806438b42cac..a62e8ad62303 100644 --- a/arch/sh/boards/mach-highlander/setup.c +++ b/arch/sh/boards/mach-highlander/setup.c @@ -279,7 +279,7 @@ static void r7780rp_power_off(void) /* * Initialize the board */ -static void __init highlander_setup(char **cmdline_p) +static void __init highlander_setup(void) { u16 ver = ctrl_inw(PA_VERREG); int i; diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c index 48fece78ff54..6151c9d34a02 100644 --- a/arch/sh/boards/mach-hp6xx/setup.c +++ b/arch/sh/boards/mach-hp6xx/setup.c @@ -67,7 +67,7 @@ static int __init hp6xx_devices_setup(void) return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); } -static void __init hp6xx_setup(char **cmdline_p) +static void __init hp6xx_setup(void) { u8 v8; u16 v; diff --git a/arch/sh/boards/mach-landisk/setup.c b/arch/sh/boards/mach-landisk/setup.c index db22ea2e6d49..cd5b05f8c050 100644 --- a/arch/sh/boards/mach-landisk/setup.c +++ b/arch/sh/boards/mach-landisk/setup.c @@ -85,7 +85,7 @@ static int __init landisk_devices_setup(void) __initcall(landisk_devices_setup); -static void __init landisk_setup(char **cmdline_p) +static void __init landisk_setup(void) { /* LED ON */ ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED); diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c index c585be00956e..9787545f4e05 100644 --- a/arch/sh/boards/mach-r2d/setup.c +++ b/arch/sh/boards/mach-r2d/setup.c @@ -218,7 +218,7 @@ static void rts7751r2d_power_off(void) /* * Initialize the board */ -static void __init rts7751r2d_setup(char **cmdline_p) +static void __init rts7751r2d_setup(void) { void __iomem *sm501_reg; u16 ver = ctrl_inw(PA_VERREG); diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c index aad94a78dc70..afc85dd74b72 100644 --- a/arch/sh/boards/mach-sdk7780/setup.c +++ b/arch/sh/boards/mach-sdk7780/setup.c @@ -81,7 +81,7 @@ static int __init sdk7780_devices_setup(void) } device_initcall(sdk7780_devices_setup); -static void __init sdk7780_setup(char **cmdline_p) +static void __init sdk7780_setup(void) { u16 ver = ctrl_inw(FPGA_FPVERR); u16 dateStamp = ctrl_inw(FPGA_FPDATER); diff --git a/arch/sh/boards/mach-se/7343/setup.c b/arch/sh/boards/mach-se/7343/setup.c index 4de56f35f419..25d4b81c902b 100644 --- a/arch/sh/boards/mach-se/7343/setup.c +++ b/arch/sh/boards/mach-se/7343/setup.c @@ -163,7 +163,7 @@ device_initcall(sh7343se_devices_setup); /* * Initialize the board */ -static void __init sh7343se_setup(char **cmdline_p) +static void __init sh7343se_setup(void) { ctrl_outw(0xf900, FPGA_OUT); /* FPGA */ diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 527eb6b12610..f3f310ca11f9 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c @@ -25,7 +25,7 @@ static void __init smsc_config(int index, int data) } /* XXX: Another candidate for a more generic cchip machine vector */ -static void __init smsc_setup(char **cmdline_p) +static void __init smsc_setup(void) { outb_p(CONFIG_ENTER, CONFIG_PORT); outb_p(CONFIG_ENTER, CONFIG_PORT); diff --git a/arch/sh/boards/mach-se/7721/setup.c b/arch/sh/boards/mach-se/7721/setup.c index 55af4c36b43a..41b4650732f9 100644 --- a/arch/sh/boards/mach-se/7721/setup.c +++ b/arch/sh/boards/mach-se/7721/setup.c @@ -80,7 +80,7 @@ static int __init se7721_devices_setup(void) } device_initcall(se7721_devices_setup); -static void __init se7721_setup(char **cmdline_p) +static void __init se7721_setup(void) { /* for USB */ ctrl_outw(0x0000, 0xA405010C); /* PGCR */ diff --git a/arch/sh/boards/mach-se/7722/setup.c b/arch/sh/boards/mach-se/7722/setup.c index af84904ed86f..66728c9fe2bb 100644 --- a/arch/sh/boards/mach-se/7722/setup.c +++ b/arch/sh/boards/mach-se/7722/setup.c @@ -153,7 +153,7 @@ static int __init se7722_devices_setup(void) } device_initcall(se7722_devices_setup); -static void __init se7722_setup(char **cmdline_p) +static void __init se7722_setup(void) { ctrl_outw(0x010D, FPGA_OUT); /* FPGA */ diff --git a/arch/sh/boards/mach-se/7780/setup.c b/arch/sh/boards/mach-se/7780/setup.c index 1d3a867e94e3..ce0abfe03c44 100644 --- a/arch/sh/boards/mach-se/7780/setup.c +++ b/arch/sh/boards/mach-se/7780/setup.c @@ -81,7 +81,7 @@ device_initcall(se7780_devices_setup); #define GPIO_PMSELR 0xFFEA0080 #define GPIO_PECR 0xFFEA0008 -static void __init se7780_setup(char **cmdline_p) +static void __init se7780_setup(void) { /* "SH-Linux" on LED Display */ ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) ); diff --git a/arch/sh/boards/mach-sh03/setup.c b/arch/sh/boards/mach-sh03/setup.c index 74cfb4b8b03d..a036120376a6 100644 --- a/arch/sh/boards/mach-sh03/setup.c +++ b/arch/sh/boards/mach-sh03/setup.c @@ -24,7 +24,7 @@ static void __init init_sh03_IRQ(void) /* arch/sh/boards/sh03/rtc.c */ void sh03_time_init(void); -static void __init sh03_setup(char **cmdline_p) +static void __init sh03_setup(void) { board_time_init = sh03_time_init; } diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c index 6f926fd2162b..75e757dd3331 100644 --- a/arch/sh/boards/mach-sh7763rdp/setup.c +++ b/arch/sh/boards/mach-sh7763rdp/setup.c @@ -151,7 +151,7 @@ static int __init sh7763rdp_devices_setup(void) } device_initcall(sh7763rdp_devices_setup); -static void __init sh7763rdp_setup(char **cmdline_p) +static void __init sh7763rdp_setup(void) { /* Board version check */ if (ctrl_inw(CPLD_BOARD_ID_ERV_REG) == 0xECB1) diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h index 64b1c16a0f03..6e4926d5b99d 100644 --- a/arch/sh/include/asm/machvec.h +++ b/arch/sh/include/asm/machvec.h @@ -15,7 +15,7 @@ #include <asm/machtypes.h> struct sh_machine_vector { - void (*mv_setup)(char **cmdline_p); + void (*mv_setup)(void); const char *mv_name; int mv_nr_irqs; diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 534247508572..8ca05c019fc4 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -329,7 +329,19 @@ static int __init parse_elfcorehdr(char *arg) early_param("elfcorehdr", parse_elfcorehdr); #endif -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) +{ +#ifdef CONFIG_CMDLINE_BOOL + strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); +#else + strlcpy(command_line, COMMAND_LINE, sizeof(command_line)); +#endif + + /* FIXME: get rid of command_line, just use boot_command_line? */ + memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +} + +void __init setup_arch(void) { enable_mmu(); @@ -370,18 +382,6 @@ void __init setup_arch(char **cmdline_p) if (!memory_end) memory_end = memory_start + __MEMORY_SIZE; -#ifdef CONFIG_CMDLINE_BOOL - strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); -#else - strlcpy(command_line, COMMAND_LINE, sizeof(command_line)); -#endif - - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - parse_early_param(); - sh_mv_setup(); /* @@ -407,7 +407,7 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) - sh_mv.mv_setup(cmdline_p); + sh_mv.mv_setup(); paging_init(); diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index c96c65d1b58b..5208a2f79fbb 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -205,18 +205,18 @@ struct tt_entry *sparc_ttable; struct pt_regs fake_swapper_regs; -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) +{ + strcpy(boot_command_line, prom_getbootargs()); +} + +void __init setup_arch(void) { int i; unsigned long highest_paddr; sparc_ttable = (struct tt_entry *) &start; - /* Initialize PROM console and command line. */ - *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); - parse_early_param(); - /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; if (!strcmp(&cputypval,"sun4 ")) @@ -264,7 +264,7 @@ void __init setup_arch(char **cmdline_p) #elif defined(CONFIG_PROM_CONSOLE) conswitchp = &prom_con; #endif - boot_flags_init(*cmdline_p); + boot_flags_init(boot_command_line); idprom_init(); if (ARCH_SUN4C) diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 555db7452ebe..26f95b4b0279 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -277,14 +277,14 @@ void __init boot_cpu_id_too_large(int cpu) } #endif -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) { - /* Initialize PROM console and command line. */ - *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); - parse_early_param(); + strcpy(boot_command_line, prom_getbootargs()); +} - boot_flags_init(*cmdline_p); +void __init setup_arch(void) +{ + boot_flags_init(boot_command_line); register_console(&prom_early_console); if (tlb_type == hypervisor) diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 8d84250324b3..3e73bd66dabf 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -371,11 +371,15 @@ int __init linux_main(int argc, char **argv) return start_uml(); } -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) { - paging_init(); + /* FIXME: do we need command_line at all? */ strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; +} + +void __init setup_arch(void) +{ + paging_init(); setup_hostinfo(host_info, sizeof host_info); } diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index ea408dcba513..f53fbb2acf38 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -190,11 +190,11 @@ extern const char * const x86_power_flags[32]; #define clear_cpu_cap(c, bit) clear_bit(bit, (unsigned long *)((c)->x86_capability)) #define setup_clear_cpu_cap(bit) do { \ clear_cpu_cap(&boot_cpu_data, bit); \ - set_bit(bit, (unsigned long *)cleared_cpu_caps); \ + set_bit(bit, (unsigned long *)cpu_caps_cleared); \ } while (0) #define setup_force_cpu_cap(bit) do { \ set_cpu_cap(&boot_cpu_data, bit); \ - clear_bit(bit, (unsigned long *)cleared_cpu_caps); \ + set_bit(bit, (unsigned long *)cpu_caps_set); \ } while (0) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 091cd8855f2e..1b474f63e09c 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -134,7 +134,8 @@ extern struct cpuinfo_x86 boot_cpu_data; extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct doublefault_tss; -extern __u32 cleared_cpu_caps[NCAPINTS]; +extern __u32 cpu_caps_cleared[NCAPINTS]; +extern __u32 cpu_caps_set[NCAPINTS]; #ifdef CONFIG_SMP DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 42e0853030cb..3eb803eaff78 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -220,7 +220,8 @@ static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) return NULL; /* Not found */ } -__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; +__u32 cpu_caps_cleared[NCAPINTS] __cpuinitdata; +__u32 cpu_caps_set[NCAPINTS] __cpuinitdata; /* Current gdt points %fs at the "master" per-cpu area: after this, * it's on the real one. */ @@ -513,6 +514,16 @@ static void __cpuinit identify_cpu_without_cpuid(struct cpuinfo_x86 *c) #endif } +static void __cpuinit override_capabilities(u32 x86_capability[]) +{ + unsigned int i; + + for (i = 0; i < NCAPINTS; i++) { + x86_capability[i] &= ~cpu_caps_cleared[i]; + x86_capability[i] |= cpu_caps_set[i]; + } +} + /* * Do minimum CPU detection early. * Fields really needed: vendor, cpuid_level, family, model, mask, @@ -550,6 +561,8 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) if (this_cpu->c_early_init) this_cpu->c_early_init(c); + override_capabilities(c->x86_capability); + validate_pat_support(c); #ifdef CONFIG_SMP @@ -705,6 +718,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) #endif init_hypervisor(c); + + /* Command-line override before we AND into smp all cpus cap. */ + override_capabilities(c->x86_capability); + /* * On SMP, boot_cpu_data holds the common feature set between * all CPUs; so make sure that we indicate which features are @@ -717,10 +734,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) boot_cpu_data.x86_capability[i] &= c->x86_capability[i]; } - /* Clear all flags overriden by options */ - for (i = 0; i < NCAPINTS; i++) - c->x86_capability[i] &= ~cleared_cpu_caps[i]; - #ifdef CONFIG_X86_MCE /* Init Machine Check Exception if available. */ mcheck_init(c); diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index e85826829cf2..795b2bc78787 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -37,6 +37,8 @@ * copied. It doesn't get modified afterwards. It's registered for the * /sys/firmware/memmap interface. * + * user_e820, exactmap and memlimit are set on cmdline by mem= and memmap=. + * * That memory map is not modified and is used as base for kexec. The kexec'd * kernel should get the same memory map as the firmware provides. Then the * user can e.g. boot the original kernel with mem=1G while still booting the @@ -44,6 +46,9 @@ */ struct e820map e820; struct e820map e820_saved; +static struct e820map user_e820 __initdata; +static bool exactmap __initdata; +static u64 memlimit __initdata; /* For PCI or other memory-mapped resources */ unsigned long pci_mem_start = 0xaeedbabe; @@ -107,22 +112,28 @@ int __init e820_all_mapped(u64 start, u64 end, unsigned type) return 0; } -/* - * Add a memory region to the kernel e820 map. - */ -void __init e820_add_region(u64 start, u64 size, int type) +static void __init __e820_add_region(struct e820map *e820, + u64 start, u64 size, int type) { - int x = e820.nr_map; + int x = e820->nr_map; - if (x == ARRAY_SIZE(e820.map)) { + if (x == ARRAY_SIZE(e820->map)) { printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); return; } - e820.map[x].addr = start; - e820.map[x].size = size; - e820.map[x].type = type; - e820.nr_map++; + e820->map[x].addr = start; + e820->map[x].size = size; + e820->map[x].type = type; + e820->nr_map++; +} + +/* + * Add a memory region to the kernel e820 map. + */ +void __init e820_add_region(u64 start, u64 size, int type) +{ + __e820_add_region(&e820, start, size, type); } void __init e820_print_map(char *who) @@ -1178,13 +1189,9 @@ static void early_panic(char *msg) panic(msg); } -static int userdef __initdata; - /* "mem=nopentium" disables the 4MB page tables. */ static int __init parse_memopt(char *p) { - u64 mem_size; - if (!p) return -EINVAL; @@ -1195,10 +1202,7 @@ static int __init parse_memopt(char *p) } #endif - userdef = 1; - mem_size = memparse(p, &p); - e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); - + memlimit = memparse(p, &p); return 0; } early_param("mem", parse_memopt); @@ -1212,16 +1216,7 @@ static int __init parse_memmap_opt(char *p) return -EINVAL; if (!strncmp(p, "exactmap", 8)) { -#ifdef CONFIG_CRASH_DUMP - /* - * If we are doing a crash dump, we still need to know - * the real mem size before original memory map is - * reset. - */ - saved_max_pfn = e820_end_of_ram_pfn(); -#endif - e820.nr_map = 0; - userdef = 1; + exactmap = true; return 0; } @@ -1230,18 +1225,18 @@ static int __init parse_memmap_opt(char *p) if (p == oldp) return -EINVAL; - userdef = 1; if (*p == '@') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_RAM); + __e820_add_region(&user_e820, start_at, mem_size, E820_RAM); } else if (*p == '#') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_ACPI); + __e820_add_region(&user_e820, start_at, mem_size, E820_ACPI); } else if (*p == '$') { start_at = memparse(p+1, &p); - e820_add_region(start_at, mem_size, E820_RESERVED); + __e820_add_region(&user_e820, start_at, mem_size, + E820_RESERVED); } else - e820_remove_range(mem_size, ULLONG_MAX - mem_size, E820_RAM, 1); + memlimit = mem_size; return *p == '\0' ? 0 : -EINVAL; } @@ -1249,6 +1244,33 @@ early_param("memmap", parse_memmap_opt); void __init finish_e820_parsing(void) { + bool userdef = false; + int i; + + if (memlimit) { + e820_remove_range(memlimit, ULLONG_MAX - memlimit, E820_RAM, 1); + userdef = true; + } + + if (exactmap) { +#ifdef CONFIG_CRASH_DUMP + /* + * If we are doing a crash dump, we still need to know + * the real mem size before original memory map is + * reset. + */ + saved_max_pfn = e820_end_of_ram_pfn(); +#endif + e820.nr_map = 0; + userdef = true; + } + + for (i = 0; i < user_e820.nr_map; i++) { + e820_add_region(user_e820.map[i].addr, user_e820.map[i].size, + user_e820.map[i].type); + userdef = true; + } + if (userdef) { int nr = e820.nr_map; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index ae0d8042cf69..29ccaa135547 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -638,6 +638,25 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { {} }; +void __init arch_get_boot_command_line(void) +{ +#ifdef CONFIG_CMDLINE_BOOL +#ifdef CONFIG_CMDLINE_OVERRIDE + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); +#else + if (builtin_cmdline[0]) { + /* append boot loader cmdline to builtin */ + strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); + strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); + strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); + } +#endif +#endif + + /* FIXME: Get rid of command_line? */ + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); +} + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -650,8 +669,7 @@ static struct dmi_system_id __initdata bad_bios_dmi_table[] = { * * Note: On x86_64, fixmaps are ready for use even before this is called. */ - -void __init setup_arch(char **cmdline_p) +void __init setup_arch(void) { #ifdef CONFIG_X86_32 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); @@ -728,24 +746,6 @@ void __init setup_arch(char **cmdline_p) bss_resource.start = virt_to_phys(&__bss_start); bss_resource.end = virt_to_phys(&__bss_stop)-1; -#ifdef CONFIG_CMDLINE_BOOL -#ifdef CONFIG_CMDLINE_OVERRIDE - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); -#else - if (builtin_cmdline[0]) { - /* append boot loader cmdline to builtin */ - strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE); - strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE); - strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); - } -#endif -#endif - - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - parse_early_param(); - #ifdef CONFIG_X86_64 check_efer(); #endif @@ -784,7 +784,6 @@ void __init setup_arch(char **cmdline_p) probe_roms(); #endif - /* after parse_early_param, so could debug it */ insert_resource(&iomem_resource, &code_resource); insert_resource(&iomem_resource, &data_resource); insert_resource(&iomem_resource, &bss_resource); diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 37635c584106..6e3d187b52ad 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -576,10 +576,8 @@ static int disable_nx __initdata; static int __init noexec_setup(char *str) { if (!str || !strcmp(str, "on")) { - if (cpu_has_nx) { - __supported_pte_mask |= _PAGE_NX; - disable_nx = 0; - } + __supported_pte_mask |= _PAGE_NX; + disable_nx = 0; } else { if (!strcmp(str, "off")) { disable_nx = 1; @@ -597,6 +595,11 @@ static void __init set_nx(void) { unsigned int v[4], l, h; + if ((__supported_pte_mask & _PAGE_NX) && !cpu_has_nx) { + printk("'noexec' ignored: CPU not capable\n"); + __supported_pte_mask &= ~_PAGE_NX; + } + if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h index e3d5a48ad495..0820871f7c69 100644 --- a/arch/xtensa/include/asm/platform.h +++ b/arch/xtensa/include/asm/platform.h @@ -24,10 +24,9 @@ extern void platform_init(bp_tag_t*); /* - * platform_setup is called from setup_arch with a pointer to the command-line - * string. + * platform_setup is called from setup_arch. */ -extern void platform_setup (char **); +extern void platform_setup(void); /* * platform_init_irq is called from init_IRQ. diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 9606d2bd1dd9..0dc596f88161 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -198,10 +198,6 @@ void __init init_arch(bp_tag_t *bp_start) sysmem.nr_banks = 0; -#ifdef CONFIG_CMDLINE_BOOL - strcpy(command_line, default_command_line); -#endif - /* Parse boot parameters */ if (bp_start) @@ -240,15 +236,20 @@ extern char _UserExceptionVector_text_end; extern char _DoubleExceptionVector_literal_start; extern char _DoubleExceptionVector_text_end; -void __init setup_arch(char **cmdline_p) +void __init arch_get_boot_command_line(void) +{ +#ifdef CONFIG_CMDLINE_BOOL + strcpy(command_line, default_command_line); +#endif + /* FIXME: Can we skip command_line? */ + strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); +} + +void __init setup_arch(void) { extern int mem_reserve(unsigned long, unsigned long, int); extern void bootmem_init(void); - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; - *cmdline_p = command_line; - /* Reserve some memory regions */ #ifdef CONFIG_BLK_DEV_INITRD @@ -280,7 +281,7 @@ void __init setup_arch(char **cmdline_p) bootmem_init(); - platform_setup(cmdline_p); + platform_setup(); paging_init(); diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c index f60c8cf6dfbe..365a4d7692c7 100644 --- a/arch/xtensa/platforms/iss/setup.c +++ b/arch/xtensa/platforms/iss/setup.c @@ -104,7 +104,7 @@ static struct notifier_block iss_panic_block = { 0 }; -void __init platform_setup(char **p_cmdline) +void __init platform_setup(void) { atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block); } diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index be1fa0723f2c..74d9dcd46e52 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -962,8 +962,12 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, } EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg); -/* format to disable USB on kernel command line is: nousb */ -__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444); +/* To disable USB, kernel command line is 'nousb' not 'usbcore.nousb' */ +#ifdef MODULE +module_param(nousb, bool, 0444); +#else +core_param(nousb, nousb, bool, 0444); +#endif /* * for external read access to <nousb> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index acb72d8f01c0..c3168170878a 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -232,6 +232,9 @@ VMLINUX_SYMBOL(__start___param) = .; \ *(__param) \ VMLINUX_SYMBOL(__stop___param) = .; \ + VMLINUX_SYMBOL(__start___core_param) = .; \ + *(__core_param) \ + VMLINUX_SYMBOL(__stop___core_param) = .; \ . = ALIGN((align)); \ VMLINUX_SYMBOL(__end_rodata) = .; \ } \ diff --git a/include/linux/init.h b/include/linux/init.h index 68cb0265d009..8cd1a933ccdf 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -149,7 +149,8 @@ extern char *saved_command_line; extern unsigned int reset_devices; /* used by init/main.c */ -void setup_arch(char **); +void setup_arch(void); +void arch_get_boot_command_line(void); void prepare_namespace(void); extern void (*late_time_init)(void); @@ -245,8 +246,6 @@ struct obs_kernel_param { #define early_param(str, fn) \ __setup_param(str, fn, fn, 1) -/* Relies on boot_command_line being set */ -void __init parse_early_param(void); #endif /* __ASSEMBLY__ */ /** diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index e4af3399ef48..b2d58055dad2 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -79,7 +79,7 @@ struct kparam_array parameters. perm sets the visibility in sysfs: 000 means it's not there, read bits mean it's readable, write bits mean it's writable. */ -#define __module_param_call(prefix, name, set, get, arg, perm) \ +#define __module_param_call(prefix, section, name, set, get, arg, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ @@ -87,11 +87,12 @@ struct kparam_array static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ - __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ + __attribute__ ((unused, __section__(section), aligned(sizeof(void *)))) \ = { __param_str_##name, perm, set, get, { arg } } #define module_param_call(name, set, get, arg, perm) \ - __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm) + __module_param_call(MODULE_PARAM_PREFIX, "__param", \ + name, set, get, arg, perm) /* Helper functions: type is byte, short, ushort, int, uint, long, ulong, charp, bool or invbool, or XXX if you define param_get_XXX, @@ -106,21 +107,26 @@ struct kparam_array #ifndef MODULE /** - * core_param - define a historical core kernel parameter. + * core_param - define a core kernel parameter to be set very early * @name: the name of the cmdline and sysfs parameter (often the same as var) * @var: the variable * @type: the type (for param_set_##type and param_get_##type) * @perm: visibility in sysfs * - * core_param is just like module_param(), but cannot be modular and - * doesn't add a prefix (such as "printk."). This is for compatibility - * with __setup(), and it makes sense as truly core parameters aren't - * tied to the particular file they're in. + * core_param is just like module_param(), but cannot be modular, + * doesn't add a prefix (such as "printk.") and is called insanely + * early in boot. This is for compatibility with __setup(), and it + * makes sense as truly core parameters aren't tied to the particular + * file they're in. + * + * Note: You can't use 'charp' here (which keeps a pointer into our + * tmp cmdline). */ #define core_param(name, var, type, perm) \ param_check_##type(name, &(var)); \ - __module_param_call("", name, param_set_##type, param_get_##type, \ - &var, perm) + __module_param_call("", "__core_param", name, param_set_##type, \ + param_get_##type, &var, perm \ + + BUILD_BUG_ON_ZERO(param_##type##_keeps_reference)) #endif /* !MODULE */ /* Actually copy string: maxlen param is usually sizeof(string). */ @@ -136,7 +142,8 @@ extern int parse_args(const char *name, char *args, struct kernel_param *params, unsigned num, - int (*unknown)(char *param, char *val)); + int (*unknown)(char *param, char *val), + bool restore_args); /* All the helper functions */ /* The macros to do compile-time type checking stolen from Jakub @@ -147,42 +154,52 @@ extern int parse_args(const char *name, extern int param_set_byte(const char *val, struct kernel_param *kp); extern int param_get_byte(char *buffer, struct kernel_param *kp); #define param_check_byte(name, p) __param_check(name, p, unsigned char) +#define param_byte_keeps_reference 0 extern int param_set_short(const char *val, struct kernel_param *kp); extern int param_get_short(char *buffer, struct kernel_param *kp); #define param_check_short(name, p) __param_check(name, p, short) +#define param_short_keeps_reference 0 extern int param_set_ushort(const char *val, struct kernel_param *kp); extern int param_get_ushort(char *buffer, struct kernel_param *kp); #define param_check_ushort(name, p) __param_check(name, p, unsigned short) +#define param_ushort_keeps_reference 0 extern int param_set_int(const char *val, struct kernel_param *kp); extern int param_get_int(char *buffer, struct kernel_param *kp); #define param_check_int(name, p) __param_check(name, p, int) +#define param_int_keeps_reference 0 extern int param_set_uint(const char *val, struct kernel_param *kp); extern int param_get_uint(char *buffer, struct kernel_param *kp); #define param_check_uint(name, p) __param_check(name, p, unsigned int) +#define param_uint_keeps_reference 0 extern int param_set_long(const char *val, struct kernel_param *kp); extern int param_get_long(char *buffer, struct kernel_param *kp); #define param_check_long(name, p) __param_check(name, p, long) +#define param_long_keeps_reference 0 extern int param_set_ulong(const char *val, struct kernel_param *kp); extern int param_get_ulong(char *buffer, struct kernel_param *kp); #define param_check_ulong(name, p) __param_check(name, p, unsigned long) +#define param_ulong_keeps_reference 0 extern int param_set_charp(const char *val, struct kernel_param *kp); extern int param_get_charp(char *buffer, struct kernel_param *kp); #define param_check_charp(name, p) __param_check(name, p, char *) +#define param_charp_keeps_reference 1 extern int param_set_bool(const char *val, struct kernel_param *kp); extern int param_get_bool(char *buffer, struct kernel_param *kp); #define param_check_bool(name, p) __param_check(name, p, int) +#define param_bool_keeps_reference 0 extern int param_set_invbool(const char *val, struct kernel_param *kp); extern int param_get_invbool(char *buffer, struct kernel_param *kp); #define param_check_invbool(name, p) __param_check(name, p, int) +#define param_invbool_keeps_reference 0 /* Comma-separated array: *nump is set to number they actually specified. */ #define module_param_array_named(name, array, type, nump, perm) \ @@ -224,4 +241,8 @@ static inline void module_param_sysfs_remove(struct module *mod) { } #endif +/* Created by include/asm-generic/vmlinux.lds.h */ +extern struct kernel_param __start___core_param[], __stop___core_param[]; +extern struct kernel_param __start___param[], __stop___param[]; + #endif /* _LINUX_MODULE_PARAMS_H */ diff --git a/include/linux/start_kernel.h b/include/linux/start_kernel.h index d3e5f2756545..347cc9585191 100644 --- a/include/linux/start_kernel.h +++ b/include/linux/start_kernel.h @@ -9,4 +9,7 @@ extern asmlinkage void __init start_kernel(void); +/* Usually called by start_kernel, but some nasty archs need it earlier. */ +void __init parse_early_and_core_params(char *cmdline); + #endif /* _LINUX_START_KERNEL_H */ diff --git a/init/main.c b/init/main.c index 403bff07e25d..8fc08d4b7cab 100644 --- a/init/main.c +++ b/init/main.c @@ -126,8 +126,6 @@ extern void softirq_init(void); 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; @@ -209,7 +207,7 @@ static int __init obsolete_checksetup(char *line) int n = strlen(p->str); if (!strncmp(line, p->str, n)) { if (p->early) { - /* Already done in parse_early_param? + /* Already done in do_early_param? * (Needs exact match on param part). * Keep iterating, as we can have early * params and __setups of same names 8( */ @@ -259,12 +257,26 @@ static int __init loglevel(char *str) early_param("loglevel", loglevel); +static bool __init is_core_param(const char *param) +{ + const struct kernel_param *i; + + for (i = __start___core_param; i < __stop___core_param; i++) + if (strcmp(param, i->name) == 0) + return true; + return false; +} + /* * Unknown boot options get handed to init, unless they look like * failed parameters */ static int __init unknown_bootoption(char *param, char *val) { + /* Already handled as a core param? */ + if (is_core_param(param)) + return 0; + /* Change NUL term back to "=", to make "param" the whole string. */ if (val) { /* param=val or param="val"? */ @@ -436,20 +448,6 @@ 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 * be reaped by free_initmem before the root thread has proceeded to @@ -501,21 +499,6 @@ static int __init do_early_param(char *param, char *val) 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, boot_command_line, COMMAND_LINE_SIZE); - parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); - done = 1; -} - /* * Activate the first processor. */ @@ -537,10 +520,30 @@ void __init __weak thread_info_cache_init(void) { } +/* Non-destructive early parse of commandline. PowerPC calls this early. */ +void __init parse_early_and_core_params(char *cmdline) +{ + static bool __initdata done = false; + + if (done) + return; + + parse_args("Core and early params", cmdline, + __start___core_param, + __stop___core_param - __start___core_param, + do_early_param, true); + done = true; +} + asmlinkage void __init start_kernel(void) { - char * command_line; - extern struct kernel_param __start___param[], __stop___param[]; + char *static_command_line; + + printk(KERN_NOTICE); + printk(linux_banner); + + arch_get_boot_command_line(); + parse_early_and_core_params(boot_command_line); smp_setup_processor_id(); @@ -571,11 +574,9 @@ asmlinkage void __init start_kernel(void) tick_init(); boot_cpu_init(); page_address_init(); - printk(KERN_NOTICE); - printk(linux_banner); - setup_arch(&command_line); + setup_arch(); mm_init_owner(&init_mm, &init_task); - setup_command_line(command_line); + unwind_setup(); setup_per_cpu_areas(); setup_nr_cpu_ids(); @@ -595,10 +596,12 @@ asmlinkage void __init start_kernel(void) build_all_zonelists(); page_alloc_init(); printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line); - parse_early_param(); + /* param parsing can keep pointers to the commandline. */ + static_command_line = alloc_bootmem(strlen(boot_command_line)+1); + strcpy(static_command_line, boot_command_line); parse_args("Booting kernel", static_command_line, __start___param, __stop___param - __start___param, - &unknown_bootoption); + &unknown_bootoption, false); if (!irqs_disabled()) { printk(KERN_WARNING "start_kernel(): bug: interrupts were " "enabled *very* early, fixing it\n"); @@ -700,6 +703,8 @@ asmlinkage void __init start_kernel(void) ftrace_init(); + saved_command_line = kstrdup(boot_command_line, GFP_KERNEL); + /* Do the rest non-__init'ed, we're now alive */ rest_init(); } diff --git a/kernel/kexec.c b/kernel/kexec.c index 3fb855ad6aa0..46071b20e98a 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1273,6 +1273,7 @@ static int __init parse_crashkernel_simple(char *cmdline, /* * That function is the entry point for command line parsing and should be * called from the arch-specific code. + * FIXME: Use core_param? */ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, diff --git a/kernel/module.c b/kernel/module.c index 2f64a2278d1e..41978d15d58b 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2248,7 +2248,7 @@ static noinline struct module *load_module(void __user *umod, */ list_add_rcu(&mod->list, &modules); - err = parse_args(mod->name, mod->args, kp, num_kp, NULL); + err = parse_args(mod->name, mod->args, kp, num_kp, NULL, false); if (err < 0) goto unlink; diff --git a/kernel/params.c b/kernel/params.c index a1e3025b19a9..774ac7668e6d 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -30,6 +30,15 @@ #define DEBUGP(fmt, a...) #endif +/* + * If the arch already sets boot_command_line, we need do nothing. + * This is not in init/main.c because David Howells reports that on FRV + * gcc 4.1.2 will inline empty functions, ignoring noinline and weak. + */ +void __init __weak arch_get_boot_command_line(void) +{ +} + static inline char dash2underscore(char c) { if (c == '-') @@ -72,9 +81,36 @@ static int parse_one(char *param, return -ENOENT; } +struct replacements { + unsigned int num; + struct { + char *pos; + char oldc; + } replace[3]; +}; + +static void replace(char *place, char newc, struct replacements *replacements) +{ + BUG_ON(replacements->num == ARRAY_SIZE(replacements->replace)); + replacements->replace[replacements->num].pos = place; + replacements->replace[replacements->num].oldc = *place; + *place = newc; + replacements->num++; + +} + +static void unreplace_all(struct replacements *replaced) +{ + unsigned int i; + + for (i = 0; i < replaced->num; i++) + *replaced->replace[i].pos = replaced->replace[i].oldc; +} + /* You can use " around spaces, but can't escape ". */ /* Hyphens and underscores equivalent in parameter names. */ -static char *next_arg(char *args, char **param, char **val) +static char *next_arg(char *args, char **param, char **val, + struct replacements *replacements) { unsigned int i, equals = 0; int in_quote = 0, quoted = 0; @@ -101,21 +137,21 @@ static char *next_arg(char *args, char **param, char **val) if (!equals) *val = NULL; else { - args[equals] = '\0'; + replace(&args[equals], '\0', replacements); *val = args + equals + 1; /* Don't include quotes in value. */ if (**val == '"') { (*val)++; if (args[i-1] == '"') - args[i-1] = '\0'; + replace(&args[i-1], '\0', replacements); } if (quoted && args[i-1] == '"') - args[i-1] = '\0'; + replace(&args[i-1], '\0', replacements); } if (args[i]) { - args[i] = '\0'; + replace(&args[i], '\0', replacements); next = args + i + 1; } else next = args + i; @@ -131,7 +167,8 @@ int parse_args(const char *name, char *args, struct kernel_param *params, unsigned num, - int (*unknown)(char *param, char *val)) + int (*unknown)(char *param, char *val), + bool restore_args) { char *param, *val; @@ -144,14 +181,18 @@ int parse_args(const char *name, while (*args) { int ret; int irq_was_disabled; + struct replacements replaced = { .num = 0 }; - args = next_arg(args, ¶m, &val); + args = next_arg(args, ¶m, &val, &replaced); irq_was_disabled = irqs_disabled(); ret = parse_one(param, val, params, num, unknown); if (irq_was_disabled && !irqs_disabled()) { printk(KERN_WARNING "parse_args(): option '%s' enabled " "irq's!\n", param); } + if (restore_args) + unreplace_all(&replaced); + switch (ret) { case -ENOENT: printk(KERN_ERR "%s: Unknown parameter `%s'\n", @@ -376,8 +417,6 @@ int param_get_string(char *buffer, struct kernel_param *kp) #define to_module_attr(n) container_of(n, struct module_attribute, attr); #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); -extern struct kernel_param __start___param[], __stop___param[]; - struct param_attribute { struct module_attribute mattr; @@ -636,16 +675,17 @@ static void __init param_sysfs_builtin(void) continue; dot = strchr(kp->name, '.'); - if (!dot) { - /* This happens for core_param() */ - strcpy(modname, "kernel"); - name_len = 0; - } else { - name_len = dot - kp->name + 1; - strlcpy(modname, kp->name, name_len); - } + name_len = dot - kp->name + 1; + strlcpy(modname, kp->name, name_len); kernel_add_sysfs_param(modname, kp, name_len); } + + for (kp = __start___core_param; kp < __stop___core_param; kp++) { + if (kp->perm == 0) + continue; + + kernel_add_sysfs_param("kernel", kp, 0); + } } |