aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-03-22 17:02:21 +1100
committerPaul Mackerras <paulus@samba.org>2007-04-13 03:55:14 +1000
commit3af82a8b00f98ca54e4c860eeb2b9ede6d8cadf4 (patch)
tree38b7c1a849817869bae6c38368e389b2cd860ace /arch/powerpc
parent27fbaa9702e548e74dffd21855769f6cedad42bd (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.c52
-rw-r--r--arch/powerpc/boot/ops.h2
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;