mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-28 21:45:01 +08:00
29636a5ce8
GRUB currently relies on the magic number in the image header of ARM and arm64 EFI kernel images to decide whether or not the image in question is a bootable kernel. However, the purpose of the magic number is to identify the image as one that implements the bare metal boot protocol, and so GRUB, which only does EFI boot, is limited unnecessarily to booting images that could potentially be booted in a non-EFI manner as well. This is problematic for the new zboot decompressor image format, as it can only boot in EFI mode, and must therefore not use the bare metal boot magic number in its header. For this reason, the strict magic number was dropped from GRUB, to permit essentially any kind of EFI executable to be booted via the 'linux' command, blurring the line between the linux loader and the chainloader. So let's use the same field in the DOS header that RISC-V and arm64 already use for their 'bare metal' magic numbers to store a 'generic Linux kernel' magic number, which can be used to identify bootable kernel images in PE format which don't necessarily implement a bare metal boot protocol in the same binary. Note that, in the context of EFI, the MS-DOS header is only described in terms of the fields that it shares with the hybrid PE/COFF image format, (i.e., the MS-DOS EXE magic number at offset #0 and the PE header offset at byte offset #0x3c). Since we aim for compatibility with EFI only, and not with MS-DOS or MS-Windows, we can use the remaining space in the MS-DOS header however we want. Let's set the generic magic number for x86 images as well: existing bootloaders already have their own methods to identify x86 Linux images that can be booted in a non-EFI manner, and having the magic number in place there will ease any future transitions in loader implementations to merge the x86 and non-x86 EFI boot paths. Note that 32-bit ARM already uses the same location in the header for a different purpose, but the ARM support is already widely implemented and the EFI zboot decompressor is not available on ARM anyway, so we just disregard it here. Acked-by: Leif Lindholm <quic_llindhol@quicinc.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
132 lines
3.0 KiB
ArmAsm
132 lines
3.0 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
|
*/
|
|
#include <linux/init.h>
|
|
#include <linux/threads.h>
|
|
|
|
#include <asm/addrspace.h>
|
|
#include <asm/asm.h>
|
|
#include <asm/asmmacro.h>
|
|
#include <asm/bug.h>
|
|
#include <asm/regdef.h>
|
|
#include <asm/loongarch.h>
|
|
#include <asm/stackframe.h>
|
|
|
|
#ifdef CONFIG_EFI_STUB
|
|
|
|
#include "efi-header.S"
|
|
|
|
__HEAD
|
|
|
|
_head:
|
|
.word MZ_MAGIC /* "MZ", MS-DOS header */
|
|
.org 0x8
|
|
.dword kernel_entry /* Kernel entry point */
|
|
.dword _end - _text /* Kernel image effective size */
|
|
.quad 0 /* Kernel image load offset from start of RAM */
|
|
.org 0x38 /* 0x20 ~ 0x37 reserved */
|
|
.long LINUX_PE_MAGIC
|
|
.long pe_header - _head /* Offset to the PE header */
|
|
|
|
pe_header:
|
|
__EFI_PE_HEADER
|
|
|
|
SYM_DATA(kernel_asize, .long _end - _text);
|
|
SYM_DATA(kernel_fsize, .long _edata - _text);
|
|
SYM_DATA(kernel_offset, .long kernel_offset - _text);
|
|
|
|
#endif
|
|
|
|
__REF
|
|
|
|
.align 12
|
|
|
|
SYM_CODE_START(kernel_entry) # kernel entry point
|
|
|
|
/* Config direct window and set PG */
|
|
li.d t0, CSR_DMW0_INIT # UC, PLV0, 0x8000 xxxx xxxx xxxx
|
|
csrwr t0, LOONGARCH_CSR_DMWIN0
|
|
li.d t0, CSR_DMW1_INIT # CA, PLV0, 0x9000 xxxx xxxx xxxx
|
|
csrwr t0, LOONGARCH_CSR_DMWIN1
|
|
|
|
/* We might not get launched at the address the kernel is linked to,
|
|
so we jump there. */
|
|
la.abs t0, 0f
|
|
jr t0
|
|
0:
|
|
/* Enable PG */
|
|
li.w t0, 0xb0 # PLV=0, IE=0, PG=1
|
|
csrwr t0, LOONGARCH_CSR_CRMD
|
|
li.w t0, 0x04 # PLV=0, PIE=1, PWE=0
|
|
csrwr t0, LOONGARCH_CSR_PRMD
|
|
li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
|
csrwr t0, LOONGARCH_CSR_EUEN
|
|
|
|
la.pcrel t0, __bss_start # clear .bss
|
|
st.d zero, t0, 0
|
|
la.pcrel t1, __bss_stop - LONGSIZE
|
|
1:
|
|
addi.d t0, t0, LONGSIZE
|
|
st.d zero, t0, 0
|
|
bne t0, t1, 1b
|
|
|
|
la.pcrel t0, fw_arg0
|
|
st.d a0, t0, 0 # firmware arguments
|
|
la.pcrel t0, fw_arg1
|
|
st.d a1, t0, 0
|
|
la.pcrel t0, fw_arg2
|
|
st.d a2, t0, 0
|
|
|
|
/* KSave3 used for percpu base, initialized as 0 */
|
|
csrwr zero, PERCPU_BASE_KS
|
|
/* GPR21 used for percpu base (runtime), initialized as 0 */
|
|
move u0, zero
|
|
|
|
la.pcrel tp, init_thread_union
|
|
/* Set the SP after an empty pt_regs. */
|
|
PTR_LI sp, (_THREAD_SIZE - PT_SIZE)
|
|
PTR_ADD sp, sp, tp
|
|
set_saved_sp sp, t0, t1
|
|
|
|
bl start_kernel
|
|
ASM_BUG()
|
|
|
|
SYM_CODE_END(kernel_entry)
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
/*
|
|
* SMP slave cpus entry point. Board specific code for bootstrap calls this
|
|
* function after setting up the stack and tp registers.
|
|
*/
|
|
SYM_CODE_START(smpboot_entry)
|
|
li.d t0, CSR_DMW0_INIT # UC, PLV0
|
|
csrwr t0, LOONGARCH_CSR_DMWIN0
|
|
li.d t0, CSR_DMW1_INIT # CA, PLV0
|
|
csrwr t0, LOONGARCH_CSR_DMWIN1
|
|
|
|
la.abs t0, 0f
|
|
jr t0
|
|
0:
|
|
/* Enable PG */
|
|
li.w t0, 0xb0 # PLV=0, IE=0, PG=1
|
|
csrwr t0, LOONGARCH_CSR_CRMD
|
|
li.w t0, 0x04 # PLV=0, PIE=1, PWE=0
|
|
csrwr t0, LOONGARCH_CSR_PRMD
|
|
li.w t0, 0x00 # FPE=0, SXE=0, ASXE=0, BTE=0
|
|
csrwr t0, LOONGARCH_CSR_EUEN
|
|
|
|
la.abs t0, cpuboot_data
|
|
ld.d sp, t0, CPU_BOOT_STACK
|
|
ld.d tp, t0, CPU_BOOT_TINFO
|
|
|
|
bl start_secondary
|
|
ASM_BUG()
|
|
|
|
SYM_CODE_END(smpboot_entry)
|
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
SYM_ENTRY(kernel_entry_end, SYM_L_GLOBAL, SYM_A_NONE)
|