Files
s390-tools/genprotimg/boot/stage3b.c
Marc Hartmayer 7503d88b3b genprotimg/boot: add extended kernel command line support
In the past s390 used a fixed command line length of 896 bytes. This has
changed with newer Linux kernels. There is now a parm area indicating
the maximum command line size. This parm area has always been
initialized to zero, so with old kernels this field would read zero and
we must then assume that only 896 bytes are available.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2022-02-02 11:54:30 +01:00

88 lines
2.1 KiB
C

/*
* Main program for stage3b bootloader
*
* Copyright IBM Corp. 2020
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#include "libc.h"
#include "stage3b.h"
#include "lib/zt_common.h"
#include "boot/s390.h"
#include "boot/linux_layout.h"
#include "boot/loaders_layout.h"
#include "sclp.h"
#include "error.h"
static volatile struct stage3b_args __section(".loader_parms") loader_parms;
static inline void __noreturn load_psw(struct psw_t psw)
{
asm volatile("lpswe %0" : : "Q"(psw) : "cc");
while (1)
;
}
static unsigned long get_kernel_cmdline_size(void)
{
unsigned long size = *(volatile unsigned long *)MAX_COMMAND_LINE_SIZE;
if (size != 0)
return size;
return LEGACY_COMMAND_LINE_SIZE;
}
void __noreturn start(void)
{
volatile struct stage3b_args *args = &loader_parms;
volatile struct memblob *kernel = &args->kernel;
volatile struct memblob *cmdline = &args->cmdline;
volatile struct memblob *initrd = &args->initrd;
struct psw_t psw = args->psw;
/* set up ASCII and line-mode */
sclp_setup(SCLP_LINE_ASCII_INIT);
if (kernel->size < IMAGE_LOAD_ADDRESS)
panic(EINTERNAL, "Invalid kernel\n");
/* move the kernel and cut the kernel header */
memmove((void *)IMAGE_LOAD_ADDRESS,
(void *)(kernel->src + IMAGE_LOAD_ADDRESS),
kernel->size - IMAGE_LOAD_ADDRESS);
if (cmdline->size > get_kernel_cmdline_size())
panic(EINTERNAL, "Command line is too large\n");
/* move the kernel cmdline */
memmove((void *)COMMAND_LINE,
(void *)cmdline->src,
cmdline->size);
/* the initrd does not need to be moved */
if (initrd->size != 0) {
/* copy initrd start address and size into new kernel space */
*(unsigned long long *)INITRD_START = initrd->src;
*(unsigned long long *)INITRD_SIZE = initrd->size;
}
/* disable ASCII and line-mode */
sclp_setup(SCLP_DISABLE);
/* use lpswe instead of diag308 as a I/O subsystem reset is not
* needed as this was already done by the diag308 subcode 10 call
* in stage3a
*/
load_psw(psw);
}
void panic_notify(unsigned long UNUSED(rc))
{
}