-
Notifications
You must be signed in to change notification settings - Fork 54.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RISC-V: Add PE/COFF header for EFI stub
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> Link: https://lore.kernel.org/r/20200421033336.9663-3-atish.patra@wdc.com [ardb: - use C prefix for c.li to ensure the expected opcode is emitted - align all image sections according to PE/COFF section alignment ] Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Anup Patel <anup@brainfault.org> Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
- Loading branch information
1 parent
e8dcb61
commit cb7d2dd
Showing
5 changed files
with
212 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Copyright (C) 2020 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: | ||
#ifdef CONFIG_64BIT | ||
.short IMAGE_FILE_MACHINE_RISCV64 // Machine | ||
#else | ||
.short IMAGE_FILE_MACHINE_RISCV32 // Machine | ||
#endif | ||
.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: | ||
#ifdef CONFIG_64BIT | ||
.short PE_OPT_MAGIC_PE32PLUS // PE32+ format | ||
#else | ||
.short PE_OPT_MAGIC_PE32 // PE32 format | ||
#endif | ||
.byte 0x02 // MajorLinkerVersion | ||
.byte 0x14 // MinorLinkerVersion | ||
.long __pecoff_text_end - efi_header_end // SizeOfCode | ||
.long __pecoff_data_virt_size // SizeOfInitializedData | ||
.long 0 // SizeOfUninitializedData | ||
.long __efistub_efi_pe_entry - _start // AddressOfEntryPoint | ||
.long efi_header_end - _start // BaseOfCode | ||
#ifdef CONFIG_32BIT | ||
.long __pecoff_text_end - _start // BaseOfData | ||
#endif | ||
|
||
extra_header_fields: | ||
.quad 0 // ImageBase | ||
.long PECOFF_SECTION_ALIGNMENT // SectionAlignment | ||
.long PECOFF_FILE_ALIGNMENT // 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 - _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 __pecoff_text_end - efi_header_end // VirtualSize | ||
.long efi_header_end - _start // VirtualAddress | ||
.long __pecoff_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 __pecoff_data_virt_size // VirtualSize | ||
.long __pecoff_text_end - _start // VirtualAddress | ||
.long __pecoff_data_raw_size // SizeOfRawData | ||
.long __pecoff_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 | ||
|
||
.balign 0x1000 | ||
efi_header_end: | ||
.endm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* SPDX-License-Identifier: GPL-2.0-only */ | ||
/* | ||
* Copyright (C) 2020 Western Digital Corporation or its affiliates. | ||
* 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 | ||
|
||
/* | ||
* 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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters