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 <[email protected]>
Reviewed-by: Karsten Merker <[email protected]>
Tested-by: Karsten Merker <[email protected]> (QEMU+OpenSBI+U-Boot)
Tested-by: Kevin Hilman <[email protected]> (OpenSBI + U-Boot + Linux)
---
I have not sent out corresponding U-Boot patch as all the changes are
compatible with current u-boot support. Once, the kernel header format
is agreed upon, I will update the U-Boot patch.
Changes from v4->v5
1. Error if CONFIG_CPU_BIG_ENDIAN is enabled in kernel.
2. Typo fix
Changes from v3->v4
1. Update the commit text to clarify about PE/COFF header.
Changes from v2->v3
1. Modified reserved fields to define a header version.
2. Added header documentation.
Changes from v1-v2:
1. Added additional reserved elements to make it fully PE compatible.
---
Documentation/riscv/boot-image-header.txt | 50 ++++++++++++++++++
arch/riscv/include/asm/image.h | 62 +++++++++++++++++++++++
arch/riscv/kernel/head.S | 32 ++++++++++++
3 files changed, 144 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..acbf3b4cacfe
--- /dev/null
+++ b/Documentation/riscv/boot-image-header.txt
@@ -0,0 +1,50 @@
+ Boot image header in RISC-V Linux
+ =============================================
+
+Author: Atish Patra <[email protected]>
+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..13f4365d2dd6
--- /dev/null
+++ b/arch/riscv/include/asm/image.h
@@ -0,0 +1,62 @@
+/* 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
+ * @image_size: Effective Image size
+ * @flags: kernel flags
+ * @version: version
+ * @reserved: reserved
+ * @reserved: reserved
+ * @magic: Magic number
+ * @reserved: reserved (will be used for additional RISC-V specific header)
+ * @reserved: reserved (will be used for PE COFF offset)
+ */
+
+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 370c66ce187a..577893bb150d 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -19,9 +19,41 @@
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/csr.h>
+#include <asm/image.h>
__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
--
2.21.0
On Thu, 6 Jun 2019, Atish Patra wrote:
> 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.
...
> +#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
Is there a rationale behind these load offset values?
- Paul
On Fri, 2019-06-28 at 12:09 -0700, Paul Walmsley wrote:
> On Thu, 6 Jun 2019, Atish Patra wrote:
>
> > 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.
>
> ...
>
>
> > +#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
>
> Is there a rationale behind these load offset values?
>
2MB/4MB alignment requirement is mandatory for current RISC-V kernel.
Anup had a patch that tried to remove that but not accepted yet.
https://patchwork.kernel.org/patch/10868465/
>
> - Paul
>
> _______________________________________________
> linux-riscv mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-riscv
--
Regards,
Atish
On Fri, 28 Jun 2019, Atish Patra wrote:
> On Fri, 2019-06-28 at 12:09 -0700, Paul Walmsley wrote:
> > On Thu, 6 Jun 2019, Atish Patra wrote:
> >
> > > 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.
> >
> > ...
> >
> >
> > > +#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
> >
> > Is there a rationale behind these load offset values?
> >
>
> 2MB/4MB alignment requirement is mandatory for current RISC-V kernel.
> Anup had a patch that tried to remove that but not accepted yet.
>
> https://patchwork.kernel.org/patch/10868465/
Thanks for doing this work; this should really help. Patch queued with a
few minor tweaks to the documentation file and to the comments. (Updated
patch below)
Not sure if this will make it for v5.3-rc1. If not, we'll try to get it
in as soon as possible afterwards.
Something else to think about: we'll probably want some flag bits soon to
identify whether the kernel binary is a 32-bit, 64-bit, or 128-bit binary.
If two bits are used, and 64-bit is defined as 00, then it should be
backwards compatible. I would hope that this could be something that we'd
be able to coordinate with the ARM64 folks also; otherwise we may need to
start using that res3 field.
- Paul
From: Atish Patra <[email protected]>
Date: Thu, 6 Jun 2019 16:08:00 -0700
Subject: [PATCH] RISC-V: Add an Image header that boot loader can parse.
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 <[email protected]>
Reviewed-by: Karsten Merker <[email protected]>
Tested-by: Karsten Merker <[email protected]> (QEMU+OpenSBI+U-Boot)
Tested-by: Kevin Hilman <[email protected]> (OpenSBI + U-Boot + Linux)
[[email protected]: fixed whitespace in boot-image-header.txt;
converted structure comment to kernel-doc format and added some detail]
Signed-off-by: Paul Walmsley <[email protected]>
---
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 <[email protected]>
+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 <asm/thread_info.h>
#include <asm/page.h>
#include <asm/csr.h>
+#include <asm/image.h>
__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
--
2.20.1
On Thu, 2019-07-11 at 12:42 -0700, Paul Walmsley wrote:
> On Fri, 28 Jun 2019, Atish Patra wrote:
>
> > On Fri, 2019-06-28 at 12:09 -0700, Paul Walmsley wrote:
> > > On Thu, 6 Jun 2019, Atish Patra wrote:
> > >
> > > > 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.
> > >
> > > ...
> > >
> > >
> > > > +#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
> > >
> > > Is there a rationale behind these load offset values?
> > >
> >
> > 2MB/4MB alignment requirement is mandatory for current RISC-V
> > kernel.
> > Anup had a patch that tried to remove that but not accepted yet.
> >
> > https://patchwork.kernel.org/patch/10868465/
>
> Thanks for doing this work; this should really help. Patch queued
> with a
> few minor tweaks to the documentation file and to the
> comments. (Updated
> patch below)
>
Thank you!
> Not sure if this will make it for v5.3-rc1. If not, we'll try to get
> it
> in as soon as possible afterwards.
>
> Something else to think about: we'll probably want some flag bits
> soon to
> identify whether the kernel binary is a 32-bit, 64-bit, or 128-bit
> binary.
> If two bits are used, and 64-bit is defined as 00, then it should be
> backwards compatible. I would hope that this could be something that
> we'd
> be able to coordinate with the ARM64 folks also;
Sure. We can always any bits from 4-64 (reserved in ARM header). That
will still allow the ARM64/RISC-V headers to merge in future if ARM
maintainers are interested.
> otherwise we may need to
> start using that res3 field.
>
>
> - Paul
>
> From: Atish Patra <[email protected]>
> Date: Thu, 6 Jun 2019 16:08:00 -0700
> Subject: [PATCH] RISC-V: Add an Image header that boot loader can
> parse.
>
> 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 <[email protected]>
> Reviewed-by: Karsten Merker <[email protected]>
> Tested-by: Karsten Merker <[email protected]> (QEMU+OpenSBI+U-Boot)
> Tested-by: Kevin Hilman <[email protected]> (OpenSBI + U-Boot +
> Linux)
> [[email protected]: fixed whitespace in boot-image-header.txt;
> converted structure comment to kernel-doc format and added some
> detail]
> Signed-off-by: Paul Walmsley <[email protected]>
> ---
> 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 <[email protected]>
> +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 <asm/thread_info.h>
> #include <asm/page.h>
> #include <asm/csr.h>
> +#include <asm/image.h>
>
> __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
--
Regards,
Atish