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, [EMAIL PROTECTED] + * + * 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 ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users