# load parameter file from ipl device
#
.Lagain1:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
+ l %r2,.Linitrd # ramdisk loc. is temp
bas %r14,.Lloader # load parameter file
ltr %r2,%r2 # got anything ?
bz .Lnopf
bnh .Lnotrunc
la %r2,895
.Lnotrunc:
- l %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
+ l %r4,.Linitrd
clc 0(3,%r4),.L_hdr # if it is HDRx
bz .Lagain1 # skip dataset header
clc 0(3,%r4),.L_eof # if it is EOFx
# load ramdisk from ipl device
#
.Lagain2:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
+ l %r2,.Linitrd # addr of ramdisk
+ st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
bas %r14,.Lloader # load ramdisk
st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
ltr %r2,%r2
bnz .Lrdcont
st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
.Lrdcont:
- l %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
+ l %r2,.Linitrd
clc 0(3,%r2),.L_hdr # skip HDRx and EOFx
bz .Lagain2
l %r1,.Lstartup
br %r1
+.Linitrd:.long _end + 0x400000 # default address of initrd
.Lparm: .long PARMAREA
.Lstartup: .long startup
.Lcvtab:.long _ebcasc # ebcdic to ascii table
#include <linux/kernel_stat.h>
#include <linux/device.h>
#include <linux/notifier.h>
+#include <linux/pfn.h>
#include <asm/uaccess.h>
#include <asm/system.h>
* partially used pages are not usable - thus
* we are rounding upwards:
*/
- start_pfn = (__pa(&_end) + PAGE_SIZE - 1) >> PAGE_SHIFT;
- end_pfn = max_pfn = memory_end >> PAGE_SHIFT;
+ start_pfn = PFN_UP(__pa(&_end));
+ end_pfn = max_pfn = PFN_DOWN(memory_end);
/* Initialize storage key for kernel pages */
for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
+#ifdef CONFIG_BLK_DEV_INITRD
+ /*
+ * Move the initrd in case the bitmap of the bootmem allocater
+ * would overwrite it.
+ */
+
+ if (INITRD_START && INITRD_SIZE) {
+ unsigned long bmap_size;
+ unsigned long start;
+
+ bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);
+ bmap_size = PFN_PHYS(bmap_size);
+
+ if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
+ start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
+
+ if (start + INITRD_SIZE > memory_end) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\n"
+ "disabling initrd\n",
+ start + INITRD_SIZE, memory_end);
+ INITRD_START = INITRD_SIZE = 0;
+ } else {
+ printk("Moving initrd (0x%08lx -> 0x%08lx, "
+ "size: %ld)\n",
+ INITRD_START, start, INITRD_SIZE);
+ memmove((void *) start, (void *) INITRD_START,
+ INITRD_SIZE);
+ INITRD_START = start;
+ }
+ }
+ }
+#endif
+
/*
* Initialize the boot-time allocator (with low memory only):
*/
reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);
#ifdef CONFIG_BLK_DEV_INITRD
- if (INITRD_START) {
+ if (INITRD_START && INITRD_SIZE) {
if (INITRD_START + INITRD_SIZE <= memory_end) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
initrd_start = INITRD_START;