All of lore.kernel.org
 help / color / mirror / Atom feed
From: Makito SHIOKAWA <mshiokawa@miraclelinux.com>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [RFC] Implementing Boot Image Fallback on U-Boot
Date: Fri, 25 Apr 2008 19:45:52 +0900	[thread overview]
Message-ID: <4811B660.7020901@miraclelinux.com> (raw)
In-Reply-To: <20080424132303.4887924AB1@gemini.denx.de>

Hi,

Thank you for your reply.

> Are you aware that U-Boot has scripting capabilities, to the extend of
> being able to run shell scripts?

What I was thinking as "boomf" is like a patch bellow (It is for U-Boot 1.1.4 
and just a prototype). I knew about scripting, but I thought it was difficult 
to do this processing by a script (especially error checks). Also, I didn't 
think it's a good way to set corresponding long script to "bootcmd" (U-Boot 
environment area is limited).

But, is it better to do this processing by a script? (Or, is there more proper 
way to do same kind of things?)

> What you are asking for can be pretty easily implemented using a few
> macro definitions utilizing the aforementioned features.

Is it able to do without using all of the elements (new command, new 
environment variable, fw_setenv) I wrote in the first mail?
I'll check documents and sources over again, but I would appreciate if you can 
give me some keywords of those features ...


Best regards,

---
  common/Makefile     |    2
  common/cmd_bootmf.c |  256 +++++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 257 insertions(+), 1 deletion(-)

--- a/common/Makefile
+++ b/common/Makefile
@@ -29,7 +29,7 @@ AOBJS	=

  COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
  	  cmd_ace.o cmd_autoscript.o \
-	  cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
+	  cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o cmd_bootmf.o \
  	  cmd_cache.o cmd_console.o \
  	  cmd_date.o cmd_dcr.o cmd_diag.o cmd_display.o cmd_doc.o cmd_dtt.o \
  	  cmd_eeprom.o cmd_elf.o cmd_ext2.o \
--- /dev/null
+++ b/common/cmd_bootmf.c
@@ -0,0 +1,256 @@
+/*
+ * (C) Copyright 2008
+ * Makito SHIOKAWA, MIRACLE LINUX CORPORATION, mshiokawa at miraclelinux.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
+
+/*
+ * Codes are taken from GRUB
+ */
+
+#define MAXINT 0x7FFFFFFF
+#define MAX_FALLBACK_ENTRIES 8
+
+static int default_entry;
+static int fallback_entryno;
+static int fallback_entries[MAX_FALLBACK_ENTRIES];
+static int current_entryno;
+
+static int tolower (int c)
+{
+	if (c >= 'A' && c <= 'Z')
+		return (c + ('a' - 'A'));
+	
+	return c;
+}
+
+static int safe_parse_maxint (char **str_ptr, int *myint_ptr)
+{
+	char *ptr = *str_ptr;
+	int myint = 0;
+	int mult = 10, found = 0;
+
+	/*
+	 *  Is this a hex number?
+	 */
+	if (*ptr == '0' && tolower (*(ptr + 1)) == 'x')
+	{
+		ptr += 2;
+		mult = 16;
+	}
+	
+	while (1)
+	{
+		/* A bit tricky. This below makes use of the equivalence:
+		   (A >= B && A <= C) <=> ((A - B) <= (C - B))
+		   when C > B and A is unsigned.  */
+		unsigned int digit;
+		
+		digit = tolower (*ptr) - '0';
+		if (digit > 9)
+		{
+			digit -= 'a' - '0';
+			if (mult == 10 || digit > 5)
+				break;
+			digit += 10;
+		}
+		
+		found = 1;
+		if (myint > ((MAXINT - digit) / mult))
+		{
+			return 0;
+		}
+		myint = (myint * mult) + digit;
+		ptr++;
+	}
+	
+	if (!found)
+	{
+		return 0;
+	}
+	
+	*str_ptr = ptr;
+	*myint_ptr = myint;
+	
+	return 1;
+}
+
+static int default_func (char *arg)
+{
+	if (! safe_parse_maxint (&arg, &default_entry))
+		return 1;
+
+	return 0;
+}
+
+/* Find the next word from CMDLINE and return the pointer. If
+   AFTER_EQUAL is non-zero, assume that the character `=' is treated as
+   a space. Caution: this assumption is for backward compatibility.  */
+static char *skip_to (int after_equal, char *cmdline)
+{
+	/* Skip until we hit whitespace, or maybe an equal sign. */
+	while (*cmdline && *cmdline != ' ' && *cmdline != '\t' &&
+	      ! (after_equal && *cmdline == '='))
+		cmdline ++;
+	
+	/* Skip whitespace, and maybe equal signs. */
+	while (*cmdline == ' ' || *cmdline == '\t' ||
+	      (after_equal && *cmdline == '='))
+		cmdline ++;
+
+	return cmdline;
+}
+
+static int fallback_func (char *arg)
+{
+	int i = 0;
+	
+	while (*arg)
+	{
+		int entry;
+		int j;
+		
+		if (! safe_parse_maxint (&arg, &entry))
+			return 1;
+		
+		/* Remove duplications to prevent infinite looping.  */
+		for (j = 0; j < i; j++)
+			if (entry == fallback_entries[j])
+				break;
+		if (j != i)
+			continue;
+		
+		fallback_entries[i++] = entry;
+		if (i == MAX_FALLBACK_ENTRIES)
+			break;
+		
+		arg = skip_to (0, arg);
+	}
+	
+	if (i < MAX_FALLBACK_ENTRIES)
+		fallback_entries[i] = -1;
+	
+	fallback_entryno = (i == 0) ? -1 : 0;
+	
+	return 0;
+}
+
+static int savedefault_func (void)
+{
+	int entryno;
+	int i;
+	int index = 0;
+	char buf[16];
+	
+	for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
+	{
+		if (fallback_entries[i] < 0)
+			break;
+		if (fallback_entries[i] == current_entryno)
+		{
+			index = i + 1;
+			break;
+		}
+	}
+	
+	if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0)
+	{
+		/* This is the last.  */
+		return 1;
+	}
+	
+	entryno = fallback_entries[index];
+	
+	sprintf(buf, "%d", entryno);
+	setenv("default", buf);
+	saveenv();
+	
+	return 0;
+}
+
+/*
+ * TODO: Add error check
+ */
+
+int do_bootmf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	char *s;
+	
+	default_entry = 0;
+	fallback_entryno = -1;
+	fallback_entries[0] = -1;
+	current_entryno = 0;
+	
+	if ((s = getenv("default")) != NULL)
+		default_func(s);
+	
+	if ((s = getenv("fallback")) != NULL)
+		fallback_func(s);
+	
+	while (1) {
+		char buf[16];
+		char *local_args[2];
+		ulong addr;
+		int rcode = 0;
+		
+		if (!current_entryno)
+			current_entryno = default_entry;
+		
+		savedefault_func();
+		
+		sprintf(buf, "imgaddr%d", current_entryno);
+		if ((s = getenv(buf)) != NULL)
+			addr = simple_strtoul(s, NULL, 16);
+		else
+			break;
+		
+		sprintf(buf, "bootargs%d", current_entryno);
+		if ((s = getenv(buf)) != NULL)
+			setenv("bootargs", s);
+		else
+			break;
+		
+		load_addr = addr;
+		local_args[0] = argv[0];
+		local_args[1] = NULL;
+		rcode = do_bootm (cmdtp, 0, 1, local_args);
+		if (rcode) {
+			if (fallback_entryno >= 0) {
+				current_entryno = fallback_entries[fallback_entryno];
+				fallback_entryno++;
+				if (fallback_entryno >= MAX_FALLBACK_ENTRIES
+				   || fallback_entries[fallback_entryno] < 0)
+					fallback_entryno = -1;
+			} else
+				break;
+		} else
+			break;
+	}
+	
+	return 1;
+}
+
+U_BOOT_CMD(
+	bootmf, 1, 1, do_bootmf,
+	"bootmf - boot application image from memory with fallback enabled\n",
+	NULL
+);

-- 
MIRACLE LINUX CORPORATION
Makito SHIOKAWA

      reply	other threads:[~2008-04-25 10:45 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-24  2:53 [U-Boot-Users] [RFC] Implementing Boot Image Fallback on U-Boot Makito SHIOKAWA
2008-04-24  5:00 ` Matthias Fuchs
2008-04-24  9:59   ` Makito SHIOKAWA
2008-04-24 13:12     ` Wolfgang Denk
2008-04-24  9:01 ` Bartlomiej Sieka
2008-04-24 11:16   ` Makito SHIOKAWA
2008-04-24 12:42   ` Makito SHIOKAWA
2008-04-24 13:23     ` Wolfgang Denk
2008-04-25 10:45       ` Makito SHIOKAWA [this message]

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=4811B660.7020901@miraclelinux.com \
    --to=mshiokawa@miraclelinux.com \
    --cc=u-boot@lists.denx.de \
    /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.