[S390] nss,initrd: kernel image and initrd must be in different segments

When IPL'ing from a block device and an NSS should be created we must
make sure that the kernel image and the initrd are in different 1MB
segments. Otherwise creating the NSS will fail.
So we make sure the initrd is 4MB behind the end of the kernel image
like we do already when IPL via the VM reader is performed.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Heiko Carstens 2011-08-24 17:15:09 +02:00 коммит произвёл Martin Schwidefsky
Родитель 14c62e78dc
Коммит 27e7318c3e
1 изменённых файлов: 8 добавлений и 6 удалений

Просмотреть файл

@ -396,17 +396,19 @@ static __init void detect_machine_facilities(void)
static __init void rescue_initrd(void) static __init void rescue_initrd(void)
{ {
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
unsigned long min_initrd_addr = (unsigned long) _end + (4UL << 20);
/* /*
* Move the initrd right behind the bss section in case it starts * Just like in case of IPL from VM reader we make sure there is a
* within the bss section. So we don't overwrite it when the bss * gap of 4MB between end of kernel and start of initrd.
* section gets cleared. * That way we can also be sure that saving an NSS will succeed,
* which however only requires different segments.
*/ */
if (!INITRD_START || !INITRD_SIZE) if (!INITRD_START || !INITRD_SIZE)
return; return;
if (INITRD_START >= (unsigned long) __bss_stop) if (INITRD_START >= min_initrd_addr)
return; return;
memmove(__bss_stop, (void *) INITRD_START, INITRD_SIZE); memmove((void *) min_initrd_addr, (void *) INITRD_START, INITRD_SIZE);
INITRD_START = (unsigned long) __bss_stop; INITRD_START = min_initrd_addr;
#endif #endif
} }