diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-09-20 09:58:41 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-20 09:58:41 -0400 |
commit | 65912a84c0f33304fa5ea004c7b6ee58d5f5572e (patch) | |
tree | a9a684ed713f09cd47d6bd1cfe6872cf757feb58 | |
parent | 4ba069b802c29eee066385f9826e2d83716626b4 (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>
-rw-r--r-- | arch/s390/kernel/head.S | 10 | ||||
-rw-r--r-- | arch/s390/kernel/head31.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 41 | ||||
-rw-r--r-- | include/asm-s390/setup.h | 2 |
5 files changed, 48 insertions, 13 deletions
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index adad8863ee2f..a6e9bdb53591 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -272,7 +272,7 @@ iplstart: | |||
272 | # load parameter file from ipl device | 272 | # load parameter file from ipl device |
273 | # | 273 | # |
274 | .Lagain1: | 274 | .Lagain1: |
275 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp | 275 | l %r2,.Linitrd # ramdisk loc. is temp |
276 | bas %r14,.Lloader # load parameter file | 276 | bas %r14,.Lloader # load parameter file |
277 | ltr %r2,%r2 # got anything ? | 277 | ltr %r2,%r2 # got anything ? |
278 | bz .Lnopf | 278 | bz .Lnopf |
@@ -280,7 +280,7 @@ iplstart: | |||
280 | bnh .Lnotrunc | 280 | bnh .Lnotrunc |
281 | la %r2,895 | 281 | la %r2,895 |
282 | .Lnotrunc: | 282 | .Lnotrunc: |
283 | l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) | 283 | l %r4,.Linitrd |
284 | clc 0(3,%r4),.L_hdr # if it is HDRx | 284 | clc 0(3,%r4),.L_hdr # if it is HDRx |
285 | bz .Lagain1 # skip dataset header | 285 | bz .Lagain1 # skip dataset header |
286 | clc 0(3,%r4),.L_eof # if it is EOFx | 286 | clc 0(3,%r4),.L_eof # if it is EOFx |
@@ -323,14 +323,15 @@ iplstart: | |||
323 | # load ramdisk from ipl device | 323 | # load ramdisk from ipl device |
324 | # | 324 | # |
325 | .Lagain2: | 325 | .Lagain2: |
326 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk | 326 | l %r2,.Linitrd # addr of ramdisk |
327 | st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) | ||
327 | bas %r14,.Lloader # load ramdisk | 328 | bas %r14,.Lloader # load ramdisk |
328 | st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk | 329 | st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk |
329 | ltr %r2,%r2 | 330 | ltr %r2,%r2 |
330 | bnz .Lrdcont | 331 | bnz .Lrdcont |
331 | st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found | 332 | st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found |
332 | .Lrdcont: | 333 | .Lrdcont: |
333 | l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) | 334 | l %r2,.Linitrd |
334 | 335 | ||
335 | clc 0(3,%r2),.L_hdr # skip HDRx and EOFx | 336 | clc 0(3,%r2),.L_hdr # skip HDRx and EOFx |
336 | bz .Lagain2 | 337 | bz .Lagain2 |
@@ -379,6 +380,7 @@ iplstart: | |||
379 | l %r1,.Lstartup | 380 | l %r1,.Lstartup |
380 | br %r1 | 381 | br %r1 |
381 | 382 | ||
383 | .Linitrd:.long _end + 0x400000 # default address of initrd | ||
382 | .Lparm: .long PARMAREA | 384 | .Lparm: .long PARMAREA |
383 | .Lstartup: .long startup | 385 | .Lstartup: .long startup |
384 | .Lcvtab:.long _ebcasc # ebcdic to ascii table | 386 | .Lcvtab:.long _ebcasc # ebcdic to ascii table |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index a4dc61f3285e..0e46077d7140 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base | |||
26 | # | 26 | # |
27 | .org PARMAREA | 27 | .org PARMAREA |
28 | .long 0,0 # IPL_DEVICE | 28 | .long 0,0 # IPL_DEVICE |
29 | .long 0,RAMDISK_ORIGIN # INITRD_START | 29 | .long 0,0 # INITRD_START |
30 | .long 0,RAMDISK_SIZE # INITRD_SIZE | 30 | .long 0,0 # INITRD_SIZE |
31 | 31 | ||
32 | .org COMMAND_LINE | 32 | .org COMMAND_LINE |
33 | .byte "root=/dev/ram0 ro" | 33 | .byte "root=/dev/ram0 ro" |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 9d80c5b1ef95..3e0341acd04e 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -26,8 +26,8 @@ startup:basr %r13,0 # get base | |||
26 | # | 26 | # |
27 | .org PARMAREA | 27 | .org PARMAREA |
28 | .quad 0 # IPL_DEVICE | 28 | .quad 0 # IPL_DEVICE |
29 | .quad RAMDISK_ORIGIN # INITRD_START | 29 | .quad 0 # INITRD_START |
30 | .quad RAMDISK_SIZE # INITRD_SIZE | 30 | .quad 0 # INITRD_SIZE |
31 | 31 | ||
32 | .org COMMAND_LINE | 32 | .org COMMAND_LINE |
33 | .byte "root=/dev/ram0 ro" | 33 | .byte "root=/dev/ram0 ro" |
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; |
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index 19e31979309a..02c96d57f0cf 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define PARMAREA 0x10400 | 15 | #define PARMAREA 0x10400 |
16 | #define COMMAND_LINE_SIZE 896 | 16 | #define COMMAND_LINE_SIZE 896 |
17 | #define RAMDISK_ORIGIN 0x800000 | ||
18 | #define RAMDISK_SIZE 0x800000 | ||
19 | #define MEMORY_CHUNKS 16 /* max 0x7fff */ | 17 | #define MEMORY_CHUNKS 16 /* max 0x7fff */ |
20 | #define IPL_PARMBLOCK_ORIGIN 0x2000 | 18 | #define IPL_PARMBLOCK_ORIGIN 0x2000 |
21 | 19 | ||