aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/setup.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-09-20 09:58:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-09-20 09:58:41 -0400
commit65912a84c0f33304fa5ea004c7b6ee58d5f5572e (patch)
treea9a684ed713f09cd47d6bd1cfe6872cf757feb58 /arch/s390/kernel/setup.c
parent4ba069b802c29eee066385f9826e2d83716626b4 (diff)
[S390] initrd vs. bootmem bitmap.
Move initrd if the bitmap of the bootmem allocator would overwrite it. In addition this patch sets the default size and address of the initrd to 0. Therefore all boot loaders must set the initrd size and address correctly. This is especially relevant for ftp boot via HMC/SE, where this change requires a special patch file entry in the .ins file which sets these two values contained at address 0x10408 and 0x10410. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/setup.c')
-rw-r--r--arch/s390/kernel/setup.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index c902f059c7aa..89051e8a5d8d 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -37,6 +37,7 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/notifier.h> 39#include <linux/notifier.h>
40#include <linux/pfn.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/system.h> 43#include <asm/system.h>
@@ -501,13 +502,47 @@ setup_memory(void)
501 * partially used pages are not usable - thus 502 * partially used pages are not usable - thus
502 * we are rounding upwards: 503 * we are rounding upwards:
503 */ 504 */
504 start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT; 505 start_pfn = PFN_UP(__pa(&_end));
505 end_pfn = max_pfn = memory_end >> PAGE_SHIFT; 506 end_pfn = max_pfn = PFN_DOWN(memory_end);
506 507
507 /* Initialize storage key for kernel pages */ 508 /* Initialize storage key for kernel pages */
508 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++) 509 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
509 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY); 510 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
510 511
512#ifdef CONFIG_BLK_DEV_INITRD
513 /*
514 * Move the initrd in case the bitmap of the bootmem allocater
515 * would overwrite it.
516 */
517
518 if (INITRD_START && INITRD_SIZE) {
519 unsigned long bmap_size;
520 unsigned long start;
521
522 bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);
523 bmap_size = PFN_PHYS(bmap_size);
524
525 if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
526 start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
527
528 if (start + INITRD_SIZE > memory_end) {
529 printk("initrd extends beyond end of memory "
530 "(0x%08lx > 0x%08lx)\n"
531 "disabling initrd\n",
532 start + INITRD_SIZE, memory_end);
533 INITRD_START = INITRD_SIZE = 0;
534 } else {
535 printk("Moving initrd (0x%08lx -> 0x%08lx, "
536 "size: %ld)\n",
537 INITRD_START, start, INITRD_SIZE);
538 memmove((void *) start, (void *) INITRD_START,
539 INITRD_SIZE);
540 INITRD_START = start;
541 }
542 }
543 }
544#endif
545
511 /* 546 /*
512 * Initialize the boot-time allocator (with low memory only): 547 * Initialize the boot-time allocator (with low memory only):
513 */ 548 */
@@ -559,7 +594,7 @@ setup_memory(void)
559 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size); 594 reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
560 595
561#ifdef CONFIG_BLK_DEV_INITRD 596#ifdef CONFIG_BLK_DEV_INITRD
562 if (INITRD_START) { 597 if (INITRD_START && INITRD_SIZE) {
563 if (INITRD_START + INITRD_SIZE <= memory_end) { 598 if (INITRD_START + INITRD_SIZE <= memory_end) {
564 reserve_bootmem(INITRD_START, INITRD_SIZE); 599 reserve_bootmem(INITRD_START, INITRD_SIZE);
565 initrd_start = INITRD_START; 600 initrd_start = INITRD_START;