diff mbox

[U-Boot,02/14] arm: Optionally use existing atags in bootm.c

Message ID 1327415291-13260-3-git-send-email-pali.rohar@gmail.com
State Changes Requested, archived
Headers show

Commit Message

Pali Rohár Jan. 24, 2012, 2:27 p.m. UTC
This patch adapts the bootm command so that it can use an existing atags command
set up by a previous bootloader. If the environment variable "atagaddr" is unset,
bootm behaves as normal. If "atagaddr" is set, bootm will use atags address from
environment variable and also append new boot args (if specified in u-boot). For
example, if a previous boot loader already set up the atags struct at 0x80000100:

setenv atagaddr 0x80000100; bootm 0x80008000

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
Changes since original version:
   - Added info to README file
   - Added local define CONFIG_SETUP_ANY_TAG
   - Fixed compile warning
   - Fixed commit message
   - Check if atagaddr is not NULL

 README               |    2 ++
 arch/arm/lib/bootm.c |   39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 34 insertions(+), 7 deletions(-)

Comments

Marek Vasut Jan. 25, 2012, 6:02 p.m. UTC | #1
> This patch adapts the bootm command so that it can use an existing atags
> command set up by a previous bootloader.

Why do you need it?

> If the environment variable
> "atagaddr" is unset, bootm behaves as normal. If "atagaddr" is set, bootm
> will use atags address from environment variable and also append new boot
> args (if specified in u-boot). For example, if a previous boot loader
> already set up the atags struct at 0x80000100:
> 
> setenv atagaddr 0x80000100; bootm 0x80008000

Can't you set those atags correctly in uboot?

M
> 
> Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
> ---
> Changes since original version:
>    - Added info to README file
>    - Added local define CONFIG_SETUP_ANY_TAG
>    - Fixed compile warning
>    - Fixed commit message
>    - Check if atagaddr is not NULL
> 
>  README               |    2 ++
>  arch/arm/lib/bootm.c |   39 ++++++++++++++++++++++++++++++++-------
>  2 files changed, 34 insertions(+), 7 deletions(-)
> 
> diff --git a/README b/README
> index 9d713e8..8c3b98a 100644
> --- a/README
> +++ b/README
> @@ -3584,6 +3584,8 @@ Some configuration options can be set using
> Environment Variables.
> 
>  List of environment variables (most likely not complete):
> 
> +  atagaddr	- bootm will use ATAGs struct from specified address (arm only)
> +
>    baudrate	- see CONFIG_BAUDRATE
> 
>    bootdelay	- see CONFIG_BOOTDELAY
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index afa0093..8366dd5 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -93,6 +93,14 @@ static void announce_and_cleanup(void)
>  	cleanup_before_linux();
>  }
> 
> +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
> +defined(CONFIG_CMDLINE_TAG) || \
> +defined(CONFIG_INITRD_TAG) || \
> +defined(CONFIG_SERIAL_TAG) || \
> +defined(CONFIG_REVISION_TAG)
> +#define CONFIG_SETUP_ANY_TAG
> +#endif
> +
>  int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t
> *images) {
>  	bd_t	*bd = gd->bd;
> @@ -125,12 +133,22 @@ int do_bootm_linux(int flag, int argc, char *argv[],
> bootm_headers_t *images) debug ("## Transferring control to Linux (at
> address %08lx) ...\n", (ulong) kernel_entry);
> 
> -#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
> -    defined (CONFIG_CMDLINE_TAG) || \
> -    defined (CONFIG_INITRD_TAG) || \
> -    defined (CONFIG_SERIAL_TAG) || \
> -    defined (CONFIG_REVISION_TAG)
> -	setup_start_tag (bd);
> +	s = getenv("atagaddr");
> +	if (s)
> +		bd->bi_boot_params = simple_strtoul(s, NULL, 16);
> +
> +	if (bd->bi_boot_params) {
> +		printf("Using existing atags at %#lx\n", bd->bi_boot_params);
> +
> +		params = (struct tag *) bd->bi_boot_params;
> +		while (params->hdr.size > 0)
> +			params = tag_next(params);
> +	} else {
> +#ifdef CONFIG_SETUP_ANY_TAG
> +		setup_start_tag(bd);
> +#endif
> +	}
> +
>  #ifdef CONFIG_SERIAL_TAG
>  	setup_serial_tag (&params);
>  #endif
> @@ -147,8 +165,15 @@ int do_bootm_linux(int flag, int argc, char *argv[],
> bootm_headers_t *images) if (images->rd_start && images->rd_end)
>  		setup_initrd_tag (bd, images->rd_start, images->rd_end);
>  #endif
> -	setup_end_tag(bd);
> +
> +	if (s) {
> +		if (params->hdr.size > 0)
> +			setup_end_tag(bd);
> +	} else {
> +#ifdef CONFIG_SETUP_ANY_TAG
> +		setup_end_tag(bd);
>  #endif
> +	}
> 
>  	announce_and_cleanup();
Pali Rohár Jan. 25, 2012, 7:17 p.m. UTC | #2
On Wednesday 25 January 2012 19:02:45 Marek Vasut wrote:
> > This patch adapts the bootm command so that it can use an existing atags
> > command set up by a previous bootloader.
> 
> Why do you need it?

Default Nokia kernel has patches which using non-standard atags for reporting 
bootmode, bootreason, hw-rev, NOLO version, boot count, ...

Closed-source Maemo application need to know these properties (read via 
/proc/bootreason, ...) and will restart device if there is error.

So U-Boot must can reuse old atags from NOLO and tell it new kernel.

> 
> > If the environment variable
> > "atagaddr" is unset, bootm behaves as normal. If "atagaddr" is set, bootm
> > will use atags address from environment variable and also append new boot
> > args (if specified in u-boot). For example, if a previous boot loader
> > already set up the atags struct at 0x80000100:
> > 
> > setenv atagaddr 0x80000100; bootm 0x80008000
> 
> Can't you set those atags correctly in uboot?
> 

No, because atags are not static (e.g bootreason).
Marek Vasut Jan. 25, 2012, 8:55 p.m. UTC | #3
> On Wednesday 25 January 2012 19:02:45 Marek Vasut wrote:
> > > This patch adapts the bootm command so that it can use an existing
> > > atags command set up by a previous bootloader.
> > 
> > Why do you need it?
> 
> Default Nokia kernel has patches which using non-standard atags for
> reporting bootmode, bootreason, hw-rev, NOLO version, boot count, ...

So what? Make u-boot pass arbitrary atags and specify them in your board file.

> 
> Closed-source Maemo application need to know these properties (read via
> /proc/bootreason, ...) and will restart device if there is error.

Fine?
> 
> So U-Boot must can reuse old atags from NOLO and tell it new kernel.

must can reuse? Anyway, that's nonsense, why won't u-boot be able to craft those 
atags?

> 
> > > If the environment variable
> > > "atagaddr" is unset, bootm behaves as normal. If "atagaddr" is set,
> > > bootm will use atags address from environment variable and also append
> > > new boot args (if specified in u-boot). For example, if a previous
> > > boot loader already set up the atags struct at 0x80000100:
> > > 
> > > setenv atagaddr 0x80000100; bootm 0x80008000
> > 
> > Can't you set those atags correctly in uboot?
> 
> No, because atags are not static (e.g bootreason).

So? You craft them properly in u-boot?

M
Pali Rohár Jan. 25, 2012, 9:08 p.m. UTC | #4
On Wednesday 25 January 2012 21:55:53 Marek Vasut wrote:
> must can reuse? Anyway, that's nonsense, why won't u-boot be able to craft
> those atags?
> 

Maemo 5 (default OS in Nokia N900) cannot work if kernel does not have proper 
atags from NOLO. So if U-Boot does not reuse it, then Maemo will not boot...
Marek Vasut Jan. 25, 2012, 9:28 p.m. UTC | #5
> On Wednesday 25 January 2012 21:55:53 Marek Vasut wrote:
> > must can reuse? Anyway, that's nonsense, why won't u-boot be able to
> > craft those atags?
> 
> Maemo 5 (default OS in Nokia N900) cannot work if kernel does not have
> proper atags from NOLO. So if U-Boot does not reuse it, then Maemo will
> not boot...

U-Boot CAN GENERATE THEM
Pali Rohár Jan. 25, 2012, 9:35 p.m. UTC | #6
On Wednesday 25 January 2012 22:28:38 Marek Vasut wrote:
> > On Wednesday 25 January 2012 21:55:53 Marek Vasut wrote:
> > > must can reuse? Anyway, that's nonsense, why won't u-boot be able to
> > > craft those atags?
> > 
> > Maemo 5 (default OS in Nokia N900) cannot work if kernel does not have
> > proper atags from NOLO. So if U-Boot does not reuse it, then Maemo will
> > not boot...
> 
> U-Boot CAN GENERATE THEM

Yes, you can parse atags from NOLO and then generate new from existing... But 
why? Better and easier is copy exising and use it.
Marek Vasut Jan. 25, 2012, 9:55 p.m. UTC | #7
> On Wednesday 25 January 2012 22:28:38 Marek Vasut wrote:
> > > On Wednesday 25 January 2012 21:55:53 Marek Vasut wrote:
> > > > must can reuse? Anyway, that's nonsense, why won't u-boot be able to
> > > > craft those atags?
> > > 
> > > Maemo 5 (default OS in Nokia N900) cannot work if kernel does not have
> > > proper atags from NOLO. So if U-Boot does not reuse it, then Maemo will
> > > not boot...
> > 
> > U-Boot CAN GENERATE THEM
> 
> Yes, you can parse atags from NOLO and then generate new from existing...
> But why? Better and easier is copy exising and use it.

Because eventually, someone will replace nolo with u-boot and what then?

M
Pali Rohár Jan. 25, 2012, 10:03 p.m. UTC | #8
On Wednesday 25 January 2012 22:55:25 Marek Vasut wrote:
> > On Wednesday 25 January 2012 22:28:38 Marek Vasut wrote:
> > > > On Wednesday 25 January 2012 21:55:53 Marek Vasut wrote:
> > > > > must can reuse? Anyway, that's nonsense, why won't u-boot be able to
> > > > > craft those atags?
> > > > 
> > > > Maemo 5 (default OS in Nokia N900) cannot work if kernel does not have
> > > > proper atags from NOLO. So if U-Boot does not reuse it, then Maemo
> > > > will
> > > > not boot...
> > > 
> > > U-Boot CAN GENERATE THEM
> > 
> > Yes, you can parse atags from NOLO and then generate new from existing...
> > But why? Better and easier is copy exising and use it.
> 
> Because eventually, someone will replace nolo with u-boot and what then?
> 

Then we will know what is NOLO doing and how NOLO generating atags...

Temporary solution will be to dump atags for specified N900 HW revision and 
hard-code it into u-boot... But in one atag is stored boot reason (power key, 
watchdog reset, normal reset, alarm clock, charger connected, ...) - so we 
will do not have feature to know why was Maemo started.

Or if someone replace NOLO, he will use other system/kernel which do not 
depend on non standard atags... (Debian, Kubuntu, Mer or Android working 
without NOLO atags on N900).
diff mbox

Patch

diff --git a/README b/README
index 9d713e8..8c3b98a 100644
--- a/README
+++ b/README
@@ -3584,6 +3584,8 @@  Some configuration options can be set using Environment Variables.
 
 List of environment variables (most likely not complete):
 
+  atagaddr	- bootm will use ATAGs struct from specified address (arm only)
+
   baudrate	- see CONFIG_BAUDRATE
 
   bootdelay	- see CONFIG_BOOTDELAY
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index afa0093..8366dd5 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -93,6 +93,14 @@  static void announce_and_cleanup(void)
 	cleanup_before_linux();
 }
 
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+defined(CONFIG_CMDLINE_TAG) || \
+defined(CONFIG_INITRD_TAG) || \
+defined(CONFIG_SERIAL_TAG) || \
+defined(CONFIG_REVISION_TAG)
+#define CONFIG_SETUP_ANY_TAG
+#endif
+
 int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 {
 	bd_t	*bd = gd->bd;
@@ -125,12 +133,22 @@  int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 	debug ("## Transferring control to Linux (at address %08lx) ...\n",
 	       (ulong) kernel_entry);
 
-#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
-    defined (CONFIG_CMDLINE_TAG) || \
-    defined (CONFIG_INITRD_TAG) || \
-    defined (CONFIG_SERIAL_TAG) || \
-    defined (CONFIG_REVISION_TAG)
-	setup_start_tag (bd);
+	s = getenv("atagaddr");
+	if (s)
+		bd->bi_boot_params = simple_strtoul(s, NULL, 16);
+
+	if (bd->bi_boot_params) {
+		printf("Using existing atags at %#lx\n", bd->bi_boot_params);
+
+		params = (struct tag *) bd->bi_boot_params;
+		while (params->hdr.size > 0)
+			params = tag_next(params);
+	} else {
+#ifdef CONFIG_SETUP_ANY_TAG
+		setup_start_tag(bd);
+#endif
+	}
+
 #ifdef CONFIG_SERIAL_TAG
 	setup_serial_tag (&params);
 #endif
@@ -147,8 +165,15 @@  int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 	if (images->rd_start && images->rd_end)
 		setup_initrd_tag (bd, images->rd_start, images->rd_end);
 #endif
-	setup_end_tag(bd);
+
+	if (s) {
+		if (params->hdr.size > 0)
+			setup_end_tag(bd);
+	} else {
+#ifdef CONFIG_SETUP_ANY_TAG
+		setup_end_tag(bd);
 #endif
+	}
 
 	announce_and_cleanup();