aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/setup.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-05-06 02:09:45 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-05-06 02:09:45 -0400
commit9b7a37853a8cd69829eb1d9715a6c09aae01eeec (patch)
tree0ae5f3290d5a3804fc87b7af5af5943104d9531e /arch/sh/kernel/setup.c
parent1483feac74fdfd84a7ed7586c66482842e3b6e86 (diff)
sh: Make initrd detection more robust.
Various boot loaders go to various extents to thwart the initrd detection logic (mostly on account of not being able to be bothered with adhering to the established boot ABI), so we make the detection logic a bit more robust. This makes it possible to work around the SDK7786's firmware's attempts to thwart compressed image booting. Victory is mine. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/setup.c')
-rw-r--r--arch/sh/kernel/setup.c78
1 files changed, 58 insertions, 20 deletions
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 14735d5ede5..9c7f7811af7 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -188,6 +188,63 @@ static inline void __init reserve_crashkernel(void)
188{} 188{}
189#endif 189#endif
190 190
191static void __init check_for_initrd(void)
192{
193#ifdef CONFIG_BLK_DEV_INITRD
194 unsigned long start, end;
195
196 /*
197 * Check for the rare cases where boot loaders adhere to the boot
198 * ABI.
199 */
200 if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE)
201 goto disable;
202
203 start = INITRD_START + __MEMORY_START;
204 end = start + INITRD_SIZE;
205
206 if (unlikely(end <= start))
207 goto disable;
208 if (unlikely(start & ~PAGE_MASK)) {
209 pr_err("initrd must be page aligned\n");
210 goto disable;
211 }
212
213 if (unlikely(start < PAGE_OFFSET)) {
214 pr_err("initrd start < PAGE_OFFSET\n");
215 goto disable;
216 }
217
218 if (unlikely(end > lmb_end_of_DRAM())) {
219 pr_err("initrd extends beyond end of memory "
220 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
221 end, (unsigned long)lmb_end_of_DRAM());
222 goto disable;
223 }
224
225 /*
226 * If we got this far inspite of the boot loader's best efforts
227 * to the contrary, assume we actually have a valid initrd and
228 * fix up the root dev.
229 */
230 ROOT_DEV = Root_RAM0;
231
232 /*
233 * Address sanitization
234 */
235 initrd_start = (unsigned long)__va(__pa(start));
236 initrd_end = initrd_start + INITRD_SIZE;
237
238 reserve_bootmem(__pa(initrd_start), INITRD_SIZE, BOOTMEM_DEFAULT);
239
240 return;
241
242disable:
243 pr_info("initrd disabled\n");
244 initrd_start = initrd_end = 0;
245#endif
246}
247
191void __cpuinit calibrate_delay(void) 248void __cpuinit calibrate_delay(void)
192{ 249{
193 struct clk *clk = clk_get(NULL, "cpu_clk"); 250 struct clk *clk = clk_get(NULL, "cpu_clk");
@@ -277,26 +334,7 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
277 334
278 sparse_memory_present_with_active_regions(0); 335 sparse_memory_present_with_active_regions(0);
279 336
280#ifdef CONFIG_BLK_DEV_INITRD 337 check_for_initrd();
281 ROOT_DEV = Root_RAM0;
282
283 if (LOADER_TYPE && INITRD_START) {
284 unsigned long initrd_start_phys = INITRD_START + __MEMORY_START;
285
286 if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
287 reserve_bootmem(initrd_start_phys, INITRD_SIZE,
288 BOOTMEM_DEFAULT);
289 initrd_start = (unsigned long)__va(initrd_start_phys);
290 initrd_end = initrd_start + INITRD_SIZE;
291 } else {
292 printk("initrd extends beyond end of memory "
293 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
294 initrd_start_phys + INITRD_SIZE,
295 (unsigned long)PFN_PHYS(max_low_pfn));
296 initrd_start = 0;
297 }
298 }
299#endif
300 338
301 reserve_crashkernel(); 339 reserve_crashkernel();
302} 340}