Commit 3af82a8b authored by David Gibson's avatar David Gibson Committed by Paul Mackerras

[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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 27fbaa97
...@@ -205,31 +205,22 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, ...@@ -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). * 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. * 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"))); __attribute__((__section__("__builtin_cmdline")));
static void get_cmdline(char *buf, int size) static void prep_cmdline(void *chosen)
{ {
void *devp; if (cmdline[0] == '\0')
int len = strlen(builtin_cmdline); 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 (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */ if (console_ops.edit_cmdline)
len = min(len, size-1); console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
strncpy(buf, builtin_cmdline, len); printf("\n\r");
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"))) /* Put the command line back into the devtree for the kernel */
setprop(devp, "bootargs", buf, strlen(buf) + 1); setprop_str(chosen, "bootargs", cmdline);
} }
struct platform_ops platform_ops; struct platform_ops platform_ops;
...@@ -241,10 +232,16 @@ void start(void) ...@@ -241,10 +232,16 @@ void start(void)
{ {
struct addr_range vmlinux, initrd; struct addr_range vmlinux, initrd;
kernel_entry_t kentry; kernel_entry_t kentry;
char cmdline[COMMAND_LINE_SIZE];
unsigned long ft_addr = 0; unsigned long ft_addr = 0;
void *chosen; 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)) if (console_ops.open && (console_ops.open() < 0))
exit(); exit();
if (platform_ops.fixups) if (platform_ops.fixups)
...@@ -261,18 +258,7 @@ void start(void) ...@@ -261,18 +258,7 @@ void start(void)
vmlinux = prep_kernel(); vmlinux = prep_kernel();
initrd = prep_initrd(vmlinux, chosen, initrd = prep_initrd(vmlinux, chosen,
loader_info.initrd_addr, loader_info.initrd_size); loader_info.initrd_addr, loader_info.initrd_size);
prep_cmdline(chosen);
/* 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);
}
printf("Finalizing device tree..."); printf("Finalizing device tree...");
if (dt_ops.finalize) if (dt_ops.finalize)
......
...@@ -70,6 +70,8 @@ struct serial_console_data { ...@@ -70,6 +70,8 @@ struct serial_console_data {
struct loader_info { struct loader_info {
void *promptr; void *promptr;
unsigned long initrd_addr, initrd_size; unsigned long initrd_addr, initrd_size;
char *cmdline;
int cmdline_len;
}; };
extern struct loader_info loader_info; extern struct loader_info loader_info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment