Newer
Older
/*
* Booting a (NetBSD) kernel image
*
* This process is pretty similar to a standalone application:
* The (first part of an multi-) image must be a stage-2 loader,
* which in turn is responsible for loading & invoking the actual
* kernel. The only differences are the parameters being passed:
* besides the board info strucure, the loader expects a command
* line, the name of the console device, and (optionally) the
* address of the original image header.
*/
os_hdr = NULL;
if (image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
image_multi_getimg (hdr, 1, &kernel_data, &kernel_len);
if (kernel_len)
os_hdr = hdr;
consdev = "";
#if defined (CONFIG_8xx_CONS_SMC1)
consdev = "smc1";
#elif defined (CONFIG_8xx_CONS_SMC2)
consdev = "smc2";
#elif defined (CONFIG_8xx_CONS_SCC2)
consdev = "scc2";
#elif defined (CONFIG_8xx_CONS_SCC3)
consdev = "scc3";
#endif
if (argc > 2) {
ulong len;
int i;
for (i = 2, len = 0; i < argc; i += 1)
len += strlen (argv[i]) + 1;
cmdline = malloc (len);
for (i = 2, len = 0; i < argc; i += 1) {
if (i > 2)
cmdline[len++] = ' ';
strcpy (&cmdline[len], argv[i]);
len += strlen (argv[i]);
}
} else if ((cmdline = getenv ("bootargs")) == NULL) {
loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;
printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
(ulong)loader);
/*
* NetBSD Stage-2 Loader Parameters:
* r3: ptr to board info data
* r4: image address
* r5: console device
* r6: boot args string
*/
(*loader) (gd->bd, os_hdr, consdev, cmdline);
static int do_bootm_lynxkdi (int flag, int argc, char *argv[],
bootm_headers_t *images)
image_header_t *hdr = &images->legacy_hdr_os_copy;
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("Lynx");
}
#endif
lynxkdi_boot ((image_header_t *)hdr);
}
#endif /* CONFIG_LYNXKDI */
static int do_bootm_rtems (int flag, int argc, char *argv[],
bootm_headers_t *images)
{
void (*entry_point)(bd_t *);
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("RTEMS");
}
#endif
entry_point = (void (*)(bd_t *))images->ep;
printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
(ulong)entry_point);
/*
* RTEMS Parameters:
* r3: ptr to board info data
*/
#if defined(CONFIG_CMD_ELF)
static int do_bootm_vxworks (int flag, int argc, char *argv[],
bootm_headers_t *images)
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("VxWorks");
}
#endif
sprintf(str, "%lx", images->ep); /* write entry-point into string */
do_bootvx(NULL, 0, 0, NULL);
return 1;
static int do_bootm_qnxelf(int flag, int argc, char *argv[],
bootm_headers_t *images)
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("QNX");
}
#endif
sprintf(str, "%lx", images->ep); /* write entry-point into string */
local_args[0] = argv[0];
local_args[1] = str; /* and provide it via the arguments */
do_bootelf(NULL, 0, 2, local_args);
return 1;
#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
static int do_bootm_artos (int flag, int argc, char *argv[],
bootm_headers_t *images)
{
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);
#if defined(CONFIG_FIT)
if (!images->legacy_hdr_valid) {
fit_unsupported_reset ("ARTOS");
}
#endif
/*
* 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 */
top = (top - (len + 1)) & ~0xF;
cmdline = (char *)top;
debug ("## cmdline at 0x%08lX ", top);
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++ = '\0';
}
*ss++ = NULL; /* terminate */
entry = (void (*)(bd_t *, char *, char **, ulong))images->ep;
(*entry) (kbd, cmdline, fwenv, top);