Commit d1b52a43 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Martin Schwidefsky

s390: introduce .boot.data section

Introduce .boot.data section which is "shared" between the decompressor
code and the decompressed kernel. The decompressor will store values in
it, and copy over to the decompressed image before starting it. This
method allows to avoid using pre-defined addresses and other hacks to
pass values between those boot phases.

.boot.data section is a part of init data, and will be freed after kernel
initialization is complete.

For uncompressed kernel image, .boot.data section is basically the same
as .init.data
Reviewed-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 7516fc11
...@@ -15,6 +15,8 @@ struct vmlinux_info { ...@@ -15,6 +15,8 @@ struct vmlinux_info {
void (*entry)(void); void (*entry)(void);
unsigned long image_size; /* does not include .bss */ unsigned long image_size; /* does not include .bss */
unsigned long bss_size; /* uncompressed image .bss size */ unsigned long bss_size; /* uncompressed image .bss size */
unsigned long bootdata_off;
unsigned long bootdata_size;
}; };
extern char _vmlinux_info[]; extern char _vmlinux_info[];
......
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#include <asm-generic/vmlinux.lds.h> #include <asm-generic/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit) OUTPUT_ARCH(s390:64-bit)
...@@ -32,6 +33,8 @@ SECTIONS ...@@ -32,6 +33,8 @@ SECTIONS
*(.data.*) *(.data.*)
_edata = . ; _edata = . ;
} }
BOOT_DATA
/* /*
* uncompressed image info used by the decompressor it should match * uncompressed image info used by the decompressor it should match
* struct vmlinux_info. It comes from .vmlinux.info section of * struct vmlinux_info. It comes from .vmlinux.info section of
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "compressed/decompressor.h" #include "compressed/decompressor.h"
#include "boot.h" #include "boot.h"
extern char __boot_data_start[], __boot_data_end[];
void error(char *x) void error(char *x)
{ {
sclp_early_printk("\n\n"); sclp_early_printk("\n\n");
...@@ -36,6 +38,13 @@ static void rescue_initrd(void) ...@@ -36,6 +38,13 @@ static void rescue_initrd(void)
INITRD_START = min_initrd_addr; INITRD_START = min_initrd_addr;
} }
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);
}
void startup_kernel(void) void startup_kernel(void)
{ {
void *img; void *img;
...@@ -45,5 +54,6 @@ void startup_kernel(void) ...@@ -45,5 +54,6 @@ void startup_kernel(void)
img = decompress_kernel(); img = decompress_kernel();
memmove((void *)vmlinux.default_lma, img, vmlinux.image_size); memmove((void *)vmlinux.default_lma, img, vmlinux.image_size);
} }
copy_bootdata();
vmlinux.entry(); vmlinux.entry();
} }
...@@ -4,4 +4,16 @@ ...@@ -4,4 +4,16 @@
#include <asm-generic/sections.h> #include <asm-generic/sections.h>
/*
* .boot.data section contains variables "shared" between the decompressor and
* the decompressed kernel. The decompressor will store values in them, and
* copy over to the decompressed image before starting it.
*
* Each variable end up in its own intermediate section .boot.data.<var name>,
* those sections are later sorted by alignment + name and merged together into
* final .boot.data section, which should be identical in the decompressor and
* the decompressed kernel (that is checked during the build).
*/
#define __bootdata(var) __section(.boot.data.var) var
#endif #endif
/* SPDX-License-Identifier: GPL-2.0 */
#include <asm/page.h>
/*
* .boot.data section is shared between the decompressor code and the
* decompressed kernel. The decompressor will store values in it, and copy
* over to the decompressed image before starting it.
*
* .boot.data variables are kept in separate .boot.data.<var name> sections,
* which are sorted by alignment first, then by name before being merged
* into single .boot.data section. This way big holes cased by page aligned
* structs are avoided and linker produces consistent result.
*/
#define BOOT_DATA \
. = ALIGN(PAGE_SIZE); \
.boot.data : { \
__boot_data_start = .; \
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.boot.data*))) \
__boot_data_end = .; \
}
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#define RO_AFTER_INIT_DATA #define RO_AFTER_INIT_DATA
#include <asm-generic/vmlinux.lds.h> #include <asm-generic/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit) OUTPUT_ARCH(s390:64-bit)
...@@ -134,6 +135,8 @@ SECTIONS ...@@ -134,6 +135,8 @@ SECTIONS
__nospec_return_end = . ; __nospec_return_end = . ;
} }
BOOT_DATA
/* early.c uses stsi, which requires page aligned data. */ /* early.c uses stsi, which requires page aligned data. */
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
INIT_DATA_SECTION(0x100) INIT_DATA_SECTION(0x100)
...@@ -155,6 +158,8 @@ SECTIONS ...@@ -155,6 +158,8 @@ SECTIONS
QUAD(startup_continue) /* entry */ QUAD(startup_continue) /* entry */
QUAD(__bss_start - _stext) /* image_size */ QUAD(__bss_start - _stext) /* image_size */
QUAD(__bss_stop - __bss_start) /* bss_size */ QUAD(__bss_stop - __bss_start) /* bss_size */
QUAD(__boot_data_start) /* bootdata_off */
QUAD(__boot_data_end - __boot_data_start) /* bootdata_size */
} }
/* Debugging sections. */ /* Debugging sections. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment