From 196e63e9cc683044ba06206af138d86b8cee0731 Mon Sep 17 00:00:00 2001 From: Karsten Merker Date: Wed, 31 Jul 2019 23:01:17 +0200 Subject: [PATCH] [riscv64] Backport kernel image header support from kernel 5.3 This patch adds a header to the kernel image that allows bootloaders such as u-boot to properly load plain kernel images instead of requiring uImage-wrapped kernels. That also enables the use of syslinux-style boot menus in u-boot on riscv64. --- .../riscv64/RISC-V-Add-Image-header.patch | 217 ++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 218 insertions(+) create mode 100644 debian/patches/features/riscv64/RISC-V-Add-Image-header.patch diff --git a/debian/patches/features/riscv64/RISC-V-Add-Image-header.patch b/debian/patches/features/riscv64/RISC-V-Add-Image-header.patch new file mode 100644 index 000000000000..79402cc4fcea --- /dev/null +++ b/debian/patches/features/riscv64/RISC-V-Add-Image-header.patch @@ -0,0 +1,217 @@ +From 0f327f2aaad6a87356cbccfa390d4d3b64d0d3b6 Mon Sep 17 00:00:00 2001 +From: Atish Patra +Date: Thu, 6 Jun 2019 16:08:00 -0700 +Subject: RISC-V: Add an Image header that boot loader can parse. +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=0f327f2aaad6a87356cbccfa390d4d3b64d0d3b6 + +Currently, the last stage boot loaders such as U-Boot can accept only +uImage which is an unnecessary additional step in automating boot +process. + +Add an image header that boot loader understands and boot Linux from +flat Image directly. + +This header is based on ARM64 boot image header and provides an +opportunity to combine both ARM64 & RISC-V image headers in future. + +Also make sure that PE/COFF header can co-exist in the same image so +that EFI stub can be supported for RISC-V in future. EFI specification +needs PE/COFF image header in the beginning of the kernel image in order +to load it as an EFI application. In order to support EFI stub, code0 +should be replaced with "MZ" magic string and res4(at offset 0x3c) +should point to the rest of the PE/COFF header (which will be added +during EFI support). + +Tested on both QEMU and HiFive Unleashed using OpenSBI + U-Boot + Linux. + +Signed-off-by: Atish Patra +Reviewed-by: Karsten Merker +Tested-by: Karsten Merker (QEMU+OpenSBI+U-Boot) +Tested-by: Kevin Hilman (OpenSBI + U-Boot + Linux) +[paul.walmsley@sifive.com: fixed whitespace in boot-image-header.txt; + converted structure comment to kernel-doc format and added some detail] +Signed-off-by: Paul Walmsley +--- + Documentation/riscv/boot-image-header.txt | 50 ++++++++++++++++++++++++ + arch/riscv/include/asm/image.h | 65 +++++++++++++++++++++++++++++++ + arch/riscv/kernel/head.S | 32 +++++++++++++++ + 3 files changed, 147 insertions(+) + create mode 100644 Documentation/riscv/boot-image-header.txt + create mode 100644 arch/riscv/include/asm/image.h + +diff --git a/Documentation/riscv/boot-image-header.txt b/Documentation/riscv/boot-image-header.txt +new file mode 100644 +index 000000000000..1b73fea23b39 +--- /dev/null ++++ b/Documentation/riscv/boot-image-header.txt +@@ -0,0 +1,50 @@ ++ Boot image header in RISC-V Linux ++ ============================================= ++ ++Author: Atish Patra ++Date : 20 May 2019 ++ ++This document only describes the boot image header details for RISC-V Linux. ++The complete booting guide will be available at Documentation/riscv/booting.txt. ++ ++The following 64-byte header is present in decompressed Linux kernel image. ++ ++ u32 code0; /* Executable code */ ++ u32 code1; /* Executable code */ ++ u64 text_offset; /* Image load offset, little endian */ ++ u64 image_size; /* Effective Image size, little endian */ ++ u64 flags; /* kernel flags, little endian */ ++ u32 version; /* Version of this header */ ++ u32 res1 = 0; /* Reserved */ ++ u64 res2 = 0; /* Reserved */ ++ u64 magic = 0x5643534952; /* Magic number, little endian, "RISCV" */ ++ u32 res3; /* Reserved for additional RISC-V specific header */ ++ u32 res4; /* Reserved for PE COFF offset */ ++ ++This header format is compliant with PE/COFF header and largely inspired from ++ARM64 header. Thus, both ARM64 & RISC-V header can be combined into one common ++header in future. ++ ++Notes: ++- This header can also be reused to support EFI stub for RISC-V in future. EFI ++ specification needs PE/COFF image header in the beginning of the kernel image ++ in order to load it as an EFI application. In order to support EFI stub, ++ code0 should be replaced with "MZ" magic string and res5(at offset 0x3c) should ++ point to the rest of the PE/COFF header. ++ ++- version field indicate header version number. ++ Bits 0:15 - Minor version ++ Bits 16:31 - Major version ++ ++ This preserves compatibility across newer and older version of the header. ++ The current version is defined as 0.1. ++ ++- res3 is reserved for offset to any other additional fields. This makes the ++ header extendible in future. One example would be to accommodate ISA ++ extension for RISC-V in future. For current version, it is set to be zero. ++ ++- In current header, the flag field has only one field. ++ Bit 0: Kernel endianness. 1 if BE, 0 if LE. ++ ++- Image size is mandatory for boot loader to load kernel image. Booting will ++ fail otherwise. +diff --git a/arch/riscv/include/asm/image.h b/arch/riscv/include/asm/image.h +new file mode 100644 +index 000000000000..ef28e106f247 +--- /dev/null ++++ b/arch/riscv/include/asm/image.h +@@ -0,0 +1,65 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++#ifndef __ASM_IMAGE_H ++#define __ASM_IMAGE_H ++ ++#define RISCV_IMAGE_MAGIC "RISCV" ++ ++#define RISCV_IMAGE_FLAG_BE_SHIFT 0 ++#define RISCV_IMAGE_FLAG_BE_MASK 0x1 ++ ++#define RISCV_IMAGE_FLAG_LE 0 ++#define RISCV_IMAGE_FLAG_BE 1 ++ ++#ifdef CONFIG_CPU_BIG_ENDIAN ++#error conversion of header fields to LE not yet implemented ++#else ++#define __HEAD_FLAG_BE RISCV_IMAGE_FLAG_LE ++#endif ++ ++#define __HEAD_FLAG(field) (__HEAD_FLAG_##field << \ ++ RISCV_IMAGE_FLAG_##field##_SHIFT) ++ ++#define __HEAD_FLAGS (__HEAD_FLAG(BE)) ++ ++#define RISCV_HEADER_VERSION_MAJOR 0 ++#define RISCV_HEADER_VERSION_MINOR 1 ++ ++#define RISCV_HEADER_VERSION (RISCV_HEADER_VERSION_MAJOR << 16 | \ ++ RISCV_HEADER_VERSION_MINOR) ++ ++#ifndef __ASSEMBLY__ ++/** ++ * struct riscv_image_header - riscv kernel image header ++ * @code0: Executable code ++ * @code1: Executable code ++ * @text_offset: Image load offset (little endian) ++ * @image_size: Effective Image size (little endian) ++ * @flags: kernel flags (little endian) ++ * @version: version ++ * @res1: reserved ++ * @res2: reserved ++ * @magic: Magic number ++ * @res3: reserved (will be used for additional RISC-V specific ++ * header) ++ * @res4: reserved (will be used for PE COFF offset) ++ * ++ * The intention is for this header format to be shared between multiple ++ * architectures to avoid a proliferation of image header formats. ++ */ ++ ++struct riscv_image_header { ++ u32 code0; ++ u32 code1; ++ u64 text_offset; ++ u64 image_size; ++ u64 flags; ++ u32 version; ++ u32 res1; ++ u64 res2; ++ u64 magic; ++ u32 res3; ++ u32 res4; ++}; ++#endif /* __ASSEMBLY__ */ ++#endif /* __ASM_IMAGE_H */ +diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S +index e368106f2228..0f1ba17e476f 100644 +--- a/arch/riscv/kernel/head.S ++++ b/arch/riscv/kernel/head.S +@@ -11,9 +11,41 @@ + #include + #include + #include ++#include + + __INIT + ENTRY(_start) ++ /* ++ * Image header expected by Linux boot-loaders. The image header data ++ * structure is described in asm/image.h. ++ * Do not modify it without modifying the structure and all bootloaders ++ * that expects this header format!! ++ */ ++ /* jump to start kernel */ ++ j _start_kernel ++ /* reserved */ ++ .word 0 ++ .balign 8 ++#if __riscv_xlen == 64 ++ /* Image load offset(2MB) from start of RAM */ ++ .dword 0x200000 ++#else ++ /* Image load offset(4MB) from start of RAM */ ++ .dword 0x400000 ++#endif ++ /* Effective size of kernel image */ ++ .dword _end - _start ++ .dword __HEAD_FLAGS ++ .word RISCV_HEADER_VERSION ++ .word 0 ++ .dword 0 ++ .asciz RISCV_IMAGE_MAGIC ++ .word 0 ++ .balign 4 ++ .word 0 ++ ++.global _start_kernel ++_start_kernel: + /* Mask all interrupts */ + csrw CSR_SIE, zero + csrw CSR_SIP, zero +-- +cgit 1.2-0.3.lf.el7 + diff --git a/debian/patches/series b/debian/patches/series index 868a8e944de3..4db471131d44 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -76,6 +76,7 @@ features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch features/x86/x86-memtest-WARN-if-bad-RAM-found.patch features/x86/x86-make-x32-syscall-support-conditional.patch +features/riscv64/RISC-V-Add-Image-header.patch # Miscellaneous bug fixes bugfix/all/disable-some-marvell-phys.patch