diff mbox series

[U-Boot,v3,27/28] riscv: qemu: detect and boot the kernel passed by QEMU

Message ID 20181109125923.7034-28-lukas.auer@aisec.fraunhofer.de
State Superseded
Delegated to: Andes
Headers show
Series General fixes / cleanup for RISC-V and improvements to qemu-riscv | expand

Commit Message

Lukas Auer Nov. 9, 2018, 12:59 p.m. UTC
QEMU embeds the location of the kernel image in the device tree. Store
this address in the environment as variable kernel_start. It is used in
the board-local distro boot command QEMU to boot the kernel with the
U-Boot device tree. The QEMU boot command is added as the first boot
target device.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
---

Changes in v3:
- Adapt code and commit message to distro boot
- Replace printf with debug
- Clarify debug messages if no chosen node is found

Changes in v2:
- Rebase onto u-boot-dm/next
- Boot Linux with the device tree provided by the prior boot stage

 board/emulation/qemu-riscv/Kconfig      |  1 +
 board/emulation/qemu-riscv/qemu-riscv.c | 29 +++++++++++++++++++++++++
 include/configs/qemu-riscv.h            | 10 +++++++++
 3 files changed, 40 insertions(+)

Comments

Bin Meng Nov. 13, 2018, 5:57 a.m. UTC | #1
On Fri, Nov 9, 2018 at 9:00 PM Lukas Auer
<lukas.auer@aisec.fraunhofer.de> wrote:
>
> QEMU embeds the location of the kernel image in the device tree. Store
> this address in the environment as variable kernel_start. It is used in
> the board-local distro boot command QEMU to boot the kernel with the
> U-Boot device tree. The QEMU boot command is added as the first boot
> target device.
>
> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> ---
>
> Changes in v3:
> - Adapt code and commit message to distro boot
> - Replace printf with debug
> - Clarify debug messages if no chosen node is found
>
> Changes in v2:
> - Rebase onto u-boot-dm/next
> - Boot Linux with the device tree provided by the prior boot stage
>
>  board/emulation/qemu-riscv/Kconfig      |  1 +
>  board/emulation/qemu-riscv/qemu-riscv.c | 29 +++++++++++++++++++++++++
>  include/configs/qemu-riscv.h            | 10 +++++++++
>  3 files changed, 40 insertions(+)
>

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Alexander Graf Nov. 13, 2018, 9:01 a.m. UTC | #2
On 09.11.18 13:59, Lukas Auer wrote:
> QEMU embeds the location of the kernel image in the device tree. Store
> this address in the environment as variable kernel_start. It is used in
> the board-local distro boot command QEMU to boot the kernel with the
> U-Boot device tree. The QEMU boot command is added as the first boot
> target device.
> 
> Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>

That is a very elegant solution to the problem :). Awesome. Maybe we
should consider to move to board specific distro targets for things like
the NXP LS legacy flash boot as well?

Reviewed-by: Alexander Graf <agraf@suse.de>


Alex

> ---
> 
> Changes in v3:
> - Adapt code and commit message to distro boot
> - Replace printf with debug
> - Clarify debug messages if no chosen node is found
> 
> Changes in v2:
> - Rebase onto u-boot-dm/next
> - Boot Linux with the device tree provided by the prior boot stage
> 
>  board/emulation/qemu-riscv/Kconfig      |  1 +
>  board/emulation/qemu-riscv/qemu-riscv.c | 29 +++++++++++++++++++++++++
>  include/configs/qemu-riscv.h            | 10 +++++++++
>  3 files changed, 40 insertions(+)
> 
> diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
> index 37a80db6a9..be5839b7db 100644
> --- a/board/emulation/qemu-riscv/Kconfig
> +++ b/board/emulation/qemu-riscv/Kconfig
> @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
>  	imply CMD_EXT2
>  	imply CMD_EXT4
>  	imply CMD_FAT
> +	imply BOARD_LATE_INIT
>  
>  endif
> diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
> index 2ce093e19a..587f2c4909 100644
> --- a/board/emulation/qemu-riscv/qemu-riscv.c
> +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> @@ -19,3 +19,32 @@ int board_init(void)
>  
>  	return 0;
>  }
> +
> +int board_late_init(void)
> +{
> +	ulong kernel_start;
> +	ofnode chosen_node;
> +	int ret;
> +
> +	chosen_node = ofnode_path("/chosen");
> +	if (!ofnode_valid(chosen_node)) {
> +		debug("No chosen node found, can't get kernel start address\n");
> +		return 0;
> +	}
> +
> +#ifdef CONFIG_ARCH_RV64I
> +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> +			      (u64 *)&kernel_start);
> +#else
> +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> +			      (u32 *)&kernel_start);
> +#endif
> +	if (ret) {
> +		debug("Can't find kernel start address in device tree\n");
> +		return 0;
> +	}
> +
> +	env_set_hex("kernel_start", kernel_start);
> +
> +	return 0;
> +}
> diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
> index 66d61bd896..b29d155d09 100644
> --- a/include/configs/qemu-riscv.h
> +++ b/include/configs/qemu-riscv.h
> @@ -21,11 +21,21 @@
>  #define CONFIG_ENV_SIZE			SZ_4K
>  
>  #define BOOT_TARGET_DEVICES(func) \
> +	func(QEMU, qemu, na) \
>  	func(VIRTIO, virtio, 0) \
>  	func(DHCP, dhcp, na)
>  
>  #include <config_distro_bootcmd.h>
>  
> +#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \
> +	"bootcmd_qemu=" \
> +		"if env exists kernel_start; then " \
> +			"bootm ${kernel_start} - ${fdtcontroladdr};" \
> +		"fi;\0"
> +
> +#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \
> +	"qemu "
> +
>  #define CONFIG_EXTRA_ENV_SETTINGS \
>  	"fdt_high=0xffffffffffffffff\0" \
>  	"initrd_high=0xffffffffffffffff\0" \
>
Lukas Auer Nov. 13, 2018, 10 p.m. UTC | #3
On Tue, 2018-11-13 at 10:01 +0100, Alexander Graf wrote:
> 
> On 09.11.18 13:59, Lukas Auer wrote:
> > QEMU embeds the location of the kernel image in the device tree.
> > Store
> > this address in the environment as variable kernel_start. It is
> > used in
> > the board-local distro boot command QEMU to boot the kernel with
> > the
> > U-Boot device tree. The QEMU boot command is added as the first
> > boot
> > target device.
> > 
> > Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
> 
> That is a very elegant solution to the problem :). Awesome. Maybe we
> should consider to move to board specific distro targets for things
> like
> the NXP LS legacy flash boot as well?
> 

Thank you! I am not the only one using board-specific boot commands
however, I saw it used on sunxi with the FEL boot command. :)
Yes, I think that would make sense, even if it is just to move shared
targets into a common file and make them more reusable. There seems to
also be a lot of code duplication from config_distro_common.h in the
NXP LS board files, which can probably be removed.

Lukas

> Reviewed-by: Alexander Graf <agraf@suse.de>
> 
> 
> Alex
> 
> > ---
> > 
> > Changes in v3:
> > - Adapt code and commit message to distro boot
> > - Replace printf with debug
> > - Clarify debug messages if no chosen node is found
> > 
> > Changes in v2:
> > - Rebase onto u-boot-dm/next
> > - Boot Linux with the device tree provided by the prior boot stage
> > 
> >  board/emulation/qemu-riscv/Kconfig      |  1 +
> >  board/emulation/qemu-riscv/qemu-riscv.c | 29
> > +++++++++++++++++++++++++
> >  include/configs/qemu-riscv.h            | 10 +++++++++
> >  3 files changed, 40 insertions(+)
> > 
> > diff --git a/board/emulation/qemu-riscv/Kconfig
> > b/board/emulation/qemu-riscv/Kconfig
> > index 37a80db6a9..be5839b7db 100644
> > --- a/board/emulation/qemu-riscv/Kconfig
> > +++ b/board/emulation/qemu-riscv/Kconfig
> > @@ -29,5 +29,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> >  	imply CMD_EXT2
> >  	imply CMD_EXT4
> >  	imply CMD_FAT
> > +	imply BOARD_LATE_INIT
> >  
> >  endif
> > diff --git a/board/emulation/qemu-riscv/qemu-riscv.c
> > b/board/emulation/qemu-riscv/qemu-riscv.c
> > index 2ce093e19a..587f2c4909 100644
> > --- a/board/emulation/qemu-riscv/qemu-riscv.c
> > +++ b/board/emulation/qemu-riscv/qemu-riscv.c
> > @@ -19,3 +19,32 @@ int board_init(void)
> >  
> >  	return 0;
> >  }
> > +
> > +int board_late_init(void)
> > +{
> > +	ulong kernel_start;
> > +	ofnode chosen_node;
> > +	int ret;
> > +
> > +	chosen_node = ofnode_path("/chosen");
> > +	if (!ofnode_valid(chosen_node)) {
> > +		debug("No chosen node found, can't get kernel start
> > address\n");
> > +		return 0;
> > +	}
> > +
> > +#ifdef CONFIG_ARCH_RV64I
> > +	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
> > +			      (u64 *)&kernel_start);
> > +#else
> > +	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
> > +			      (u32 *)&kernel_start);
> > +#endif
> > +	if (ret) {
> > +		debug("Can't find kernel start address in device
> > tree\n");
> > +		return 0;
> > +	}
> > +
> > +	env_set_hex("kernel_start", kernel_start);
> > +
> > +	return 0;
> > +}
> > diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-
> > riscv.h
> > index 66d61bd896..b29d155d09 100644
> > --- a/include/configs/qemu-riscv.h
> > +++ b/include/configs/qemu-riscv.h
> > @@ -21,11 +21,21 @@
> >  #define CONFIG_ENV_SIZE			SZ_4K
> >  
> >  #define BOOT_TARGET_DEVICES(func) \
> > +	func(QEMU, qemu, na) \
> >  	func(VIRTIO, virtio, 0) \
> >  	func(DHCP, dhcp, na)
> >  
> >  #include <config_distro_bootcmd.h>
> >  
> > +#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \
> > +	"bootcmd_qemu=" \
> > +		"if env exists kernel_start; then " \
> > +			"bootm ${kernel_start} - ${fdtcontroladdr};" \
> > +		"fi;\0"
> > +
> > +#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \
> > +	"qemu "
> > +
> >  #define CONFIG_EXTRA_ENV_SETTINGS \
> >  	"fdt_high=0xffffffffffffffff\0" \
> >  	"initrd_high=0xffffffffffffffff\0" \
> >
diff mbox series

Patch

diff --git a/board/emulation/qemu-riscv/Kconfig b/board/emulation/qemu-riscv/Kconfig
index 37a80db6a9..be5839b7db 100644
--- a/board/emulation/qemu-riscv/Kconfig
+++ b/board/emulation/qemu-riscv/Kconfig
@@ -29,5 +29,6 @@  config BOARD_SPECIFIC_OPTIONS # dummy
 	imply CMD_EXT2
 	imply CMD_EXT4
 	imply CMD_FAT
+	imply BOARD_LATE_INIT
 
 endif
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 2ce093e19a..587f2c4909 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -19,3 +19,32 @@  int board_init(void)
 
 	return 0;
 }
+
+int board_late_init(void)
+{
+	ulong kernel_start;
+	ofnode chosen_node;
+	int ret;
+
+	chosen_node = ofnode_path("/chosen");
+	if (!ofnode_valid(chosen_node)) {
+		debug("No chosen node found, can't get kernel start address\n");
+		return 0;
+	}
+
+#ifdef CONFIG_ARCH_RV64I
+	ret = ofnode_read_u64(chosen_node, "riscv,kernel-start",
+			      (u64 *)&kernel_start);
+#else
+	ret = ofnode_read_u32(chosen_node, "riscv,kernel-start",
+			      (u32 *)&kernel_start);
+#endif
+	if (ret) {
+		debug("Can't find kernel start address in device tree\n");
+		return 0;
+	}
+
+	env_set_hex("kernel_start", kernel_start);
+
+	return 0;
+}
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index 66d61bd896..b29d155d09 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -21,11 +21,21 @@ 
 #define CONFIG_ENV_SIZE			SZ_4K
 
 #define BOOT_TARGET_DEVICES(func) \
+	func(QEMU, qemu, na) \
 	func(VIRTIO, virtio, 0) \
 	func(DHCP, dhcp, na)
 
 #include <config_distro_bootcmd.h>
 
+#define BOOTENV_DEV_QEMU(devtypeu, devtypel, instance) \
+	"bootcmd_qemu=" \
+		"if env exists kernel_start; then " \
+			"bootm ${kernel_start} - ${fdtcontroladdr};" \
+		"fi;\0"
+
+#define BOOTENV_DEV_NAME_QEMU(devtypeu, devtypel, instance) \
+	"qemu "
+
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"fdt_high=0xffffffffffffffff\0" \
 	"initrd_high=0xffffffffffffffff\0" \