From: Atish Patra <atish.patra@wdc.com>
To: linux-kernel@vger.kernel.org
Cc: Kate Stewart <kstewart@linuxfoundation.org>,
linux-efi@vger.kernel.org, Ard Biesheuvel <ardb@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Linus Walleij <linus.walleij@linaro.org>,
Russell King <linux@armlinux.org.uk>,
Atish Patra <atish.patra@wdc.com>,
Mauro Carvalho Chehab <mchehab+samsung@kernel.org>,
linux-riscv@lists.infradead.org, Will Deacon <will@kernel.org>,
Ingo Molnar <mingo@kernel.org>,
"Chang, Abner \(HPS SW/FW Technologist\)" <abner.chang@hpe.com>,
Michal Simek <michal.simek@xilinx.com>,
Mike Rapoport <rppt@linux.ibm.com>,
Greentime Hu <greentime.hu@sifive.com>,
Borislav Petkov <bp@suse.de>, Mao Han <han_mao@c-sky.com>,
daniel.schaefer@hpe.com, Albert Ou <aou@eecs.berkeley.edu>,
Kees Cook <keescook@chromium.org>, Arnd Bergmann <arnd@arndb.de>,
Alexios Zavras <alexios.zavras@intel.com>,
Alexander Graf <agraf@csgraf.de>,
Paul Walmsley <paul.walmsley@sifive.com>,
Thomas Gleixner <tglx@linutronix.de>,
Allison Randal <allison@lohutok.net>,
"leif@nuviainc.com" <leif@nuviainc.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Anup Patel <Anup.Patel@wdc.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>
Subject: [RFC PATCH 4/5] RISC-V: Add PE/COFF header for EFI stub
Date: Tue, 25 Feb 2020 17:10:36 -0800 [thread overview]
Message-ID: <20200226011037.7179-5-atish.patra@wdc.com> (raw)
In-Reply-To: <20200226011037.7179-1-atish.patra@wdc.com>
Linux kernel Image can appear as an EFI application With appropriate
PE/COFF header fields in the beginning of the Image header. An EFI
application loader can directly load a Linux kernel Image and an EFI
stub residing in kernel can boot Linux kernel directly.
Add the necessary PE/COFF header.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
---
arch/riscv/include/asm/Kbuild | 1 -
arch/riscv/include/asm/sections.h | 13 ++++
arch/riscv/kernel/Makefile | 4 ++
| 107 ++++++++++++++++++++++++++++++
arch/riscv/kernel/head.S | 15 +++++
arch/riscv/kernel/image-vars.h | 52 +++++++++++++++
arch/riscv/kernel/vmlinux.lds.S | 27 ++++++--
7 files changed, 212 insertions(+), 7 deletions(-)
create mode 100644 arch/riscv/include/asm/sections.h
create mode 100644 arch/riscv/kernel/efi-header.S
create mode 100644 arch/riscv/kernel/image-vars.h
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 517394390106..ef797fe44934 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -24,7 +24,6 @@ generic-y += local64.h
generic-y += mm-arch-hooks.h
generic-y += percpu.h
generic-y += preempt.h
-generic-y += sections.h
generic-y += serial.h
generic-y += shmparam.h
generic-y += topology.h
diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
new file mode 100644
index 000000000000..3a9971b1210f
--- /dev/null
+++ b/arch/riscv/include/asm/sections.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 Western Digital Corporation or its affiliates.
+ */
+#ifndef __ASM_SECTIONS_H
+#define __ASM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _start[];
+extern char _start_kernel[];
+
+#endif /* __ASM_SECTIONS_H */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 9601ac907f70..471b1c73f77d 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -29,6 +29,10 @@ obj-y += cacheinfo.o
obj-$(CONFIG_MMU) += vdso.o vdso/
obj-$(CONFIG_RISCV_M_MODE) += clint.o
+OBJCOPYFLAGS := --prefix-symbols=__efistub_
+$(obj)/%.stub.o: $(obj)/%.o FORCE
+ $(call if_changed,objcopy)
+
obj-$(CONFIG_FPU) += fpu.o
obj-$(CONFIG_SMP) += smpboot.o
obj-$(CONFIG_SMP) += smp.o
--git a/arch/riscv/kernel/efi-header.S b/arch/riscv/kernel/efi-header.S
new file mode 100644
index 000000000000..af959e748d93
--- /dev/null
+++ b/arch/riscv/kernel/efi-header.S
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
+ * Adapted from arch/arm64/kernel/efi-header.S
+ */
+
+#include <linux/pe.h>
+#include <linux/sizes.h>
+
+ .macro __EFI_PE_HEADER
+ .long PE_MAGIC
+coff_header:
+ .short IMAGE_FILE_MACHINE_RISCV64 // Machine
+ .short section_count // NumberOfSections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 0 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short IMAGE_FILE_DEBUG_STRIPPED | \
+ IMAGE_FILE_EXECUTABLE_IMAGE | \
+ IMAGE_FILE_LINE_NUMS_STRIPPED // Characteristics
+
+optional_header:
+ .short PE_OPT_MAGIC_PE32PLUS // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // MinorLinkerVersion
+ .long __text_end - efi_header_end // SizeOfCode
+ .long _end - __text_end // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long __efistub_efi_entry - _start // AddressOfEntryPoint
+ .long efi_header_end - _start // BaseOfCode
+
+extra_header_fields:
+ .quad 0 // ImageBase
+ .long SZ_4K // SectionAlignment
+ .long PECOFF_FILE_ALIGNMENT // FileAlignment
+ .short 0 // MajorOperatingSystemVersion
+ .short 0 // MinorOperatingSystemVersion
+ .short 0 // MajorImageVersion
+ .short 0 // MinorImageVersion
+ .short 0 // MajorSubsystemVersion
+ .short 0 // MinorSubsystemVersion
+ .long 0 // Win32VersionValue
+
+ .long _end - _start // SizeOfImage
+
+ // Everything before the kernel image is considered part of the header
+ .long efi_header_end - _start // 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 (section_table - .) / 8 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+ // Section table
+section_table:
+ .ascii ".text\0\0\0"
+ .long __text_end - efi_header_end // VirtualSize
+ .long efi_header_end - _start // VirtualAddress
+ .long __text_end - efi_header_end // SizeOfRawData
+ .long efi_header_end - _start // 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 __data_virt_size // VirtualSize
+ .long __text_end - _start // VirtualAddress
+ .long __data_raw_size // SizeOfRawData
+ .long __text_end - _start // 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 section_count, (. - section_table) / 40
+
+ /*
+ * EFI will load .text onwards at the 4k section alignment
+ * described in the PE/COFF header. To ensure that instruction
+ * sequences using an adrp and a :lo12: immediate will function
+ * correctly at this alignment, we must ensure that .text is
+ * placed at a 4k boundary in the Image to begin with.
+ */
+ .align 12
+efi_header_end:
+ .endm
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index ac5b0e0a02f6..835dc76de285 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -13,6 +13,7 @@
#include <asm/csr.h>
#include <asm/hwcap.h>
#include <asm/image.h>
+#include "efi-header.S"
__HEAD
ENTRY(_start)
@@ -22,10 +23,17 @@ ENTRY(_start)
* Do not modify it without modifying the structure and all bootloaders
* that expects this header format!!
*/
+#ifdef CONFIG_EFI
+ /*
+ * This instruction decodes to "MZ" ASCII required by UEFI.
+ */
+ li s4,-13
+#else
/* jump to start kernel */
j _start_kernel
/* reserved */
.word 0
+#endif
.balign 8
#if __riscv_xlen == 64
/* Image load offset(2MB) from start of RAM */
@@ -43,7 +51,14 @@ ENTRY(_start)
.ascii RISCV_IMAGE_MAGIC
.balign 4
.ascii RISCV_IMAGE_MAGIC2
+#ifdef CONFIG_EFI
+ .word pe_head_start - _start
+pe_head_start:
+
+ __EFI_PE_HEADER
+#else
.word 0
+#endif
.align 2
#ifdef CONFIG_MMU
diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h
new file mode 100644
index 000000000000..57abb85065e9
--- /dev/null
+++ b/arch/riscv/kernel/image-vars.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Linker script variables to be set after section resolution, as
+ * ld.lld does not like variables assigned before SECTIONS is processed.
+ * Based on arch/arm64/kerne/image-vars.h
+ */
+#ifndef __RISCV_KERNEL_IMAGE_VARS_H
+#define __RISCV_KERNEL_IMAGE_VARS_H
+
+#ifndef LINKER_SCRIPT
+#error This file should only be included in vmlinux.lds.S
+#endif
+
+#ifdef CONFIG_EFI
+
+__efistub_stext_offset = _start_kernel - _start;
+
+/*
+ * The EFI stub has its own symbol namespace prefixed by __efistub_, to
+ * isolate it from the kernel proper. The following symbols are legally
+ * accessed by the stub, so provide some aliases to make them accessible.
+ * Only include data symbols here, or text symbols of functions that are
+ * guaranteed to be safe when executed at another offset than they were
+ * linked at. The routines below are all implemented in assembler in a
+ * position independent manner
+ */
+__efistub_memcmp = memcmp;
+__efistub_memchr = memchr;
+__efistub_memcpy = memcpy;
+__efistub_memmove = memmove;
+__efistub_memset = memset;
+__efistub_strlen = strlen;
+__efistub_strnlen = strnlen;
+__efistub_strcmp = strcmp;
+__efistub_strncmp = strncmp;
+__efistub_strrchr = strrchr;
+
+#ifdef CONFIG_KASAN
+__efistub___memcpy = memcpy;
+__efistub___memmove = memmove;
+__efistub___memset = memset;
+#endif
+
+__efistub__start = _start;
+__efistub__start_kernel = _start_kernel;
+__efistub__end = _end;
+__efistub__edata = _edata;
+__efistub_screen_info = screen_info;
+
+#endif
+
+#endif /* __RISCV_KERNEL_IMAGE_VARS_H */
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index b32640300d07..933b9e9a4b39 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -9,6 +9,7 @@
#include <asm/page.h>
#include <asm/cache.h>
#include <asm/thread_info.h>
+#include "image-vars.h"
#include <linux/sizes.h>
OUTPUT_ARCH(riscv)
@@ -16,6 +17,14 @@ ENTRY(_start)
jiffies = jiffies_64;
+PECOFF_FILE_ALIGNMENT = 0x200;
+#ifdef CONFIG_EFI
+#define PECOFF_EDATA_PADDING \
+ .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
+#else
+#define PECOFF_EDATA_PADDING
+#endif
+
SECTIONS
{
/* Beginning of code and text segment */
@@ -26,12 +35,15 @@ SECTIONS
__init_begin = .;
INIT_TEXT_SECTION(PAGE_SIZE)
+
+ /* Start of data section */
INIT_DATA_SECTION(16)
/* we have to discard exit text and such at runtime, not link time */
.exit.text :
{
EXIT_TEXT
}
+
.exit.data :
{
EXIT_DATA
@@ -54,7 +66,8 @@ SECTIONS
_etext = .;
}
- /* Start of data section */
+ __text_end = .;
+
_sdata = .;
RO_DATA(L1_CACHE_BYTES)
.srodata : {
@@ -65,19 +78,21 @@ SECTIONS
.sdata : {
__global_pointer$ = . + 0x800;
*(.sdata*)
- /* End of data section */
- _edata = .;
*(.sbss*)
}
-
- BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0)
-
+ PECOFF_EDATA_PADDING
+ __data_raw_size = ABSOLUTE(. - __text_end);
+ /* End of data section */
+ _edata = .;
EXCEPTION_TABLE(0x10)
.rel.dyn : {
*(.rel.dyn*)
}
+ BSS_SECTION(PAGE_SIZE, PAGE_SIZE, 0)
+ __data_virt_size = ABSOLUTE(. - __text_end);
+
_end = .;
STABS_DEBUG
--
2.24.0
next prev parent reply other threads:[~2020-02-26 1:11 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-26 1:10 [RFC PATCH 0/5] Add UEFI support for RISC-V Atish Patra
2020-02-26 1:10 ` [RFC PATCH 1/5] efi: Move arm-stub to a common file Atish Patra
2020-02-26 7:04 ` Ard Biesheuvel
2020-02-27 1:16 ` Atish Patra
2020-02-26 1:10 ` [RFC PATCH 2/5] include: pe.h: Add RISC-V related PE definition Atish Patra
2020-02-26 7:06 ` Ard Biesheuvel
2020-02-27 0:53 ` Atish Patra
2020-02-26 1:10 ` [RFC PATCH 3/5] RISC-V: Define fixmap bindings for generic early ioremap support Atish Patra
2020-02-26 7:08 ` Ard Biesheuvel
2020-02-27 19:58 ` Atish Patra
2020-02-27 20:00 ` Ard Biesheuvel
2020-02-26 1:10 ` Atish Patra [this message]
2020-02-26 7:14 ` [RFC PATCH 4/5] RISC-V: Add PE/COFF header for EFI stub Ard Biesheuvel
2020-02-27 1:29 ` Atish Patra
2020-02-27 7:44 ` Ard Biesheuvel
2020-02-26 1:10 ` [RFC PATCH 5/5] RISC-V: Add EFI stub support Atish Patra
2020-02-26 7:28 ` Ard Biesheuvel
2020-02-27 19:53 ` Atish Patra
2020-02-27 19:59 ` Ard Biesheuvel
2020-02-28 1:05 ` Atish Patra
2020-02-28 6:57 ` Ard Biesheuvel
2020-03-10 7:08 ` Atish Patra
2020-03-10 7:38 ` Anup Patel
2020-03-10 13:18 ` Ard Biesheuvel
2020-02-26 23:46 ` [RFC PATCH 0/5] Add UEFI support for RISC-V Palmer Dabbelt
2020-02-27 2:09 ` Atish Patra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200226011037.7179-5-atish.patra@wdc.com \
--to=atish.patra@wdc.com \
--cc=Anup.Patel@wdc.com \
--cc=abner.chang@hpe.com \
--cc=agraf@csgraf.de \
--cc=akpm@linux-foundation.org \
--cc=alexios.zavras@intel.com \
--cc=allison@lohutok.net \
--cc=aou@eecs.berkeley.edu \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=bp@suse.de \
--cc=catalin.marinas@arm.com \
--cc=daniel.schaefer@hpe.com \
--cc=greentime.hu@sifive.com \
--cc=gregkh@linuxfoundation.org \
--cc=han_mao@c-sky.com \
--cc=keescook@chromium.org \
--cc=kstewart@linuxfoundation.org \
--cc=leif@nuviainc.com \
--cc=linus.walleij@linaro.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=mchehab+samsung@kernel.org \
--cc=michal.simek@xilinx.com \
--cc=mingo@kernel.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=pbonzini@redhat.com \
--cc=rppt@linux.ibm.com \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).