Commit ead384d9 authored by Huacai Chen's avatar Huacai Chen Committed by Ard Biesheuvel
Browse files

efi/loongarch: Add efistub booting support



This patch adds efistub booting support, which is the standard UEFI boot
protocol for LoongArch to use.

We use generic efistub, which means we can pass boot information (i.e.,
system table, memory map, kernel command line, initrd) via a light FDT
and drop a lot of non-standard code.

We use a flat mapping to map the efi runtime in the kernel's address
space. In efi, VA = PA; in kernel, VA = PA + PAGE_OFFSET. As a result,
flat mapping is not identity mapping, SetVirtualAddressMap() is still
needed for the efi runtime.

Tested-by: default avatarXi Ruoyao <xry111@xry111.site>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
[ardb: change fpic to fpie as suggested by Xi Ruoyao]
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 568035b0
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -317,6 +317,15 @@ config EFI
	  This enables the kernel to use EFI runtime services that are
	  available (such as the EFI variable services).

config EFI_STUB
	bool "EFI boot stub support"
	default y
	depends on EFI
	select EFI_GENERIC_STUB
	help
	  This kernel feature allows the kernel to be loaded directly by
	  EFI firmware without the use of a bootloader.

config SMP
	bool "Multi-Processing support"
	help
+9 −4
Original line number Diff line number Diff line
@@ -7,7 +7,11 @@ boot := arch/loongarch/boot

KBUILD_DEFCONFIG := loongson3_defconfig

KBUILD_IMAGE	= $(boot)/vmlinux
ifndef CONFIG_EFI_STUB
KBUILD_IMAGE	:= $(boot)/vmlinux.elf
else
KBUILD_IMAGE	:= $(boot)/vmlinux.efi
endif

#
# Select the object file format to substitute into the linker script.
@@ -75,6 +79,7 @@ endif
head-y := arch/loongarch/kernel/head.o

libs-y += arch/loongarch/lib/
libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a

ifeq ($(KBUILD_EXTMOD),)
prepare: vdso_prepare
@@ -86,10 +91,10 @@ PHONY += vdso_install
vdso_install:
	$(Q)$(MAKE) $(build)=arch/loongarch/vdso $@

all:	$(KBUILD_IMAGE)
all:	$(notdir $(KBUILD_IMAGE))

$(KBUILD_IMAGE): vmlinux
	$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $@
vmlinux.elf vmlinux.efi: vmlinux
	$(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@

install:
	$(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
+6 −2
Original line number Diff line number Diff line
@@ -8,9 +8,13 @@ drop-sections := .comment .note .options .note.gnu.build-id
strip-flags   := $(addprefix --remove-section=,$(drop-sections)) -S
OBJCOPYFLAGS_vmlinux.efi := -O binary $(strip-flags)

targets := vmlinux
quiet_cmd_strip = STRIP	  $@
      cmd_strip = $(STRIP) -s -o $@ $<

$(obj)/vmlinux: vmlinux FORCE
targets := vmlinux.elf
$(obj)/vmlinux.elf: vmlinux FORCE
	$(call if_changed,strip)

targets += vmlinux.efi
$(obj)/vmlinux.efi: vmlinux FORCE
	$(call if_changed,objcopy)
+9 −2
Original line number Diff line number Diff line
@@ -17,9 +17,16 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt);
#define arch_efi_call_virt_teardown()

#define EFI_ALLOC_ALIGN		SZ_64K
#define EFI_RT_VIRTUAL_OFFSET	CSR_DMW0_BASE

struct screen_info *alloc_screen_info(void);
void free_screen_info(struct screen_info *si);
static inline struct screen_info *alloc_screen_info(void)
{
	return &screen_info;
}

static inline void free_screen_info(struct screen_info *si)
{
}

static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
{
+99 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
 */

#include <linux/pe.h>
#include <linux/sizes.h>

	.macro	__EFI_PE_HEADER
	.long	PE_MAGIC
.Lcoff_header:
	.short	IMAGE_FILE_MACHINE_LOONGARCH64		/* Machine */
	.short	.Lsection_count				/* NumberOfSections */
	.long	0 					/* TimeDateStamp */
	.long	0					/* PointerToSymbolTable */
	.long	0					/* NumberOfSymbols */
	.short	.Lsection_table - .Loptional_header	/* SizeOfOptionalHeader */
	.short	IMAGE_FILE_DEBUG_STRIPPED | \
		IMAGE_FILE_EXECUTABLE_IMAGE | \
		IMAGE_FILE_LINE_NUMS_STRIPPED		/* Characteristics */

.Loptional_header:
	.short	PE_OPT_MAGIC_PE32PLUS			/* PE32+ format */
	.byte	0x02					/* MajorLinkerVersion */
	.byte	0x14					/* MinorLinkerVersion */
	.long	__inittext_end - .Lefi_header_end	/* SizeOfCode */
	.long	_end - __initdata_begin			/* SizeOfInitializedData */
	.long	0					/* SizeOfUninitializedData */
	.long	__efistub_efi_pe_entry - _head		/* AddressOfEntryPoint */
	.long	.Lefi_header_end - _head		/* BaseOfCode */

.Lextra_header_fields:
	.quad	0					/* ImageBase */
	.long	PECOFF_SEGMENT_ALIGN			/* SectionAlignment */
	.long	PECOFF_FILE_ALIGN			/* FileAlignment */
	.short	0					/* MajorOperatingSystemVersion */
	.short	0					/* MinorOperatingSystemVersion */
	.short	LINUX_EFISTUB_MAJOR_VERSION		/* MajorImageVersion */
	.short	LINUX_EFISTUB_MINOR_VERSION		/* MinorImageVersion */
	.short	0					/* MajorSubsystemVersion */
	.short	0					/* MinorSubsystemVersion */
	.long	0					/* Win32VersionValue */

	.long	_end - _head				/* SizeOfImage */

	/* Everything before the kernel image is considered part of the header */
	.long	.Lefi_header_end - _head		/* SizeOfHeaders */
	.long	0					/* CheckSum */
	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION		/* Subsystem */
	.short	0					/* DllCharacteristics */
	.quad	0					/* SizeOfStackReserve */
	.quad	0					/* SizeOfStackCommit */
	.quad	0					/* SizeOfHeapReserve */
	.quad	0					/* SizeOfHeapCommit */
	.long	0					/* LoaderFlags */
	.long	(.Lsection_table - .) / 8		/* NumberOfRvaAndSizes */

	.quad	0					/* ExportTable */
	.quad	0					/* ImportTable */
	.quad	0					/* ResourceTable */
	.quad	0					/* ExceptionTable */
	.quad	0					/* CertificationTable */
	.quad	0					/* BaseRelocationTable */

	/* Section table */
.Lsection_table:
	.ascii	".text\0\0\0"
	.long	__inittext_end - .Lefi_header_end	/* VirtualSize */
	.long	.Lefi_header_end - _head		/* VirtualAddress */
	.long	__inittext_end - .Lefi_header_end	/* SizeOfRawData */
	.long	.Lefi_header_end - _head		/* PointerToRawData */

	.long	0					/* PointerToRelocations */
	.long	0					/* PointerToLineNumbers */
	.short	0					/* NumberOfRelocations */
	.short	0					/* NumberOfLineNumbers */
	.long	IMAGE_SCN_CNT_CODE | \
		IMAGE_SCN_MEM_READ | \
		IMAGE_SCN_MEM_EXECUTE			/* Characteristics */

	.ascii	".data\0\0\0"
	.long	_end - __initdata_begin			/* VirtualSize */
	.long	__initdata_begin - _head		/* VirtualAddress */
	.long	_edata - __initdata_begin		/* SizeOfRawData */
	.long	__initdata_begin - _head		/* PointerToRawData */

	.long	0					/* PointerToRelocations */
	.long	0					/* PointerToLineNumbers */
	.short	0					/* NumberOfRelocations */
	.short	0					/* NumberOfLineNumbers */
	.long	IMAGE_SCN_CNT_INITIALIZED_DATA | \
		IMAGE_SCN_MEM_READ | \
		IMAGE_SCN_MEM_WRITE			/* Characteristics */

	.set	.Lsection_count, (. - .Lsection_table) / 40

	.balign	0x10000					/* PECOFF_SEGMENT_ALIGN */
.Lefi_header_end:
	.endm
Loading