diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2007-03-22 02:02:21 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-12 13:55:14 -0400 |
commit | 3af82a8b00f98ca54e4c860eeb2b9ede6d8cadf4 (patch) | |
tree | 38b7c1a849817869bae6c38368e389b2cd860ace /arch/powerpc/boot | |
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/boot')
-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 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 | */ |
208 | static char builtin_cmdline[COMMAND_LINE_SIZE] | 208 | static char cmdline[COMMAND_LINE_SIZE] |
209 | __attribute__((__section__("__builtin_cmdline"))); | 209 | __attribute__((__section__("__builtin_cmdline"))); |
210 | 210 | ||
211 | static void get_cmdline(char *buf, int size) | 211 | static 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 | |||
227 | static 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 | ||
235 | struct platform_ops platform_ops; | 226 | struct 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 { | |||
70 | struct loader_info { | 70 | struct 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 | }; |
74 | extern struct loader_info loader_info; | 76 | extern struct loader_info loader_info; |
75 | 77 | ||