Skip to content

Commit 0f327f2

Browse files
atishp04paul-walmsley-sifive
authored andcommitted
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]>
1 parent 671f9a3 commit 0f327f2

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
Boot image header in RISC-V Linux
2+
=============================================
3+
4+
Author: Atish Patra <[email protected]>
5+
Date : 20 May 2019
6+
7+
This document only describes the boot image header details for RISC-V Linux.
8+
The complete booting guide will be available at Documentation/riscv/booting.txt.
9+
10+
The following 64-byte header is present in decompressed Linux kernel image.
11+
12+
u32 code0; /* Executable code */
13+
u32 code1; /* Executable code */
14+
u64 text_offset; /* Image load offset, little endian */
15+
u64 image_size; /* Effective Image size, little endian */
16+
u64 flags; /* kernel flags, little endian */
17+
u32 version; /* Version of this header */
18+
u32 res1 = 0; /* Reserved */
19+
u64 res2 = 0; /* Reserved */
20+
u64 magic = 0x5643534952; /* Magic number, little endian, "RISCV" */
21+
u32 res3; /* Reserved for additional RISC-V specific header */
22+
u32 res4; /* Reserved for PE COFF offset */
23+
24+
This header format is compliant with PE/COFF header and largely inspired from
25+
ARM64 header. Thus, both ARM64 & RISC-V header can be combined into one common
26+
header in future.
27+
28+
Notes:
29+
- This header can also be reused to support EFI stub for RISC-V in future. EFI
30+
specification needs PE/COFF image header in the beginning of the kernel image
31+
in order to load it as an EFI application. In order to support EFI stub,
32+
code0 should be replaced with "MZ" magic string and res5(at offset 0x3c) should
33+
point to the rest of the PE/COFF header.
34+
35+
- version field indicate header version number.
36+
Bits 0:15 - Minor version
37+
Bits 16:31 - Major version
38+
39+
This preserves compatibility across newer and older version of the header.
40+
The current version is defined as 0.1.
41+
42+
- res3 is reserved for offset to any other additional fields. This makes the
43+
header extendible in future. One example would be to accommodate ISA
44+
extension for RISC-V in future. For current version, it is set to be zero.
45+
46+
- In current header, the flag field has only one field.
47+
Bit 0: Kernel endianness. 1 if BE, 0 if LE.
48+
49+
- Image size is mandatory for boot loader to load kernel image. Booting will
50+
fail otherwise.

arch/riscv/include/asm/image.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef __ASM_IMAGE_H
4+
#define __ASM_IMAGE_H
5+
6+
#define RISCV_IMAGE_MAGIC "RISCV"
7+
8+
#define RISCV_IMAGE_FLAG_BE_SHIFT 0
9+
#define RISCV_IMAGE_FLAG_BE_MASK 0x1
10+
11+
#define RISCV_IMAGE_FLAG_LE 0
12+
#define RISCV_IMAGE_FLAG_BE 1
13+
14+
#ifdef CONFIG_CPU_BIG_ENDIAN
15+
#error conversion of header fields to LE not yet implemented
16+
#else
17+
#define __HEAD_FLAG_BE RISCV_IMAGE_FLAG_LE
18+
#endif
19+
20+
#define __HEAD_FLAG(field) (__HEAD_FLAG_##field << \
21+
RISCV_IMAGE_FLAG_##field##_SHIFT)
22+
23+
#define __HEAD_FLAGS (__HEAD_FLAG(BE))
24+
25+
#define RISCV_HEADER_VERSION_MAJOR 0
26+
#define RISCV_HEADER_VERSION_MINOR 1
27+
28+
#define RISCV_HEADER_VERSION (RISCV_HEADER_VERSION_MAJOR << 16 | \
29+
RISCV_HEADER_VERSION_MINOR)
30+
31+
#ifndef __ASSEMBLY__
32+
/**
33+
* struct riscv_image_header - riscv kernel image header
34+
* @code0: Executable code
35+
* @code1: Executable code
36+
* @text_offset: Image load offset (little endian)
37+
* @image_size: Effective Image size (little endian)
38+
* @flags: kernel flags (little endian)
39+
* @version: version
40+
* @res1: reserved
41+
* @res2: reserved
42+
* @magic: Magic number
43+
* @res3: reserved (will be used for additional RISC-V specific
44+
* header)
45+
* @res4: reserved (will be used for PE COFF offset)
46+
*
47+
* The intention is for this header format to be shared between multiple
48+
* architectures to avoid a proliferation of image header formats.
49+
*/
50+
51+
struct riscv_image_header {
52+
u32 code0;
53+
u32 code1;
54+
u64 text_offset;
55+
u64 image_size;
56+
u64 flags;
57+
u32 version;
58+
u32 res1;
59+
u64 res2;
60+
u64 magic;
61+
u32 res3;
62+
u32 res4;
63+
};
64+
#endif /* __ASSEMBLY__ */
65+
#endif /* __ASM_IMAGE_H */

arch/riscv/kernel/head.S

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,41 @@
1111
#include <asm/thread_info.h>
1212
#include <asm/page.h>
1313
#include <asm/csr.h>
14+
#include <asm/image.h>
1415

1516
__INIT
1617
ENTRY(_start)
18+
/*
19+
* Image header expected by Linux boot-loaders. The image header data
20+
* structure is described in asm/image.h.
21+
* Do not modify it without modifying the structure and all bootloaders
22+
* that expects this header format!!
23+
*/
24+
/* jump to start kernel */
25+
j _start_kernel
26+
/* reserved */
27+
.word 0
28+
.balign 8
29+
#if __riscv_xlen == 64
30+
/* Image load offset(2MB) from start of RAM */
31+
.dword 0x200000
32+
#else
33+
/* Image load offset(4MB) from start of RAM */
34+
.dword 0x400000
35+
#endif
36+
/* Effective size of kernel image */
37+
.dword _end - _start
38+
.dword __HEAD_FLAGS
39+
.word RISCV_HEADER_VERSION
40+
.word 0
41+
.dword 0
42+
.asciz RISCV_IMAGE_MAGIC
43+
.word 0
44+
.balign 4
45+
.word 0
46+
47+
.global _start_kernel
48+
_start_kernel:
1749
/* Mask all interrupts */
1850
csrw CSR_SIE, zero
1951
csrw CSR_SIP, zero

0 commit comments

Comments
 (0)