All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karsten Merker <merker@debian.org>
To: Anup Patel <anup@brainfault.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
	Palmer Dabbelt <palmer@sifive.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"zong@andestech.com" <zong@andestech.com>,
	Atish Patra <atish.patra@wdc.com>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>
Subject: Re: [PATCH] RISC-V: Add an Image header that boot loader can parse.
Date: Wed, 1 May 2019 21:54:43 +0200	[thread overview]
Message-ID: <20190501195443.trgjv6tujctsw5sw@excalibur.cnev.de> (raw)
In-Reply-To: <CAAhSdy2OuCb6wBrs-O=fTWo0D_CgwTztfV-kMDi=tPmSJhM7og@mail.gmail.com>

On Wed, May 01, 2019 at 10:41:52PM +0530, Anup Patel wrote:
> On Wed, May 1, 2019 at 10:30 PM Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Apr 29, 2019 at 10:42:40PM -0700, Atish Patra wrote:
> > > On 4/29/19 4:40 PM, Palmer Dabbelt wrote:
> > > > On Tue, 23 Apr 2019 16:25:06 PDT (-0700), atish.patra@wdc.com wrote:
> > > > > Currently, last stage boot loaders such as U-Boot can accept only
> > > > > uImage which is an unnecessary additional step in automating boot flows.
> > > > >
> > > > > Add a simple image header that boot loaders can parse and directly
> > > > > load kernel flat Image. The existing booting methods will continue to
> > > > > work as it is.
> > > > >
> > > > > Tested on both QEMU and HiFive Unleashed using OpenSBI + U-Boot + Linux.
> > > > >
> > > > > Signed-off-by: Atish Patra <atish.patra@wdc.com>
> > > > > ---
> > > > >   arch/riscv/include/asm/image.h | 32 ++++++++++++++++++++++++++++++++
> > > > >   arch/riscv/kernel/head.S       | 28 ++++++++++++++++++++++++++++
> > > > >   2 files changed, 60 insertions(+)
> > > > >   create mode 100644 arch/riscv/include/asm/image.h
> > > > >
> > > > > diff --git a/arch/riscv/include/asm/image.h b/arch/riscv/include/asm/image.h
> > > > > new file mode 100644
> > > > > index 000000000000..76a7e0d4068a
> > > > > --- /dev/null
> > > > > +++ b/arch/riscv/include/asm/image.h
> > > > > @@ -0,0 +1,32 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > +
> > > > > +#ifndef __ASM_IMAGE_H
> > > > > +#define __ASM_IMAGE_H
> > > > > +
> > > > > +#define RISCV_IMAGE_MAGIC        "RISCV"
> > > > > +
> > > > > +#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
> > > > > + * @reserved:            reserved
> > > > > + * @magic:               Magic number
> > > > > + * @reserved:            reserved
> > > > > + */
> > > > > +
> > > > > +struct riscv_image_header {
> > > > > + u32 code0;
> > > > > + u32 code1;
> > > > > + u64 text_offset;
> > > > > + u64 image_size;
> > > > > + u64 res1;
> > > > > + u64 magic;
> > > > > + u32 res2;
> > > > > + u32 res3;
> > > > > +};
> > > >
> > > > I don't want to invent our own file format.  Is there a reason we can't just
> > > > use something standard?  Off the top of my head I can think of ELF files and
> > > > multiboot.
> > >
> > > Additional header is required to accommodate PE header format. Currently,
> > > this is only used for booti command but it will be reused for EFI headers as
> > > well. Linux kernel Image can pretend as an EFI application if PE/COFF header
> > > is present. This removes the need of an explicit EFI boot loader and EFI
> > > firmware can directly load Linux (obviously after EFI stub implementation
> > > for RISC-V).
> >
> > Adding the EFI stub on arm64 required very careful consideration of our
> > Image header and the EFI spec, along with the PE/COFF spec.
> >
> > For example, to be a compliant PE/COFF header, the first two bytes of
> > your kernel image need to be "MZ" in ASCII. On arm64 we happened to find
> > a valid instruction that we could rely upon that met this requirement...
> 
> The "MZ" ASCII (i.e. 0x5a4d) is "li s4,-13" instruction in RISC-V so this
> modifies "s4" register which is pretty harmless from Linux RISC-V booting
> perspective.
> 
> Of course, we should only add "MZ" ASCII in Linux RISC-V image header
> when CONFIG_EFI is enabled (just like Linux ARM64).

Probably I'm missing something obvious, but I cannot completely
follow you here. My understanding is as follows:

The kernel gets executed by jumping to the _start label, where it
currently immediately starts with setting up everything (mask
interrupts, disable FPU, etc).  Now we insert a structure before
the actual init code where the first 64 bits of the structure
(the code0 and code1 fields) are filled with values that
constitute a valid jump opcode to the actual init code behind the
end of the new structure.

If the first byte in a PE/COFF header has to be an ASCII "M",
that is 01001101 in binary.  RISC-V is little-endian and the last
two bits of the lowest-value byte define the type of instruction. 
According to the chapter "Base Instruction-Length Encoding" in
the RISC-V ISA spec everything except 11 as the lowest bits
denotes a compressed instruction and if I have puzzeled together
the the various instruction bits correctly, ASCII "MZ" would be
excuted as a compressed load immediate to x9/s1, wouldn't it?

If my previous thoughts are correct, this would also mean that
having a PE/COFF-compatible header for EFI boot would make a
kernel image inherently incompatible with performing a non-EFI
boot of the same image on systems that don't implement the C
extension.  As the work-in-progress RISC-V Unix platform spec
will probably mandate C, that probably won't be much of a
practical problem, though.

Regards,
Karsten
-- 
Ich widerspreche hiermit ausdrücklich der Nutzung sowie der
Weitergabe meiner personenbezogenen Daten für Zwecke der Werbung
sowie der Markt- oder Meinungsforschung.

WARNING: multiple messages have this Message-ID (diff)
From: Karsten Merker <merker@debian.org>
To: Anup Patel <anup@brainfault.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	"aou@eecs.berkeley.edu" <aou@eecs.berkeley.edu>,
	Palmer Dabbelt <palmer@sifive.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"zong@andestech.com" <zong@andestech.com>,
	Atish Patra <atish.patra@wdc.com>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>
Subject: Re: [PATCH] RISC-V: Add an Image header that boot loader can parse.
Date: Wed, 1 May 2019 21:54:43 +0200	[thread overview]
Message-ID: <20190501195443.trgjv6tujctsw5sw@excalibur.cnev.de> (raw)
In-Reply-To: <CAAhSdy2OuCb6wBrs-O=fTWo0D_CgwTztfV-kMDi=tPmSJhM7og@mail.gmail.com>

On Wed, May 01, 2019 at 10:41:52PM +0530, Anup Patel wrote:
> On Wed, May 1, 2019 at 10:30 PM Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Apr 29, 2019 at 10:42:40PM -0700, Atish Patra wrote:
> > > On 4/29/19 4:40 PM, Palmer Dabbelt wrote:
> > > > On Tue, 23 Apr 2019 16:25:06 PDT (-0700), atish.patra@wdc.com wrote:
> > > > > Currently, last stage boot loaders such as U-Boot can accept only
> > > > > uImage which is an unnecessary additional step in automating boot flows.
> > > > >
> > > > > Add a simple image header that boot loaders can parse and directly
> > > > > load kernel flat Image. The existing booting methods will continue to
> > > > > work as it is.
> > > > >
> > > > > Tested on both QEMU and HiFive Unleashed using OpenSBI + U-Boot + Linux.
> > > > >
> > > > > Signed-off-by: Atish Patra <atish.patra@wdc.com>
> > > > > ---
> > > > >   arch/riscv/include/asm/image.h | 32 ++++++++++++++++++++++++++++++++
> > > > >   arch/riscv/kernel/head.S       | 28 ++++++++++++++++++++++++++++
> > > > >   2 files changed, 60 insertions(+)
> > > > >   create mode 100644 arch/riscv/include/asm/image.h
> > > > >
> > > > > diff --git a/arch/riscv/include/asm/image.h b/arch/riscv/include/asm/image.h
> > > > > new file mode 100644
> > > > > index 000000000000..76a7e0d4068a
> > > > > --- /dev/null
> > > > > +++ b/arch/riscv/include/asm/image.h
> > > > > @@ -0,0 +1,32 @@
> > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > +
> > > > > +#ifndef __ASM_IMAGE_H
> > > > > +#define __ASM_IMAGE_H
> > > > > +
> > > > > +#define RISCV_IMAGE_MAGIC        "RISCV"
> > > > > +
> > > > > +#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
> > > > > + * @reserved:            reserved
> > > > > + * @magic:               Magic number
> > > > > + * @reserved:            reserved
> > > > > + */
> > > > > +
> > > > > +struct riscv_image_header {
> > > > > + u32 code0;
> > > > > + u32 code1;
> > > > > + u64 text_offset;
> > > > > + u64 image_size;
> > > > > + u64 res1;
> > > > > + u64 magic;
> > > > > + u32 res2;
> > > > > + u32 res3;
> > > > > +};
> > > >
> > > > I don't want to invent our own file format.  Is there a reason we can't just
> > > > use something standard?  Off the top of my head I can think of ELF files and
> > > > multiboot.
> > >
> > > Additional header is required to accommodate PE header format. Currently,
> > > this is only used for booti command but it will be reused for EFI headers as
> > > well. Linux kernel Image can pretend as an EFI application if PE/COFF header
> > > is present. This removes the need of an explicit EFI boot loader and EFI
> > > firmware can directly load Linux (obviously after EFI stub implementation
> > > for RISC-V).
> >
> > Adding the EFI stub on arm64 required very careful consideration of our
> > Image header and the EFI spec, along with the PE/COFF spec.
> >
> > For example, to be a compliant PE/COFF header, the first two bytes of
> > your kernel image need to be "MZ" in ASCII. On arm64 we happened to find
> > a valid instruction that we could rely upon that met this requirement...
> 
> The "MZ" ASCII (i.e. 0x5a4d) is "li s4,-13" instruction in RISC-V so this
> modifies "s4" register which is pretty harmless from Linux RISC-V booting
> perspective.
> 
> Of course, we should only add "MZ" ASCII in Linux RISC-V image header
> when CONFIG_EFI is enabled (just like Linux ARM64).

Probably I'm missing something obvious, but I cannot completely
follow you here. My understanding is as follows:

The kernel gets executed by jumping to the _start label, where it
currently immediately starts with setting up everything (mask
interrupts, disable FPU, etc).  Now we insert a structure before
the actual init code where the first 64 bits of the structure
(the code0 and code1 fields) are filled with values that
constitute a valid jump opcode to the actual init code behind the
end of the new structure.

If the first byte in a PE/COFF header has to be an ASCII "M",
that is 01001101 in binary.  RISC-V is little-endian and the last
two bits of the lowest-value byte define the type of instruction. 
According to the chapter "Base Instruction-Length Encoding" in
the RISC-V ISA spec everything except 11 as the lowest bits
denotes a compressed instruction and if I have puzzeled together
the the various instruction bits correctly, ASCII "MZ" would be
excuted as a compressed load immediate to x9/s1, wouldn't it?

If my previous thoughts are correct, this would also mean that
having a PE/COFF-compatible header for EFI boot would make a
kernel image inherently incompatible with performing a non-EFI
boot of the same image on systems that don't implement the C
extension.  As the work-in-progress RISC-V Unix platform spec
will probably mandate C, that probably won't be much of a
practical problem, though.

Regards,
Karsten
-- 
Ich widerspreche hiermit ausdrücklich der Nutzung sowie der
Weitergabe meiner personenbezogenen Daten für Zwecke der Werbung
sowie der Markt- oder Meinungsforschung.

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  parent reply	other threads:[~2019-05-01 19:55 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-23 23:25 [PATCH] RISC-V: Add an Image header that boot loader can parse Atish Patra
2019-04-23 23:25 ` Atish Patra
2019-04-29 23:40 ` Palmer Dabbelt
2019-04-29 23:40   ` Palmer Dabbelt
2019-04-30  5:42   ` Atish Patra
2019-04-30  5:42     ` Atish Patra
2019-05-01 16:43     ` Karsten Merker
2019-05-01 16:43       ` Karsten Merker
2019-05-01 17:02       ` Anup Patel
2019-05-01 17:02         ` Anup Patel
2019-05-01 17:32         ` Atish Patra
2019-05-01 17:32           ` Atish Patra
2019-05-01 17:00     ` Mark Rutland
2019-05-01 17:00       ` Mark Rutland
2019-05-01 17:11       ` Anup Patel
2019-05-01 17:11         ` Anup Patel
2019-05-01 17:35         ` Mark Rutland
2019-05-01 17:35           ` Mark Rutland
2019-05-01 19:54         ` Karsten Merker [this message]
2019-05-01 19:54           ` Karsten Merker
2019-05-01 20:32           ` Karsten Merker
2019-05-01 20:32             ` Karsten Merker

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=20190501195443.trgjv6tujctsw5sw@excalibur.cnev.de \
    --to=merker@debian.org \
    --cc=anup@brainfault.org \
    --cc=aou@eecs.berkeley.edu \
    --cc=atish.patra@wdc.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=palmer@sifive.com \
    --cc=zong@andestech.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.