diff options
author | Michal Simek <monstr@monstr.eu> | 2012-08-16 09:53:35 -0400 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2012-10-04 08:59:19 -0400 |
commit | fcc1c0ff2506cab8c3a019374550f68b3cbadcbe (patch) | |
tree | 5e78312ddff66318a7cd38fcaa92e48b7baaf5da /arch/microblaze | |
parent | c7e9a211e22782af5857d265a83abf55619f19ea (diff) |
microblaze: Fix bug with passing command line
When u-boot passes control over to Linux it places the Linux command
line between to the end of __init_end. When space between
__init_end and __bss_start is not COMMAND_LINE_SIZE then
the part of cmdline can be lost.
In extreme case if __init_end == __bss_start u-boot can't pass
any cmdline to Linux kernel.
This patch fix this issue by copying cmd line directly to
cmd_line char array which is placed in data section.
Reported-by: David Mc Andrew <david.mcandrew@xilinx.com>
Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze')
-rw-r--r-- | arch/microblaze/kernel/head.S | 14 | ||||
-rw-r--r-- | arch/microblaze/kernel/setup.c | 13 |
2 files changed, 15 insertions, 12 deletions
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S index 98b17f9f904b..eef84de5e8c8 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S | |||
@@ -109,20 +109,24 @@ no_fdt_arg: | |||
109 | #ifndef CONFIG_CMDLINE_BOOL | 109 | #ifndef CONFIG_CMDLINE_BOOL |
110 | /* | 110 | /* |
111 | * handling command line | 111 | * handling command line |
112 | * copy command line to __init_end. There is space for storing command line. | 112 | * copy command line directly to cmd_line placed in data section. |
113 | */ | 113 | */ |
114 | beqid r5, skip /* Skip if NULL pointer */ | ||
114 | or r6, r0, r0 /* incremment */ | 115 | or r6, r0, r0 /* incremment */ |
115 | ori r4, r0, __init_end /* load address of command line */ | 116 | ori r4, r0, cmd_line /* load address of command line */ |
116 | tophys(r4,r4) /* convert to phys address */ | 117 | tophys(r4,r4) /* convert to phys address */ |
117 | ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ | 118 | ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ |
118 | _copy_command_line: | 119 | _copy_command_line: |
119 | lbu r2, r5, r6 /* r2=r5+r6 - r5 contain pointer to command line */ | 120 | /* r2=r5+r6 - r5 contain pointer to command line */ |
120 | sb r2, r4, r6 /* addr[r4+r6]= r2*/ | 121 | lbu r2, r5, r6 |
122 | beqid r2, skip /* Skip if no data */ | ||
123 | sb r2, r4, r6 /* addr[r4+r6]= r2*/ | ||
121 | addik r6, r6, 1 /* increment counting */ | 124 | addik r6, r6, 1 /* increment counting */ |
122 | bgtid r3, _copy_command_line /* loop for all entries */ | 125 | bgtid r3, _copy_command_line /* loop for all entries */ |
123 | addik r3, r3, -1 /* descrement loop */ | 126 | addik r3, r3, -1 /* decrement loop */ |
124 | addik r5, r4, 0 /* add new space for command line */ | 127 | addik r5, r4, 0 /* add new space for command line */ |
125 | tovirt(r5,r5) | 128 | tovirt(r5,r5) |
129 | skip: | ||
126 | #endif /* CONFIG_CMDLINE_BOOL */ | 130 | #endif /* CONFIG_CMDLINE_BOOL */ |
127 | 131 | ||
128 | #ifdef NOT_COMPILE | 132 | #ifdef NOT_COMPILE |
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 4da971d4392f..9dbc9ecb28f1 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
@@ -40,7 +40,12 @@ DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */ | |||
40 | DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ | 40 | DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */ |
41 | 41 | ||
42 | unsigned int boot_cpuid; | 42 | unsigned int boot_cpuid; |
43 | char cmd_line[COMMAND_LINE_SIZE]; | 43 | /* |
44 | * Placed cmd_line to .data section because can be initialized from | ||
45 | * ASM code. Default position is BSS section which is cleared | ||
46 | * in machine_early_init(). | ||
47 | */ | ||
48 | char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data"))); | ||
44 | 49 | ||
45 | void __init setup_arch(char **cmdline_p) | 50 | void __init setup_arch(char **cmdline_p) |
46 | { | 51 | { |
@@ -130,12 +135,6 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
130 | memset(__bss_start, 0, __bss_stop-__bss_start); | 135 | memset(__bss_start, 0, __bss_stop-__bss_start); |
131 | memset(_ssbss, 0, _esbss-_ssbss); | 136 | memset(_ssbss, 0, _esbss-_ssbss); |
132 | 137 | ||
133 | /* Copy command line passed from bootloader */ | ||
134 | #ifndef CONFIG_CMDLINE_BOOL | ||
135 | if (cmdline && cmdline[0] != '\0') | ||
136 | strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE); | ||
137 | #endif | ||
138 | |||
139 | lockdep_init(); | 138 | lockdep_init(); |
140 | 139 | ||
141 | /* initialize device tree for usage in early_printk */ | 140 | /* initialize device tree for usage in early_printk */ |