diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2007-03-22 17:02:21 +1100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-13 03:55:14 +1000 |
commit | 3af82a8b00f98ca54e4c860eeb2b9ede6d8cadf4 (patch) | |
tree | 38b7c1a849817869bae6c38368e389b2cd860ace /arch/powerpc | |
parent | 27fbaa9702e548e74dffd21855769f6cedad42bd (diff) |
[POWERPC] Clean up zImage handling of the command line
This cleans up how the zImage code manipulates the kernel
command line. Notable improvements from the old handling:
- Command line manipulation is consolidated into a new
prep_cmdline() function, rather than being scattered across start()
and some helper functions
- Less stack space use: we use just a single global command
line buffer, which can be initialized by an external tool as before,
we no longer need another command line sized buffer on the stack.
- Easier to support platforms whose firmware passes a
commandline, but not a device tree. Platform code can now point new
loader_info fields to the firmware's command line, rather than having
to do early manipulation of the /chosen bootargs property which may
then be rewritten again by the core.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/boot/main.c | 52 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 2 |
2 files changed, 21 insertions, 33 deletions
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index ab9dfe2b38f..03c0ccaecf2 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -205,31 +205,22 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, * edit the command line passed to vmlinux (by setting /chosen/bootargs). * The buffer is put in it's own section so that tools may locate it easier. */ -static char builtin_cmdline[COMMAND_LINE_SIZE] +static char cmdline[COMMAND_LINE_SIZE] __attribute__((__section__("__builtin_cmdline"))); -static void get_cmdline(char *buf, int size) +static void prep_cmdline(void *chosen) { - void *devp; - int len = strlen(builtin_cmdline); + if (cmdline[0] == '\0') + getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); - buf[0] = '\0'; + printf("\n\rLinux/PowerPC load: %s", cmdline); + /* If possible, edit the command line */ + if (console_ops.edit_cmdline) + console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); + printf("\n\r"); - if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */ - len = min(len, size-1); - strncpy(buf, builtin_cmdline, len); - buf[len] = '\0'; - } - else if ((devp = finddevice("/chosen"))) - getprop(devp, "bootargs", buf, size); -} - -static void set_cmdline(char *buf) -{ - void *devp; - - if ((devp = finddevice("/chosen"))) - setprop(devp, "bootargs", buf, strlen(buf) + 1); + /* Put the command line back into the devtree for the kernel */ + setprop_str(chosen, "bootargs", cmdline); } struct platform_ops platform_ops; @@ -241,10 +232,16 @@ void start(void) { struct addr_range vmlinux, initrd; kernel_entry_t kentry; - char cmdline[COMMAND_LINE_SIZE]; unsigned long ft_addr = 0; void *chosen; + /* Do this first, because malloc() could clobber the loader's + * command line. Only use the loader command line if a + * built-in command line wasn't set by an external tool */ + if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) + memmove(cmdline, loader_info.cmdline, + min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); + if (console_ops.open && (console_ops.open() < 0)) exit(); if (platform_ops.fixups) @@ -261,18 +258,7 @@ void start(void) vmlinux = prep_kernel(); initrd = prep_initrd(vmlinux, chosen, loader_info.initrd_addr, loader_info.initrd_size); - - /* If cmdline came from zimage wrapper or if we can edit the one - * in the dt, print it out and edit it, if possible. - */ - if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) { - get_cmdline(cmdline, COMMAND_LINE_SIZE); - printf("\n\rLinux/PowerPC load: %s", cmdline); - if (console_ops.edit_cmdline) - console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); - printf("\n\r"); - set_cmdline(cmdline); - } + prep_cmdline(chosen); printf("Finalizing device tree..."); if (dt_ops.finalize) diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index cc191e8e147..8008d612402 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -70,6 +70,8 @@ struct serial_console_data { struct loader_info { void *promptr; unsigned long initrd_addr, initrd_size; + char *cmdline; + int cmdline_len; }; extern struct loader_info loader_info; |