2018-07-19 18:11:28 +07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#include <linux/string.h>
|
2018-04-11 16:56:55 +07:00
|
|
|
#include <asm/setup.h>
|
2018-07-25 20:01:11 +07:00
|
|
|
#include <asm/sclp.h>
|
2019-04-02 00:11:03 +07:00
|
|
|
#include <asm/uv.h>
|
2018-07-19 18:11:28 +07:00
|
|
|
#include "compressed/decompressor.h"
|
|
|
|
#include "boot.h"
|
|
|
|
|
2018-04-10 19:14:02 +07:00
|
|
|
extern char __boot_data_start[], __boot_data_end[];
|
2019-04-02 00:10:45 +07:00
|
|
|
extern char __boot_data_preserved_start[], __boot_data_preserved_end[];
|
2018-04-10 19:14:02 +07:00
|
|
|
|
2018-07-25 20:01:11 +07:00
|
|
|
void error(char *x)
|
|
|
|
{
|
|
|
|
sclp_early_printk("\n\n");
|
|
|
|
sclp_early_printk(x);
|
|
|
|
sclp_early_printk("\n\n -- System halted");
|
|
|
|
|
|
|
|
disabled_wait(0xdeadbeef);
|
|
|
|
}
|
|
|
|
|
2018-04-11 16:56:55 +07:00
|
|
|
#ifdef CONFIG_KERNEL_UNCOMPRESSED
|
|
|
|
unsigned long mem_safe_offset(void)
|
|
|
|
{
|
|
|
|
return vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void rescue_initrd(void)
|
|
|
|
{
|
|
|
|
unsigned long min_initrd_addr;
|
|
|
|
|
|
|
|
if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
|
|
|
|
return;
|
|
|
|
if (!INITRD_START || !INITRD_SIZE)
|
|
|
|
return;
|
|
|
|
min_initrd_addr = mem_safe_offset();
|
|
|
|
if (min_initrd_addr <= INITRD_START)
|
|
|
|
return;
|
|
|
|
memmove((void *)min_initrd_addr, (void *)INITRD_START, INITRD_SIZE);
|
|
|
|
INITRD_START = min_initrd_addr;
|
|
|
|
}
|
|
|
|
|
2018-04-10 19:14:02 +07:00
|
|
|
static void copy_bootdata(void)
|
|
|
|
{
|
|
|
|
if (__boot_data_end - __boot_data_start != vmlinux.bootdata_size)
|
|
|
|
error(".boot.data section size mismatch");
|
|
|
|
memcpy((void *)vmlinux.bootdata_off, __boot_data_start, vmlinux.bootdata_size);
|
2019-04-02 00:10:45 +07:00
|
|
|
if (__boot_data_preserved_end - __boot_data_preserved_start != vmlinux.bootdata_preserved_size)
|
|
|
|
error(".boot.preserved.data section size mismatch");
|
|
|
|
memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
|
2018-04-10 19:14:02 +07:00
|
|
|
}
|
|
|
|
|
2018-07-19 18:11:28 +07:00
|
|
|
void startup_kernel(void)
|
|
|
|
{
|
2018-07-19 21:51:25 +07:00
|
|
|
void *img;
|
2018-07-19 18:11:28 +07:00
|
|
|
|
2019-04-02 00:11:03 +07:00
|
|
|
uv_query_info();
|
2018-04-11 16:56:55 +07:00
|
|
|
rescue_initrd();
|
2018-05-23 16:07:13 +07:00
|
|
|
sclp_early_read_info();
|
2018-05-15 18:28:53 +07:00
|
|
|
store_ipl_parmblock();
|
|
|
|
setup_boot_command_line();
|
2019-02-27 22:52:42 +07:00
|
|
|
parse_boot_command_line();
|
2018-05-15 18:28:53 +07:00
|
|
|
setup_memory_end();
|
2018-04-11 16:56:55 +07:00
|
|
|
detect_memory();
|
2018-07-19 18:11:28 +07:00
|
|
|
if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
|
2018-07-19 21:51:25 +07:00
|
|
|
img = decompress_kernel();
|
|
|
|
memmove((void *)vmlinux.default_lma, img, vmlinux.image_size);
|
2018-07-19 18:11:28 +07:00
|
|
|
}
|
2018-04-10 19:14:02 +07:00
|
|
|
copy_bootdata();
|
2018-07-19 21:51:25 +07:00
|
|
|
vmlinux.entry();
|
2018-07-19 18:11:28 +07:00
|
|
|
}
|