summaryrefslogtreecommitdiffstats
path: root/common/cmd_bootm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/cmd_bootm.c')
-rw-r--r--common/cmd_bootm.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index c3d62cb8c1..fa32d467ed 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -31,6 +31,7 @@
#include <image.h>
#include <malloc.h>
#include <zlib.h>
+#include <environment.h>
#include <asm/byteorder.h>
#if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
#include <rtc.h>
@@ -105,6 +106,9 @@ static boot_os_Fcn do_bootm_qnxelf;
int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] );
int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] );
#endif /* CFG_CMD_ELF */
+#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
+static boot_os_Fcn do_bootm_artos;
+#endif
image_header_t header;
@@ -338,6 +342,12 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
addr, len_ptr, verify);
break;
#endif /* CFG_CMD_ELF */
+#ifdef CONFIG_ARTOS
+ case IH_OS_ARTOS:
+ do_bootm_artos (cmdtp, flag, argc, argv,
+ addr, len_ptr, verify);
+ break;
+#endif
}
SHOW_BOOT_PROGRESS (-9);
@@ -717,6 +727,99 @@ do_bootm_netbsd (cmd_tbl_t *cmdtp, int flag,
(*loader) (gd->bd, img_addr, consdev, cmdline);
}
+#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
+
+/* Function that returns a character from the environment */
+extern uchar (*env_get_char)(int);
+
+static void
+do_bootm_artos (cmd_tbl_t *cmdtp, int flag,
+ int argc, char *argv[],
+ ulong addr,
+ ulong *len_ptr,
+ int verify)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+ ulong top;
+ char *s, *cmdline;
+ char **fwenv, **ss;
+ int i, j, nxt, len, envno, envsz;
+ bd_t *kbd;
+ void (*entry)(bd_t *bd, char *cmdline, char **fwenv, ulong top);
+ image_header_t *hdr = &header;
+
+ /*
+ * Booting an ARTOS kernel image + application
+ */
+
+ /* this used to be the top of memory, but was wrong... */
+#ifdef CONFIG_PPC
+ /* get stack pointer */
+ asm volatile ("mr %0,1" : "=r"(top) );
+#endif
+ debug ("## Current stack ends at 0x%08lX ", top);
+
+ top -= 2048; /* just to be sure */
+ if (top > CFG_BOOTMAPSZ)
+ top = CFG_BOOTMAPSZ;
+ top &= ~0xF;
+
+ debug ("=> set upper limit to 0x%08lX\n", top);
+
+ /* first check the artos specific boot args, then the linux args*/
+ if ((s = getenv("abootargs")) == NULL && (s = getenv("bootargs")) == NULL)
+ s = "";
+
+ /* get length of cmdline, and place it */
+ len = strlen(s);
+ top = (top - (len + 1)) & ~0xF;
+ cmdline = (char *)top;
+ debug ("## cmdline at 0x%08lX ", top);
+ strcpy(cmdline, s);
+
+ /* copy bdinfo */
+ top = (top - sizeof(bd_t)) & ~0xF;
+ debug ("## bd at 0x%08lX ", top);
+ kbd = (bd_t *)top;
+ memcpy(kbd, gd->bd, sizeof(bd_t));
+
+ /* first find number of env entries, and their size */
+ envno = 0;
+ envsz = 0;
+ for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+ for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
+ ;
+ envno++;
+ envsz += (nxt - i) + 1; /* plus trailing zero */
+ }
+ envno++; /* plus the terminating zero */
+ debug ("## %u envvars total size %u ", envno, envsz);
+
+ top = (top - sizeof(char **)*envno) & ~0xF;
+ fwenv = (char **)top;
+ debug ("## fwenv at 0x%08lX ", top);
+
+ top = (top - envsz) & ~0xF;
+ s = (char *)top;
+ ss = fwenv;
+
+ /* now copy them */
+ for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
+ for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
+ ;
+ *ss++ = s;
+ for (j = i; j < nxt; ++j)
+ *s++ = env_get_char(j);
+ *s++ = '\0';
+ }
+ *ss++ = NULL; /* terminate */
+
+ entry = (void (*)(bd_t *, char *, char **, ulong))ntohl(hdr->ih_ep);
+ (*entry)(kbd, cmdline, fwenv, top);
+}
+#endif
+
+
#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
@@ -839,6 +942,9 @@ print_type (image_header_t *hdr)
case IH_OS_QNX: os = "QNX"; break;
case IH_OS_U_BOOT: os = "U-Boot"; break;
case IH_OS_RTEMS: os = "RTEMS"; break;
+#ifdef CONFIG_ARTOS
+ case IH_OS_ARTOS: os = "ARTOS"; break;
+#endif
default: os = "Unknown OS"; break;
}
OpenPOWER on IntegriCloud