aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-03-22 02:02:21 -0400
committerPaul Mackerras <paulus@samba.org>2007-04-12 13:55:14 -0400
commit3af82a8b00f98ca54e4c860eeb2b9ede6d8cadf4 (patch)
tree38b7c1a849817869bae6c38368e389b2cd860ace /arch/powerpc/boot
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/boot')
-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 ab9dfe2b38f1..03c0ccaecf29 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,
205 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 205 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
206 * The buffer is put in it's own section so that tools may locate it easier. 206 * The buffer is put in it's own section so that tools may locate it easier.
207 */ 207 */
208static char builtin_cmdline[COMMAND_LINE_SIZE] 208static char cmdline[COMMAND_LINE_SIZE]
209 __attribute__((__section__("__builtin_cmdline"))); 209 __attribute__((__section__("__builtin_cmdline")));
210 210
211static void get_cmdline(char *buf, int size) 211static void prep_cmdline(void *chosen)
212{ 212{
213 void *devp; 213 if (cmdline[0] == '\0')
214 int len = strlen(builtin_cmdline); 214 getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1);
215 215
216 buf[0] = '\0'; 216 printf("\n\rLinux/PowerPC load: %s", cmdline);
217 /* If possible, edit the command line */
218 if (console_ops.edit_cmdline)
219 console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
220 printf("\n\r");
217 221
218 if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */ 222 /* Put the command line back into the devtree for the kernel */
219 len = min(len, size-1); 223 setprop_str(chosen, "bootargs", cmdline);
220 strncpy(buf, builtin_cmdline, len);
221 buf[len] = '\0';
222 }
223 else if ((devp = finddevice("/chosen")))
224 getprop(devp, "bootargs", buf, size);
225}
226
227static void set_cmdline(char *buf)
228{
229 void *devp;
230
231 if ((devp = finddevice("/chosen")))
232 setprop(devp, "bootargs", buf, strlen(buf) + 1);
233} 224}
234 225
235struct platform_ops platform_ops; 226struct platform_ops platform_ops;
@@ -241,10 +232,16 @@ void start(void)
241{ 232{
242 struct addr_range vmlinux, initrd; 233 struct addr_range vmlinux, initrd;
243 kernel_entry_t kentry; 234 kernel_entry_t kentry;
244 char cmdline[COMMAND_LINE_SIZE];
245 unsigned long ft_addr = 0; 235 unsigned long ft_addr = 0;
246 void *chosen; 236 void *chosen;
247 237
238 /* Do this first, because malloc() could clobber the loader's
239 * command line. Only use the loader command line if a
240 * built-in command line wasn't set by an external tool */
241 if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0'))
242 memmove(cmdline, loader_info.cmdline,
243 min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1));
244
248 if (console_ops.open && (console_ops.open() < 0)) 245 if (console_ops.open && (console_ops.open() < 0))
249 exit(); 246 exit();
250 if (platform_ops.fixups) 247 if (platform_ops.fixups)
@@ -261,18 +258,7 @@ void start(void)
261 vmlinux = prep_kernel(); 258 vmlinux = prep_kernel();
262 initrd = prep_initrd(vmlinux, chosen, 259 initrd = prep_initrd(vmlinux, chosen,
263 loader_info.initrd_addr, loader_info.initrd_size); 260 loader_info.initrd_addr, loader_info.initrd_size);
264 261 prep_cmdline(chosen);
265 /* If cmdline came from zimage wrapper or if we can edit the one
266 * in the dt, print it out and edit it, if possible.
267 */
268 if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
269 get_cmdline(cmdline, COMMAND_LINE_SIZE);
270 printf("\n\rLinux/PowerPC load: %s", cmdline);
271 if (console_ops.edit_cmdline)
272 console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
273 printf("\n\r");
274 set_cmdline(cmdline);
275 }
276 262
277 printf("Finalizing device tree..."); 263 printf("Finalizing device tree...");
278 if (dt_ops.finalize) 264 if (dt_ops.finalize)
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index cc191e8e147f..8008d612402e 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -70,6 +70,8 @@ struct serial_console_data {
70struct loader_info { 70struct loader_info {
71 void *promptr; 71 void *promptr;
72 unsigned long initrd_addr, initrd_size; 72 unsigned long initrd_addr, initrd_size;
73 char *cmdline;
74 int cmdline_len;
73}; 75};
74extern struct loader_info loader_info; 76extern struct loader_info loader_info;
75 77