mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pvimg: Copy genprotimg/boot to rust/pvimg/boot
This change is done in preparation for the Rust port of genprotimg. While at it, format the code using `clang-format`. Reviewed-by: Steffen Eiden <seiden@linux.ibm.com> Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
2ed2c608ab
commit
7d81c1bbd4
@@ -40,7 +40,12 @@ endif #OPENSSL
|
||||
TEST_TARGETS := $(addsuffix _build,$(CARGO_TEST_TARGETS))
|
||||
endif #CARGO
|
||||
|
||||
BUILD_TARGETS += $(PV_BUILD_TARGETS)
|
||||
pvimg-bootloaders:
|
||||
$(MAKE) -C pvimg/boot/
|
||||
.PHONY: pvimg-bootloaders
|
||||
|
||||
BUILD_TARGETS += $(PV_BUILD_TARGETS) pvimg-bootloaders
|
||||
INSTALL_TARGETS += pvimg-bootloaders
|
||||
|
||||
# build release targets by default
|
||||
ifeq ("${D}","0")
|
||||
@@ -78,6 +83,7 @@ all: $(BUILD_TARGETS)
|
||||
install: $(INSTALL_TARGETS)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 pvattest/tools/pvextract-hdr $(DESTDIR)$(USRBINDIR)
|
||||
$(MAKE) -C pvimg/boot install
|
||||
|
||||
print-rust-targets:
|
||||
echo $(BUILD_TARGETS)
|
||||
@@ -86,6 +92,7 @@ clean:
|
||||
ifneq (${HAVE_CARGO},0)
|
||||
$(CARGO_CLEAN) ${ALL_CARGOFLAGS}
|
||||
endif # CARGO
|
||||
$(MAKE) -C pvimg/boot/ clean
|
||||
$(RM) -- .check-dep-pvtools .detect-openssl.dep.c .check-cargo
|
||||
|
||||
rust-test: $(CARGO_TEST_TARGETS)
|
||||
|
||||
4
rust/pvimg/boot/.gitignore
vendored
Normal file
4
rust/pvimg/boot/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.elf
|
||||
*.lds
|
||||
*.bin
|
||||
*.d
|
||||
111
rust/pvimg/boot/Makefile
Normal file
111
rust/pvimg/boot/Makefile
Normal file
@@ -0,0 +1,111 @@
|
||||
# Common definitions
|
||||
include ../../../common.mak
|
||||
|
||||
FILES := stage3a.bin stage3b.bin stage3b_reloc.bin
|
||||
DEBUG_FILES := $(addsuffix .debug,$(FILES))
|
||||
|
||||
ifeq ($(HOST_ARCH),s390x)
|
||||
ZIPL_DIR := $(rootdir)/zipl
|
||||
ZIPL_BOOT_DIR := $(ZIPL_DIR)/boot
|
||||
PKGDATADIR := $(TOOLS_DATADIR)/pvimg
|
||||
|
||||
INCLUDE_PATHS := $(ZIPL_BOOT_DIR) $(ZIPL_DIR)/include $(rootdir)/include
|
||||
INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
|
||||
|
||||
ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
|
||||
$(INCLUDE_PARMS) \
|
||||
-DENABLE_SCLP_ASCII=1 \
|
||||
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
|
||||
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
|
||||
-fno-delete-null-pointer-checks -fno-stack-protector \
|
||||
-fexec-charset=IBM1047 -m64 -mpacked-stack \
|
||||
-mstack-size=4096 -mstack-guard=128 -msoft-float \
|
||||
-Wall -Wformat-security -Wextra \
|
||||
-Wno-array-bounds
|
||||
|
||||
ZIPL_SRCS_C := libc.c ebcdic.c ebcdic_conv.c sclp.c
|
||||
ZIPL_SRCS_ASM := entry.S
|
||||
|
||||
ZIPL_OBJS_C := $(ZIPL_SRCS_C:%.c=%.o)
|
||||
ZIPL_OBJS_ASM := $(ZIPL_SRCS_ASM:%.S=%.o)
|
||||
ZIPL_OBJS := $(ZIPL_OBJS_C) $(ZIPL_OBJS_ASM)
|
||||
|
||||
# Prevent make from using some default rules...
|
||||
%: %.S
|
||||
|
||||
%.o: %.S Makefile
|
||||
$(CC) $(ALL_CFLAGS) -c -o $@ $<
|
||||
|
||||
%.o: %.c Makefile
|
||||
$(CC) $(ALL_CFLAGS) -c -o $@ $<
|
||||
|
||||
|
||||
# Dependencies for the .lds generation
|
||||
sources_lds_S = $(wildcard *.lds.S)
|
||||
dependencies_lds_S = $(sources_lds_S:%.lds.S=.%.lds.d)
|
||||
# Include all ".lds.d" dependency files for all make targets except for "clean"
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(dependencies_lds_S)
|
||||
endif
|
||||
|
||||
%.lds: %.lds.S Makefile
|
||||
$(CPP) -Wp,-MD,.$@.d,-MT,$@ $(INCLUDE_PARMS) -P -C -o $@ $<
|
||||
|
||||
# Special rules for zipl object files
|
||||
$(ZIPL_OBJS_C): %.o : $(ZIPL_BOOT_DIR)/%.c
|
||||
$(CC) $(ALL_CFLAGS) -c -o $@ $<
|
||||
|
||||
$(ZIPL_OBJS_ASM): %.o : $(ZIPL_BOOT_DIR)/%.S
|
||||
$(CC) $(ALL_CFLAGS) -c -o $@ $<
|
||||
|
||||
dependencies_zipl_c := $(ZIPL_SRCS_C:%.c=.%.o.d)
|
||||
|
||||
$(dependencies_zipl_c): .%.o.d : $(ZIPL_BOOT_DIR)/%.c
|
||||
$(CC_SILENT) -MM $(ALL_CPPFLAGS) $(ALL_CFLAGS) $< > $@
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
-include $(dependencies_zipl_c)
|
||||
endif
|
||||
|
||||
stage3b_reloc.o: stage3b.bin
|
||||
|
||||
stage3a.elf: head.o stage3a_init.o $(ZIPL_OBJS)
|
||||
stage3b.elf: head.o $(ZIPL_OBJS)
|
||||
|
||||
.SECONDARY: $(FILES:.bin=.lds)
|
||||
%.elf: %.lds %.o
|
||||
$(LINK) $(NO_PIE_LDFLAGS) $(NO_WARN_RWX_SEGMENTS_LDFLAGS) -Wl,-T,$< -Wl,--build-id=none -m64 -static -nostdlib $(filter %.o, $^) -o $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin.debug: %.elf
|
||||
$(OBJCOPY) --only-keep-debug $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
@chmod a-x $@
|
||||
|
||||
install: stage3a.bin stage3b_reloc.bin
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(PKGDATADIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3a.bin $(DESTDIR)$(PKGDATADIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 stage3b_reloc.bin $(DESTDIR)$(PKGDATADIR)
|
||||
|
||||
else
|
||||
# Don't generate the dependency files (see `common.mak` for the
|
||||
# `-include $(dependencies_c)` statement).
|
||||
.PHONY: $(dependencies_c)
|
||||
|
||||
$(FILES) $(DEBUG_FILES):
|
||||
echo " SKIP $@ due to HOST_ARCH != s390x"
|
||||
|
||||
install:
|
||||
echo " SKIP Bootloader installation due to HOST_ARCH != s390x"
|
||||
endif
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
all: $(FILES) $(DEBUG_FILES)
|
||||
|
||||
clean:
|
||||
rm -f -- *.o *.elf *.bin *.map .*.d *.lds *.debug
|
||||
|
||||
.PHONY: all clean
|
||||
24
rust/pvimg/boot/common_memory_layout.h
Normal file
24
rust/pvimg/boot/common_memory_layout.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Common memory layout for stage3a and 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.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_MEMORY_LAYOUT_H
|
||||
#define COMMON_MEMORY_LAYOUT_H
|
||||
|
||||
#include "boot/loaders_layout.h"
|
||||
|
||||
#define STACK_ADDRESS STAGE3_STACK_ADDRESS
|
||||
#define STACK_SIZE STAGE3_STACK_SIZE
|
||||
|
||||
#define HEAP_ADDRESS STAGE3_HEAP_ADDRESS
|
||||
#define HEAP_SIZE STAGE3_HEAP_SIZE
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* COMMON_MEMORY_LAYOUT_H */
|
||||
36
rust/pvimg/boot/head.S
Normal file
36
rust/pvimg/boot/head.S
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Entry code for stage 3a and stage 3b boot loader
|
||||
*
|
||||
* 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 "common_memory_layout.h"
|
||||
|
||||
#include "boot/s390.h"
|
||||
#include "boot/sigp.h"
|
||||
|
||||
.section .text.start
|
||||
.globl _start
|
||||
_start:
|
||||
/* Might be called after a diag308 so better set
|
||||
* architecture and addressing mode
|
||||
*/
|
||||
lhi %r1, 1
|
||||
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
|
||||
sam64
|
||||
|
||||
/* Initialize stack */
|
||||
basr %r13, 0
|
||||
.Lbase: llgf %r15, .Lstack - .Lbase(%r13)
|
||||
brasl %r14, initialize
|
||||
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
60
rust/pvimg/boot/stage3a.c
Normal file
60
rust/pvimg/boot/stage3a.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Main program for stage3a 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 "stage3a.h"
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/error.h"
|
||||
#include "boot/s390.h"
|
||||
#include "boot/ipl.h"
|
||||
#include "sclp.h"
|
||||
|
||||
static volatile struct stage3a_args __section(".loader_parms") loader_parms;
|
||||
|
||||
void __noreturn start(void)
|
||||
{
|
||||
int rc;
|
||||
volatile struct stage3a_args *args = &loader_parms;
|
||||
/* calculate the IPIB memory address */
|
||||
struct ipl_parameter_block *ipib = (void *)((uint64_t)args + args->ipib_offs);
|
||||
|
||||
/* Calculate the PV header memory address and set it and its
|
||||
* size in the IPIB. This allows the PV header to be position
|
||||
* independent.
|
||||
*/
|
||||
ipib->pv.pv_hdr_addr = (uint64_t)args + args->hdr_offs;
|
||||
ipib->pv.pv_hdr_size = args->hdr_size;
|
||||
|
||||
/* set up ASCII and line-mode */
|
||||
sclp_setup(SCLP_LINE_ASCII_INIT);
|
||||
|
||||
/* test if Secure Execution Unpack facility is available */
|
||||
stfle(S390_lowcore.stfle_fac_list, ARRAY_SIZE(S390_lowcore.stfle_fac_list));
|
||||
rc = test_facility(UNPACK_FACILITY);
|
||||
if (rc == 0)
|
||||
panic(ENOPV, "Secure unpack facility is not available\n");
|
||||
|
||||
rc = diag308(DIAG308_SET_PV, ipib);
|
||||
if (rc != DIAG308_RC_OK)
|
||||
panic(EPV, "Protected boot setup has failed: 0x%x\n", rc);
|
||||
|
||||
rc = diag308(DIAG308_UNPACK_PV, 0x0);
|
||||
if (rc != DIAG308_RC_OK) {
|
||||
sclp_setup(SCLP_LINE_ASCII_INIT);
|
||||
panic(EPV, "Protected boot has failed: 0x%x\n", rc);
|
||||
}
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
void panic_notify(unsigned long UNUSED(rc))
|
||||
{
|
||||
}
|
||||
33
rust/pvimg/boot/stage3a.h
Normal file
33
rust/pvimg/boot/stage3a.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Main program for stage3a 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.
|
||||
*/
|
||||
|
||||
#ifndef STAGE3A_H
|
||||
#define STAGE3A_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
|
||||
#define STAGE3A_INIT_ENTRY IMAGE_ENTRY
|
||||
#define STAGE3A_ENTRY (STAGE3A_INIT_ENTRY + _AC(0x1000, UL))
|
||||
#define STAGE3A_LOAD_ADDRESS IMAGE_LOAD_ADDRESS
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Must not have any padding */
|
||||
struct stage3a_args {
|
||||
uint64_t hdr_offs;
|
||||
uint64_t hdr_size;
|
||||
uint64_t ipib_offs;
|
||||
};
|
||||
STATIC_ASSERT(sizeof(struct stage3a_args) == 3 * 8)
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* STAGE3A_H */
|
||||
98
rust/pvimg/boot/stage3a.lds.S
Normal file
98
rust/pvimg/boot/stage3a.lds.S
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Memory layout for stage 3a
|
||||
* ==========================
|
||||
*
|
||||
* General memory layout
|
||||
* ---------------------
|
||||
*
|
||||
* 0x00000 - 0x01fff Lowcore
|
||||
* 0x02000 - 0x05fff Memory allocation (heap)
|
||||
* 0x0f000 - 0x0ffff Stack
|
||||
* 0x10000 - 0x10012 Jump to the "actual" stage3a code
|
||||
* 0x11000 - 0x12fff Stage3a code + arguments (offsets and lengths to the
|
||||
* actual data: IPIB and UV header)
|
||||
*/
|
||||
|
||||
#include "stage3a.h"
|
||||
#include "common_memory_layout.h"
|
||||
|
||||
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||
OUTPUT_ARCH(s390:64-bit)
|
||||
|
||||
ENTRY(_init)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = HEAP_ADDRESS;
|
||||
__heap_start = .;
|
||||
.heap : {
|
||||
. = . + HEAP_SIZE;
|
||||
ASSERT(__heap_stop - __heap_start == HEAP_SIZE,
|
||||
"Heap section doesn't conform to the described memory layout");
|
||||
}
|
||||
__heap_stop = .;
|
||||
|
||||
. = STACK_ADDRESS;
|
||||
__stack_start = .;
|
||||
.stack : {
|
||||
. = . + STACK_SIZE;
|
||||
ASSERT(__stack_end - __stack_start == STACK_SIZE,
|
||||
"Stack section doesn't conform to the described memory layout");
|
||||
}
|
||||
__stack_end = .;
|
||||
|
||||
. = STAGE3A_INIT_ENTRY;
|
||||
__text_init_start = .;
|
||||
.text : {
|
||||
*(.text.init)
|
||||
__text_init_stop = ABSOLUTE(.);
|
||||
/* Text size of text_init must be smaller than 'PARMAREA - IMAGE_ENTRY',
|
||||
* otherwise the text data could be overwritten by the original zipl stage3
|
||||
* boot loader */
|
||||
ASSERT(__text_init_stop - __text_init_start < PARMAREA - IMAGE_ENTRY,
|
||||
"Text size must be smaller than 'PARMAREA - IMAGE_ENTRY'");
|
||||
. = 0x1000;
|
||||
ASSERT(ABSOLUTE(.) == STAGE3A_ENTRY,
|
||||
"Text section doesn't conform to the described memory layout");
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
.ex_table ALIGN(16) : {
|
||||
__ex_table_start = .;
|
||||
*(.ex_table)
|
||||
__ex_table_stop = .;
|
||||
}
|
||||
|
||||
.bss ALIGN(16) : {
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
__bss_stop = .;
|
||||
}
|
||||
|
||||
.rodata ALIGN(16) : {
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
.data ALIGN(16) : {
|
||||
*(.data)
|
||||
. = ALIGN(16);
|
||||
/* The IPIB offset and the UV header offset and size will be
|
||||
* saved in 'loader_parms' */
|
||||
__loader_parms_start = .;
|
||||
KEEP(*(.loader_parms));
|
||||
__loader_parms_stop = .;
|
||||
ASSERT(__loader_parms_stop - __loader_parms_start == 3 * 8,
|
||||
"Data size must be equal to 'sizeof(struct stage3a_args)'");
|
||||
ASSERT(ABSOLUTE(.) < 0x13000, "Data section doesn't conform to the described memory layout");
|
||||
}
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
*(.note.package)
|
||||
}
|
||||
}
|
||||
33
rust/pvimg/boot/stage3a_init.S
Normal file
33
rust/pvimg/boot/stage3a_init.S
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Entry code for stage 3a boot loader
|
||||
*
|
||||
* 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 "stage3a.h"
|
||||
#include "boot/sigp.h"
|
||||
|
||||
.section .text.init
|
||||
.globl _init
|
||||
_init:
|
||||
/* set architecture and switch to 64bit */
|
||||
lhi %r1, 1
|
||||
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
|
||||
sam64
|
||||
/* The original stage3 boot loader will try to store the
|
||||
* kernel command line and the address and size of the
|
||||
* ramdisk. Simply ignore this by starting at 0x11000.
|
||||
*/
|
||||
basr %r13, 0
|
||||
.Lbase: llgf %r1, .Lstage3a_entry - .Lbase(%r13)
|
||||
br %r1
|
||||
.Lstage3a_entry: .long STAGE3A_ENTRY
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
90
rust/pvimg/boot/stage3b.c
Normal file
90
rust/pvimg/boot/stage3b.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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/psw.h"
|
||||
#include "boot/error.h"
|
||||
#include "boot/s390.h"
|
||||
#include "boot/linux_layout.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
#include "sclp.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");
|
||||
|
||||
if (cmdline->size > 0) {
|
||||
/* make sure the cmdline is a null-terminated string */
|
||||
if (((char *)cmdline->src)[cmdline->size - 1] != '\0')
|
||||
panic(EINTERNAL, "Command line needs to be null-terminated\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))
|
||||
{
|
||||
}
|
||||
41
rust/pvimg/boot/stage3b.h
Normal file
41
rust/pvimg/boot/stage3b.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef STAGE3B_H
|
||||
#define STAGE3B_H
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "boot/loaders_layout.h"
|
||||
|
||||
#define STAGE3B_ENTRY STAGE3_ENTRY
|
||||
#define STAGE3B_LOAD_ADDRESS STAGE3B_ENTRY
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "boot/psw.h"
|
||||
|
||||
/* Must not have any padding included */
|
||||
struct memblob {
|
||||
uint64_t src;
|
||||
uint64_t size;
|
||||
};
|
||||
STATIC_ASSERT(sizeof(struct memblob) == 2 * 8)
|
||||
|
||||
/* Must not have any padding included */
|
||||
struct stage3b_args {
|
||||
struct memblob kernel;
|
||||
struct memblob cmdline;
|
||||
struct memblob initrd;
|
||||
struct psw_t psw;
|
||||
};
|
||||
STATIC_ASSERT(sizeof(struct stage3b_args) == 3 * sizeof(struct memblob) + 16)
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* STAGE3B_H */
|
||||
84
rust/pvimg/boot/stage3b.lds.S
Normal file
84
rust/pvimg/boot/stage3b.lds.S
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Memory layout for stage 3b
|
||||
* ==========================
|
||||
*
|
||||
* General memory layout
|
||||
* ---------------------
|
||||
*
|
||||
* 0x00000 - 0x01fff Lowcore
|
||||
* 0x02000 - 0x05fff Memory allocation (heap)
|
||||
* 0x0a000 - 0x0efff Stage3b code
|
||||
* 0x0f000 - 0x0ffff Stack
|
||||
*/
|
||||
|
||||
#include "stage3b.h"
|
||||
#include "common_memory_layout.h"
|
||||
|
||||
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||
OUTPUT_ARCH(s390:64-bit)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = HEAP_ADDRESS;
|
||||
__heap_start = .;
|
||||
.heap : {
|
||||
. = . + HEAP_SIZE;
|
||||
ASSERT(__heap_stop - __heap_start == HEAP_SIZE,
|
||||
"Heap section doesn't conform to the described memory layout");
|
||||
}
|
||||
__heap_stop = .;
|
||||
|
||||
. = STAGE3B_ENTRY;
|
||||
.text : {
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
.ex_table ALIGN(16) : {
|
||||
__ex_table_start = .;
|
||||
*(.ex_table)
|
||||
__ex_table_stop = .;
|
||||
}
|
||||
|
||||
.bss ALIGN(16) : {
|
||||
__bss_start = .;
|
||||
*(.bss)
|
||||
__bss_stop = .;
|
||||
}
|
||||
|
||||
.rodata ALIGN(16) : {
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
.data ALIGN(16) : {
|
||||
*(.data)
|
||||
. = ALIGN(16);
|
||||
__loader_parms_start = .;
|
||||
KEEP(*(.loader_parms));
|
||||
__loader_parms_end = .;
|
||||
ASSERT(__loader_parms_end - __loader_parms_start == 3 * 16 + 16,
|
||||
"Data size must be equal to 'sizeof(struct stage3b_args)'");
|
||||
}
|
||||
|
||||
. = STACK_ADDRESS;
|
||||
__stack_start = .;
|
||||
.stack : {
|
||||
. = . + STACK_SIZE;
|
||||
ASSERT(__stack_end - __stack_start == STACK_SIZE,
|
||||
"Stack section doesn't conform to the described memory layout");
|
||||
}
|
||||
__stack_end = .;
|
||||
|
||||
ASSERT(. <= IMAGE_ENTRY, "stage3b size must be smaller than 0x10000 bytes")
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
*(.note.package)
|
||||
}
|
||||
}
|
||||
60
rust/pvimg/boot/stage3b_reloc.S
Normal file
60
rust/pvimg/boot/stage3b_reloc.S
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Relocator code for stage 3b boot loader
|
||||
*
|
||||
* 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 "stage3b.h"
|
||||
#include "boot/sigp.h"
|
||||
|
||||
.macro MEMCPY dst,src,len
|
||||
lgr %r0, \dst
|
||||
lgr %r1, \len
|
||||
lgr %r2, \src
|
||||
lgr %r3, \len
|
||||
|
||||
20: mvcle %r0, %r2, 0
|
||||
jo 20b
|
||||
.endm
|
||||
|
||||
.org 0x0
|
||||
.section .text.start
|
||||
.globl _start
|
||||
_start:
|
||||
/* Might be called after a diag308 so better set
|
||||
* architecture and addressing mode
|
||||
*/
|
||||
lhi %r1, 1
|
||||
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
|
||||
sam64
|
||||
|
||||
/* Location of stage3b in memory */
|
||||
larl %r8, stage3b_start
|
||||
|
||||
/* Destination for stage3b */
|
||||
basr %r13, 0
|
||||
.Lbase: llgf %r9, .Lstage3b_load_address - .Lbase(%r13)
|
||||
|
||||
/* Size of stage3b */
|
||||
lghi %r11, stage3b_end - stage3b_start
|
||||
|
||||
/* Copy the stage3b loader to address STAGE3B_LOAD_ADDRESS */
|
||||
MEMCPY %r9, %r8, %r11
|
||||
|
||||
/* Branch to STAGE3B_ENTRY */
|
||||
llgf %r9, .Lstage3b_entry - .Lbase(%r13)
|
||||
br %r9
|
||||
.Lstage3b_load_address: .long STAGE3B_LOAD_ADDRESS
|
||||
.Lstage3b_entry: .long STAGE3B_ENTRY
|
||||
stage3b_start:
|
||||
.incbin "stage3b.bin"
|
||||
stage3b_end:
|
||||
.previous
|
||||
|
||||
/* The code doesn't require an executable stack */
|
||||
#if defined(__linux__) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
#endif
|
||||
20
rust/pvimg/boot/stage3b_reloc.lds.S
Normal file
20
rust/pvimg/boot/stage3b_reloc.lds.S
Normal file
@@ -0,0 +1,20 @@
|
||||
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
||||
OUTPUT_ARCH(s390:64-bit)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.text.start)
|
||||
*(.text .text.*)
|
||||
}
|
||||
|
||||
/* Sections to be discarded */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame)
|
||||
*(.interp)
|
||||
*(.note.GNU-stack)
|
||||
*(.note.package)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user