aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/cio.h2
-rw-r--r--arch/s390/include/asm/ipl.h1
-rw-r--r--arch/s390/include/asm/reset.h20
-rw-r--r--arch/s390/kernel/ipl.c209
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/reipl.S87
-rw-r--r--arch/s390/kernel/relocate_kernel.S54
7 files changed, 16 insertions, 358 deletions
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h
index 80c1179bc666..225667652069 100644
--- a/arch/s390/include/asm/cio.h
+++ b/arch/s390/include/asm/cio.h
@@ -328,8 +328,6 @@ static inline u8 pathmask_to_pos(u8 mask)
void channel_subsystem_reinit(void);
extern void css_schedule_reprobe(void);
-extern void reipl_ccw_dev(struct ccw_dev_id *id);
-
/* Function from drivers/s390/cio/chsc.c */
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
int chsc_sstpi(void *page, void *result, size_t size);
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index eb10df9ef607..b218019ff8f3 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -87,6 +87,7 @@ struct save_area * __init save_area_boot_cpu(void);
void __init save_area_add_regs(struct save_area *, void *regs);
void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
+extern void s390_reset_system(void);
extern void do_reipl(void);
extern void do_halt(void);
extern void do_poff(void);
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h
deleted file mode 100644
index 6450b31ade03..000000000000
--- a/arch/s390/include/asm/reset.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright IBM Corp. 2006
- * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
- */
-
-#ifndef _ASM_S390_RESET_H
-#define _ASM_S390_RESET_H
-
-#include <linux/list.h>
-
-struct reset_call {
- struct list_head list;
- void (*fn)(void);
-};
-
-extern void register_reset_call(struct reset_call *reset);
-extern void unregister_reset_call(struct reset_call *reset);
-extern void s390_reset_system(void);
-#endif /* _ASM_S390_RESET_H */
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 39572ee8e2a7..db86c67f48ec 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -25,7 +25,6 @@
#include <asm/setup.h>
#include <asm/cpcmd.h>
#include <asm/ebcdic.h>
-#include <asm/reset.h>
#include <asm/sclp.h>
#include <asm/checksum.h>
#include <asm/debug.h>
@@ -119,29 +118,20 @@ static char *dump_type_str(enum dump_type type)
}
enum ipl_method {
- REIPL_METHOD_CCW_CIO,
REIPL_METHOD_CCW_DIAG,
- REIPL_METHOD_CCW_VM,
- REIPL_METHOD_FCP_RO_DIAG,
- REIPL_METHOD_FCP_RW_DIAG,
- REIPL_METHOD_FCP_RO_VM,
+ REIPL_METHOD_FCP_DIAG,
REIPL_METHOD_FCP_DUMP,
- REIPL_METHOD_NSS,
REIPL_METHOD_NSS_DIAG,
REIPL_METHOD_DEFAULT,
};
enum dump_method {
DUMP_METHOD_NONE,
- DUMP_METHOD_CCW_CIO,
DUMP_METHOD_CCW_DIAG,
- DUMP_METHOD_CCW_VM,
DUMP_METHOD_FCP_DIAG,
};
static int ipl_block_valid;
-static int diag308_set_works;
-
static struct ipl_parameter_block ipl_block;
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
@@ -256,14 +246,6 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
sys_##_prefix##_##_name##_show, \
sys_##_prefix##_##_name##_store)
-static void make_attrs_ro(struct attribute **attrs)
-{
- while (*attrs) {
- (*attrs)->mode = S_IRUGO;
- attrs++;
- }
-}
-
/*
* ipl section
*/
@@ -541,10 +523,6 @@ static void __ipl_run(void *unused)
{
__bpon();
diag308(DIAG308_LOAD_CLEAR, NULL);
- if (MACHINE_IS_VM)
- __cpcmd("IPL", NULL, 0, NULL);
- else if (ipl_info.type == IPL_TYPE_CCW)
- reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
}
static void ipl_run(struct shutdown_trigger *trigger)
@@ -951,31 +929,18 @@ static int reipl_set_type(enum ipl_type type)
switch(type) {
case IPL_TYPE_CCW:
- if (diag308_set_works)
- reipl_method = REIPL_METHOD_CCW_DIAG;
- else if (MACHINE_IS_VM)
- reipl_method = REIPL_METHOD_CCW_VM;
- else
- reipl_method = REIPL_METHOD_CCW_CIO;
+ reipl_method = REIPL_METHOD_CCW_DIAG;
set_reipl_block_actual(reipl_block_ccw);
break;
case IPL_TYPE_FCP:
- if (diag308_set_works)
- reipl_method = REIPL_METHOD_FCP_RW_DIAG;
- else if (MACHINE_IS_VM)
- reipl_method = REIPL_METHOD_FCP_RO_VM;
- else
- reipl_method = REIPL_METHOD_FCP_RO_DIAG;
+ reipl_method = REIPL_METHOD_FCP_DIAG;
set_reipl_block_actual(reipl_block_fcp);
break;
case IPL_TYPE_FCP_DUMP:
reipl_method = REIPL_METHOD_FCP_DUMP;
break;
case IPL_TYPE_NSS:
- if (diag308_set_works)
- reipl_method = REIPL_METHOD_NSS_DIAG;
- else
- reipl_method = REIPL_METHOD_NSS;
+ reipl_method = REIPL_METHOD_NSS_DIAG;
set_reipl_block_actual(reipl_block_nss);
break;
case IPL_TYPE_UNKNOWN:
@@ -1015,74 +980,22 @@ static struct kobj_attribute reipl_type_attr =
static struct kset *reipl_kset;
static struct kset *reipl_fcp_kset;
-static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
- const enum ipl_method m)
-{
- char loadparm[LOADPARM_LEN + 1] = {};
- char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
- char nss_name[NSS_NAME_SIZE + 1] = {};
- size_t pos = 0;
-
- reipl_get_ascii_loadparm(loadparm, ipb);
- reipl_get_ascii_nss_name(nss_name, ipb);
- reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
-
- switch (m) {
- case REIPL_METHOD_CCW_VM:
- pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno);
- break;
- case REIPL_METHOD_NSS:
- pos = sprintf(dst, "IPL %s", nss_name);
- break;
- default:
- break;
- }
- if (strlen(loadparm) > 0)
- pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm);
- if (strlen(vmparm) > 0)
- sprintf(dst + pos, " PARM %s", vmparm);
-}
-
static void __reipl_run(void *unused)
{
- struct ccw_dev_id devid;
- static char buf[128];
-
switch (reipl_method) {
- case REIPL_METHOD_CCW_CIO:
- devid.ssid = reipl_block_ccw->ipl_info.ccw.ssid;
- devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
- reipl_ccw_dev(&devid);
- break;
- case REIPL_METHOD_CCW_VM:
- get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM);
- __cpcmd(buf, NULL, 0, NULL);
- break;
case REIPL_METHOD_CCW_DIAG:
diag308(DIAG308_SET, reipl_block_ccw);
diag308(DIAG308_LOAD_CLEAR, NULL);
break;
- case REIPL_METHOD_FCP_RW_DIAG:
+ case REIPL_METHOD_FCP_DIAG:
diag308(DIAG308_SET, reipl_block_fcp);
diag308(DIAG308_LOAD_CLEAR, NULL);
break;
- case REIPL_METHOD_FCP_RO_DIAG:
- diag308(DIAG308_LOAD_CLEAR, NULL);
- break;
- case REIPL_METHOD_FCP_RO_VM:
- __cpcmd("IPL", NULL, 0, NULL);
- break;
case REIPL_METHOD_NSS_DIAG:
diag308(DIAG308_SET, reipl_block_nss);
diag308(DIAG308_LOAD_CLEAR, NULL);
break;
- case REIPL_METHOD_NSS:
- get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS);
- __cpcmd(buf, NULL, 0, NULL);
- break;
case REIPL_METHOD_DEFAULT:
- if (MACHINE_IS_VM)
- __cpcmd("IPL", NULL, 0, NULL);
diag308(DIAG308_LOAD_CLEAR, NULL);
break;
case REIPL_METHOD_FCP_DUMP:
@@ -1138,9 +1051,6 @@ static int __init reipl_nss_init(void)
if (!reipl_block_nss)
return -ENOMEM;
- if (!diag308_set_works)
- sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO;
-
rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
if (rc)
return rc;
@@ -1158,17 +1068,9 @@ static int __init reipl_ccw_init(void)
if (!reipl_block_ccw)
return -ENOMEM;
- if (MACHINE_IS_VM) {
- if (!diag308_set_works)
- sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO;
- rc = sysfs_create_group(&reipl_kset->kobj,
- &reipl_ccw_attr_group_vm);
- } else {
- if(!diag308_set_works)
- sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
- rc = sysfs_create_group(&reipl_kset->kobj,
- &reipl_ccw_attr_group_lpar);
- }
+ rc = sysfs_create_group(&reipl_kset->kobj,
+ MACHINE_IS_VM ? &reipl_ccw_attr_group_vm
+ : &reipl_ccw_attr_group_lpar);
if (rc)
return rc;
@@ -1187,14 +1089,6 @@ static int __init reipl_fcp_init(void)
{
int rc;
- if (!diag308_set_works) {
- if (ipl_info.type == IPL_TYPE_FCP) {
- make_attrs_ro(reipl_fcp_attrs);
- sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO;
- } else
- return 0;
- }
-
reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
if (!reipl_block_fcp)
return -ENOMEM;
@@ -1339,12 +1233,7 @@ static int dump_set_type(enum dump_type type)
return -EINVAL;
switch (type) {
case DUMP_TYPE_CCW:
- if (diag308_set_works)
- dump_method = DUMP_METHOD_CCW_DIAG;
- else if (MACHINE_IS_VM)
- dump_method = DUMP_METHOD_CCW_VM;
- else
- dump_method = DUMP_METHOD_CCW_CIO;
+ dump_method = DUMP_METHOD_CCW_DIAG;
break;
case DUMP_TYPE_FCP:
dump_method = DUMP_METHOD_FCP_DIAG;
@@ -1394,21 +1283,7 @@ static void diag308_dump(void *dump_block)
static void __dump_run(void *unused)
{
- struct ccw_dev_id devid;
- static char buf[100];
-
switch (dump_method) {
- case DUMP_METHOD_CCW_CIO:
- devid.ssid = dump_block_ccw->ipl_info.ccw.ssid;
- devid.devno = dump_block_ccw->ipl_info.ccw.devno;
- reipl_ccw_dev(&devid);
- break;
- case DUMP_METHOD_CCW_VM:
- sprintf(buf, "STORE STATUS");
- __cpcmd(buf, NULL, 0, NULL);
- sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
- __cpcmd(buf, NULL, 0, NULL);
- break;
case DUMP_METHOD_CCW_DIAG:
diag308_dump(dump_block_ccw);
break;
@@ -1454,8 +1329,6 @@ static int __init dump_fcp_init(void)
if (!sclp_ipl_info.has_dump)
return 0; /* LDIPL DUMP is not installed */
- if (!diag308_set_works)
- return 0;
dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
if (!dump_block_fcp)
return -ENOMEM;
@@ -1513,18 +1386,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
dump_run(trigger);
}
-static int __init dump_reipl_init(void)
-{
- if (!diag308_set_works)
- return -EOPNOTSUPP;
- else
- return 0;
-}
-
static struct shutdown_action __refdata dump_reipl_action = {
.name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
.fn = dump_reipl_run,
- .init = dump_reipl_init,
};
/*
@@ -1944,67 +1808,16 @@ void __init ipl_store_parameters(void)
int rc;
rc = diag308(DIAG308_STORE, &ipl_block);
- if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
- diag308_set_works = 1;
if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
ipl_block_valid = 1;
}
-static LIST_HEAD(rcall);
-static DEFINE_MUTEX(rcall_mutex);
-
-void register_reset_call(struct reset_call *reset)
-{
- mutex_lock(&rcall_mutex);
- list_add(&reset->list, &rcall);
- mutex_unlock(&rcall_mutex);
-}
-EXPORT_SYMBOL_GPL(register_reset_call);
-
-void unregister_reset_call(struct reset_call *reset)
-{
- mutex_lock(&rcall_mutex);
- list_del(&reset->list);
- mutex_unlock(&rcall_mutex);
-}
-EXPORT_SYMBOL_GPL(unregister_reset_call);
-
-static void do_reset_calls(void)
-{
- struct reset_call *reset;
-
- if (diag308_set_works) {
- diag308_reset();
- return;
- }
- list_for_each_entry(reset, &rcall, list)
- reset->fn();
-}
-
void s390_reset_system(void)
{
- struct lowcore *lc;
-
- lc = (struct lowcore *)(unsigned long) store_prefix();
-
- /* Stack for interrupt/machine check handler */
- lc->panic_stack = S390_lowcore.panic_stack;
-
/* Disable prefixing */
set_prefix(0);
/* Disable lowcore protection */
- __ctl_clear_bit(0,28);
-
- /* Set new machine check handler */
- S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
- S390_lowcore.mcck_new_psw.addr =
- (unsigned long) s390_base_mcck_handler;
-
- /* Set new program check handler */
- S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
- S390_lowcore.program_new_psw.addr =
- (unsigned long) s390_base_pgm_handler;
-
- do_reset_calls();
+ __ctl_clear_bit(0, 28);
+ diag308_reset();
}
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index a80050bbe2e4..9adae2a1e1a0 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -20,7 +20,6 @@
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/smp.h>
-#include <asm/reset.h>
#include <asm/ipl.h>
#include <asm/diag.h>
#include <asm/elf.h>
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index a40ebd1d29d0..73cc3750f0d3 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -75,90 +75,3 @@ ENTRY(store_status)
.align 8
.Lclkcmp: .quad 0x0000000000000000
.previous
-
-#
-# do_reipl_asm
-# Parameter: r2 = schid of reipl device
-#
-
-ENTRY(do_reipl_asm)
- basr %r13,0
-.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
-.Lpg1: lgr %r3,%r2
- larl %r2,.Lstatus
- brasl %r14,store_status
-
-.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
- lgr %r1,%r2
- mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
- stsch .Lschib-.Lpg0(%r13)
- oi .Lschib+5-.Lpg0(%r13),0x84
-.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01
- msch .Lschib-.Lpg0(%r13)
- lghi %r0,5
-.Lssch: ssch .Liplorb-.Lpg0(%r13)
- jz .L001
- brct %r0,.Lssch
- bas %r14,.Ldisab-.Lpg0(%r13)
-.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13)
-.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13)
-.Lcont: c %r1,__LC_SUBCHANNEL_ID
- jnz .Ltpi
- clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13)
- jnz .Ltpi
- tsch .Liplirb-.Lpg0(%r13)
- tm .Liplirb+9-.Lpg0(%r13),0xbf
- jz .L002
- bas %r14,.Ldisab-.Lpg0(%r13)
-.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
- jz .L003
- bas %r14,.Ldisab-.Lpg0(%r13)
-.L003: st %r1,__LC_SUBCHANNEL_ID
- lhi %r1,0 # mode 0 = esa
- slr %r0,%r0 # set cpuid to zero
- sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esa mode
- lpsw 0
-.Ldisab: sll %r14,1
- srl %r14,1 # need to kill hi bit to avoid specification exceptions.
- st %r14,.Ldispsw+12-.Lpg0(%r13)
- lpswe .Ldispsw-.Lpg0(%r13)
- .align 8
-.Lall: .quad 0x00000000ff000000
- .align 16
-/*
- * These addresses have to be 31 bit otherwise
- * the sigp will throw a specifcation exception
- * when switching to ESA mode as bit 31 be set
- * in the ESA psw.
- * Bit 31 of the addresses has to be 0 for the
- * 31bit lpswe instruction a fact they appear to have
- * omitted from the pop.
- */
-.Lnewpsw: .quad 0x0000000080000000
- .quad .Lpg1
-.Lpcnew: .quad 0x0000000080000000
- .quad .Lecs
-.Lionew: .quad 0x0000000080000000
- .quad .Lcont
-.Lwaitpsw: .quad 0x0202000080000000
- .quad .Ltpi
-.Ldispsw: .quad 0x0002000080000000
- .quad 0x0000000000000000
-.Liplccws: .long 0x02000000,0x60000018
- .long 0x08000008,0x20000001
-.Liplorb: .long 0x0049504c,0x0040ff80
- .long 0x00000000+.Liplccws
-.Lschib: .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
-.Liplirb: .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
- .long 0x00000000,0x00000000
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
index 9c2c96da23d0..c97c2d40fe15 100644
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -29,33 +29,6 @@
ENTRY(relocate_kernel)
basr %r13,0 # base address
.base:
- stctg %c0,%c15,ctlregs-.base(%r13)
- stmg %r0,%r15,gprregs-.base(%r13)
- lghi %r0,3
- sllg %r0,%r0,31
- stg %r0,0x1d0(%r0)
- la %r0,.back_pgm-.base(%r13)
- stg %r0,0x1d8(%r0)
- la %r1,load_psw-.base(%r13)
- mvc 0(8,%r0),0(%r1)
- la %r0,.back-.base(%r13)
- st %r0,4(%r0)
- oi 4(%r0),0x80
- lghi %r0,0
- diag %r0,%r0,0x308
- .back:
- lhi %r1,1 # mode 1 = esame
- sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode
- sam64 # switch to 64 bit addressing mode
- basr %r13,0
- .back_base:
- oi have_diag308-.back_base(%r13),0x01
- lctlg %c0,%c15,ctlregs-.back_base(%r13)
- lmg %r0,%r15,gprregs-.back_base(%r13)
- j .top
- .back_pgm:
- lmg %r0,%r15,gprregs-.base(%r13)
- .top:
lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7
lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9
lg %r5,0(%r2) # read another word for indirection page
@@ -64,55 +37,36 @@ ENTRY(relocate_kernel)
je .indir_check # NO, goto "indir_check"
lgr %r6,%r5 # r6 = r5
nill %r6,0xf000 # mask it out and...
- j .top # ...next iteration
+ j .base # ...next iteration
.indir_check:
tml %r5,0x2 # is it a indirection page?
je .done_test # NO, goto "done_test"
nill %r5,0xf000 # YES, mask out,
lgr %r2,%r5 # move it into the right register,
- j .top # and read next...
+ j .base # and read next...
.done_test:
tml %r5,0x4 # is it the done indicator?
je .source_test # NO! Well, then it should be the source indicator...
j .done # ok, lets finish it here...
.source_test:
tml %r5,0x8 # it should be a source indicator...
- je .top # NO, ignore it...
+ je .base # NO, ignore it...
lgr %r8,%r5 # r8 = r5
nill %r8,0xf000 # masking
0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
jo 0b
- j .top
+ j .base
.done:
sgr %r0,%r0 # clear register r0
la %r4,load_psw-.base(%r13) # load psw-address into the register
o %r3,4(%r4) # or load address into psw
st %r3,4(%r4)
mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
- tm have_diag308-.base(%r13),0x01
- jno .no_diag308
diag %r0,%r0,0x308
- .no_diag308:
- sam31 # 31 bit mode
- sr %r1,%r1 # erase register r1
- sr %r2,%r2 # erase register r2
- sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero
- lpsw 0 # hopefully start new kernel...
.align 8
load_psw:
.long 0x00080000,0x80000000
- ctlregs:
- .rept 16
- .quad 0
- .endr
- gprregs:
- .rept 16
- .quad 0
- .endr
- have_diag308:
- .byte 0
- .align 8
relocate_kernel_end:
.align 8
.globl relocate_kernel_len