diff mbox

[U-Boot,19/19] imx: ventana: config: enable Falcon mode

Message ID 1431134922-2535-20-git-send-email-tharvey@gateworks.com
State Awaiting Upstream
Delegated to: Stefano Babic
Headers show

Commit Message

Tim Harvey May 9, 2015, 1:28 a.m. UTC
Falcon mode entails the SPL booting the OS directly instead of U-Boot.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/gw_ventana_spl.c | 20 ++++++++++++++++++++
 include/configs/gw_ventana.h                | 16 ++++++++++++++++
 2 files changed, 36 insertions(+)

Comments

Fabio Estevam May 18, 2015, 11:25 p.m. UTC | #1
Hi Tim,

On Fri, May 8, 2015 at 10:28 PM, Tim Harvey <tharvey@gateworks.com> wrote:
> Falcon mode entails the SPL booting the OS directly instead of U-Boot.

I would like to give this a try, but I am not sure where the dtb
should be placed in the SD card.

Or are you combining the dtb and zImage into a single binary?

Do you have a small README that shows how the user should use Falcon mode?

Thanks!
Tim Harvey May 19, 2015, 1:26 p.m. UTC | #2
On Mon, May 18, 2015 at 4:25 PM, Fabio Estevam <festevam@gmail.com> wrote:
> Hi Tim,
>
> On Fri, May 8, 2015 at 10:28 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>> Falcon mode entails the SPL booting the OS directly instead of U-Boot.
>
> I would like to give this a try, but I am not sure where the dtb
> should be placed in the SD card.
>
> Or are you combining the dtb and zImage into a single binary?
>
> Do you have a small README that shows how the user should use Falcon mode?
>
> Thanks!

Fabio,

I will be posting a README in the next day or so to document Falcon
mode usage on the Gateworks Ventana boards. In general the
documentation will be the same for any board using it but I'll provide
some detail about where things are stored in flash/mmc and what
#defines control that.

As a general rule though, when using Falcon mode for a device-tree
kernel the dtb must get loaded and processed via the 'spl export fdt'
command which you provide the kernel and dtb address in RAM you've
loaded them to because U-Boot will tweak the dtb then allow you to
store it back.

This is documented pretty well currently in doc/README.falcon. You
have to understand that the steps normally taken by U-Boot will be
skipped in Falcon mode as you go straight from SPL to OS. In the
general case this means your SPL must do anything that U-Boot
typically does for fixups including GPIO configuration (pinmux,
padctl, output/direction) for things the kernel may not be supporting
(hence my recent patches that move or replicate some of Ventana U-Boot
capability in the SPL). For the Linux OS case the SPL must do what the
bootm U-Boot command would have done which is to load the dtb, make
adjustments (enet macs, mtdparts, memsize, console args, anything in
ft_board_setup(), etc) and it does this by using the spl export
command which goes through all the steps that bootm does 'except' for
jumping to the kernel. Then you take the mem area that spl export left
the 'args' typically passed to the kernel and store that to your
non-volatile storage so that when the SPL boots in 'OS mode' it loads
the kernel, loads the pre-prepared args and jumps.

Note that Falcon mode also requires you have a function in the SPL
that decides to boot U-Boot or to skip it and boot the OS directly. In
the Gateworks Ventana case I didn't want to make this completely
dependent on a GPIO/Button because this bootloader supports about 8
different PCB designs in the Ventana family - some of which do not
have buttons or may not have buttons loaded on the board. Instead, I
pulled env support into the SPL and use 'boot_os' env var to decide as
other boards do (see spl_start_uboot()). I also have the Ventana
config build in support for both NAND and MMC so that in general the
same SPL/U-Boot can be used on Ventana boards with or without NAND.
U-Boot however currently does not support multiple environment backing
stores, so only NAND env is defined meaning Falcon mode for Ventana on
a nand-less board won't really work right as it will try to read env
from NAND. I have a downstream patch that adds multiple env support
which reads env from whatever the boot device was, however I have not
posted this patch yet and I don't expect it will be accepted because
it was desired for me to re-write env support instead which was a
large undertaking I don't have time for. Until then, mainline U-Boot
only supports Falcon mode on NAND for Ventana (which is the vast
majority of the Ventana boards).

Regards,

Tim
Fabio Estevam May 19, 2015, 1:30 p.m. UTC | #3
Hi Tim,

On Tue, May 19, 2015 at 10:26 AM, Tim Harvey <tharvey@gateworks.com> wrote:

> Fabio,
>
> I will be posting a README in the next day or so to document Falcon
> mode usage on the Gateworks Ventana boards. In general the
> documentation will be the same for any board using it but I'll provide
> some detail about where things are stored in flash/mmc and what
> #defines control that.
>
> As a general rule though, when using Falcon mode for a device-tree
> kernel the dtb must get loaded and processed via the 'spl export fdt'
> command which you provide the kernel and dtb address in RAM you've
> loaded them to because U-Boot will tweak the dtb then allow you to
> store it back.
>
> This is documented pretty well currently in doc/README.falcon. You
> have to understand that the steps normally taken by U-Boot will be
> skipped in Falcon mode as you go straight from SPL to OS. In the
> general case this means your SPL must do anything that U-Boot
> typically does for fixups including GPIO configuration (pinmux,
> padctl, output/direction) for things the kernel may not be supporting
> (hence my recent patches that move or replicate some of Ventana U-Boot
> capability in the SPL). For the Linux OS case the SPL must do what the
> bootm U-Boot command would have done which is to load the dtb, make
> adjustments (enet macs, mtdparts, memsize, console args, anything in
> ft_board_setup(), etc) and it does this by using the spl export
> command which goes through all the steps that bootm does 'except' for
> jumping to the kernel. Then you take the mem area that spl export left
> the 'args' typically passed to the kernel and store that to your
> non-volatile storage so that when the SPL boots in 'OS mode' it loads
> the kernel, loads the pre-prepared args and jumps.
>
> Note that Falcon mode also requires you have a function in the SPL
> that decides to boot U-Boot or to skip it and boot the OS directly. In
> the Gateworks Ventana case I didn't want to make this completely
> dependent on a GPIO/Button because this bootloader supports about 8
> different PCB designs in the Ventana family - some of which do not
> have buttons or may not have buttons loaded on the board. Instead, I
> pulled env support into the SPL and use 'boot_os' env var to decide as
> other boards do (see spl_start_uboot()). I also have the Ventana
> config build in support for both NAND and MMC so that in general the
> same SPL/U-Boot can be used on Ventana boards with or without NAND.
> U-Boot however currently does not support multiple environment backing
> stores, so only NAND env is defined meaning Falcon mode for Ventana on
> a nand-less board won't really work right as it will try to read env
> from NAND. I have a downstream patch that adds multiple env support
> which reads env from whatever the boot device was, however I have not
> posted this patch yet and I don't expect it will be accepted because
> it was desired for me to re-write env support instead which was a
> large undertaking I don't have time for. Until then, mainline U-Boot
> only supports Falcon mode on NAND for Ventana (which is the vast
> majority of the Ventana boards).

Thanks for your work on this and for your detailed reply! I will give
Falcon mode a try.

Thanks,

Fabio Estevam
Stefano Babic May 21, 2015, 4:17 p.m. UTC | #4
Hi Tim,

On 19/05/2015 15:26, Tim Harvey wrote:

> Note that Falcon mode also requires you have a function in the SPL
> that decides to boot U-Boot or to skip it and boot the OS directly. In
> the Gateworks Ventana case I didn't want to make this completely
> dependent on a GPIO/Button because this bootloader supports about 8
> different PCB designs in the Ventana family - some of which do not
> have buttons or may not have buttons loaded on the board. Instead, I
> pulled env support into the SPL and use 'boot_os' env var to decide as
> other boards do (see spl_start_uboot()).

Anyway, this can be dangerous. The reason having a GPIO (or any trigger
from external, for example a received char from the console) is to
switch to U-Boot if the kernel does not work (but the kernel image is
not corrupted), mainly go to panic, and the board can be restored into
U-Boot.

If you use an environment variable and the environment is put into the
NAND (with MMC you can change the card), there is nothing you can do
anymore. Board tries to boot until next panic, and then again and again.

Best regards,
Stefano Babic
Stefan Roese May 21, 2015, 4:46 p.m. UTC | #5
Hi Stefano,

On 21.05.2015 18:17, Stefano Babic wrote:
> On 19/05/2015 15:26, Tim Harvey wrote:
>
>> Note that Falcon mode also requires you have a function in the SPL
>> that decides to boot U-Boot or to skip it and boot the OS directly. In
>> the Gateworks Ventana case I didn't want to make this completely
>> dependent on a GPIO/Button because this bootloader supports about 8
>> different PCB designs in the Ventana family - some of which do not
>> have buttons or may not have buttons loaded on the board. Instead, I
>> pulled env support into the SPL and use 'boot_os' env var to decide as
>> other boards do (see spl_start_uboot()).
>
> Anyway, this can be dangerous. The reason having a GPIO (or any trigger
> from external, for example a received char from the console) is to
> switch to U-Boot if the kernel does not work (but the kernel image is
> not corrupted), mainly go to panic, and the board can be restored into
> U-Boot.
>
> If you use an environment variable and the environment is put into the
> NAND (with MMC you can change the card), there is nothing you can do
> anymore. Board tries to boot until next panic, and then again and again.

Some boards just don't have such a means as a push button or jumper to 
select the Falcon mode. That's why I introduced this environment 
variable dependent way to select Falcon mode quite some time ago for a 
PPC based board.

You are correct. If something goes completely wrong, and the board tries 
to boot into the OS with a non-working OS installed, then you are 
doomed. JTAG comes in handy then as I have experienced myself. ;)

But this is usually only while developing this feature and kernel. Once 
its tested and mature, this really works.

Again, its a trade-off since another, better method to switch between 
U-Boot- and OS- booting is not available.

Thanks,
Stefan
Stefano Babic May 21, 2015, 5:06 p.m. UTC | #6
Hi Stefan,

On 21/05/2015 18:46, Stefan Roese wrote:

>> If you use an environment variable and the environment is put into the
>> NAND (with MMC you can change the card), there is nothing you can do
>> anymore. Board tries to boot until next panic, and then again and again.
> 
> Some boards just don't have such a means as a push button or jumper to
> select the Falcon mode. That's why I introduced this environment
> variable dependent way to select Falcon mode quite some time ago for a
> PPC based board.
> 
> You are correct. If something goes completely wrong, and the board tries
> to boot into the OS with a non-working OS installed, then you are
> doomed. JTAG comes in handy then as I have experienced myself. ;)

Right

> 
> But this is usually only while developing this feature and kernel. Once
> its tested and mature, this really works.

Yes, when the product is delivered to the customer, this does not
matter. But we should be aware of it, and know that something can go wrong.

> 
> Again, its a trade-off since another, better method to switch between
> U-Boot- and OS- booting is not available.

Exactly - anyway, patch is applied and I run build again on imx board.
Repository will be updated soon.

Best regards,
Stefano
Tim Harvey May 21, 2015, 5:07 p.m. UTC | #7
On Thu, May 21, 2015 at 9:46 AM, Stefan Roese <sr@denx.de> wrote:
> Hi Stefano,
>
> On 21.05.2015 18:17, Stefano Babic wrote:
>>
>> On 19/05/2015 15:26, Tim Harvey wrote:
>>
>>> Note that Falcon mode also requires you have a function in the SPL
>>> that decides to boot U-Boot or to skip it and boot the OS directly. In
>>> the Gateworks Ventana case I didn't want to make this completely
>>> dependent on a GPIO/Button because this bootloader supports about 8
>>> different PCB designs in the Ventana family - some of which do not
>>> have buttons or may not have buttons loaded on the board. Instead, I
>>> pulled env support into the SPL and use 'boot_os' env var to decide as
>>> other boards do (see spl_start_uboot()).
>>
>>
>> Anyway, this can be dangerous. The reason having a GPIO (or any trigger
>> from external, for example a received char from the console) is to
>> switch to U-Boot if the kernel does not work (but the kernel image is
>> not corrupted), mainly go to panic, and the board can be restored into
>> U-Boot.
>>
>> If you use an environment variable and the environment is put into the
>> NAND (with MMC you can change the card), there is nothing you can do
>> anymore. Board tries to boot until next panic, and then again and again.
>
>
> Some boards just don't have such a means as a push button or jumper to
> select the Falcon mode. That's why I introduced this environment variable
> dependent way to select Falcon mode quite some time ago for a PPC based
> board.
>
> You are correct. If something goes completely wrong, and the board tries to
> boot into the OS with a non-working OS installed, then you are doomed. JTAG
> comes in handy then as I have experienced myself. ;)
>
> But this is usually only while developing this feature and kernel. Once its
> tested and mature, this really works.
>
> Again, its a trade-off since another, better method to switch between
> U-Boot- and OS- booting is not available.
>
> Thanks,
> Stefan
>

Agreed - this is exactly why I decided (at cost) to use an env
variable - not all of our boards have a gpio that makes sense and I am
am focusing on flexibility.

Tim
diff mbox

Patch

diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index 0d8ccb6..73b5176 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -14,6 +14,7 @@ 
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/iomux-v3.h>
 #include <asm/imx-common/mxc_i2c.h>
+#include <environment.h>
 #include <spl.h>
 
 #include "gsc.h"
@@ -559,6 +560,25 @@  void spl_board_init(void)
 	setup_pmic();
 }
 
+#ifdef CONFIG_SPL_OS_BOOT
+/* return 1 if we wish to boot to uboot vs os (falcon mode) */
+int spl_start_uboot(void)
+{
+	int ret = 1;
+
+	debug("%s\n", __func__);
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	env_init();
+	env_relocate_spec();
+	debug("boot_os=%s\n", getenv("boot_os"));
+	if (getenv_yesno("boot_os") == 1)
+		ret = 0;
+#endif
+	debug("%s booting %s\n", __func__, ret ? "uboot" : "linux");
+	return ret;
+}
+#endif
+
 void reset_cpu(ulong addr)
 {
 }
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
index ccf01e2..87cb32f 100644
--- a/include/configs/gw_ventana.h
+++ b/include/configs/gw_ventana.h
@@ -19,6 +19,22 @@ 
 /* Location in NAND to read U-Boot from */
 #define CONFIG_SYS_NAND_U_BOOT_OFFS     (14 * SZ_1M)
 
+/* Falcon Mode */
+#define CONFIG_CMD_SPL
+#define CONFIG_SPL_OS_BOOT
+#define CONFIG_SPL_ENV_SUPPORT
+#define CONFIG_SYS_SPL_ARGS_ADDR	0x18000000
+#define CONFIG_CMD_SPL_WRITE_SIZE	(128 * SZ_1K)
+
+/* Falcon Mode - NAND support: args@17MB kernel@18MB */
+#define CONFIG_CMD_SPL_NAND_OFS		(17 * SZ_1M)
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS	(18 * SZ_1M)
+
+/* Falcon Mode - MMC support: args@1MB kernel@2MB */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR	0x800	/* 1MB */
+#define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS	(CONFIG_CMD_SPL_WRITE_SIZE / 512)
+#define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR	0x1000	/* 2MB */
+
 #include "imx6_spl.h"                  /* common IMX6 SPL configuration */
 #include "mx6_common.h"
 #define CONFIG_MX6