Skip to content
Snippets Groups Projects
cmd_bootm.c 30.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	printf ("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n",
    		(ulong)loader);
    
    
    	show_boot_progress (15);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	/*
    	 * 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);
    
    #ifdef CONFIG_LYNXKDI
    static void do_bootm_lynxkdi (cmd_tbl_t *cmdtp, int flag,
    			     int argc, char *argv[],
    
    	image_header_t *hdr = &images->legacy_hdr_os_copy;
    
    
    #if defined(CONFIG_FIT)
    	if (!images->legacy_hdr_valid) {
    		fit_unsupported_reset ("Lynx");
    		do_reset (cmdtp, flag, argc, argv);
    	}
    #endif
    
    	lynxkdi_boot ((image_header_t *)hdr);
    
    }
    #endif /* CONFIG_LYNXKDI */
    
    static void do_bootm_rtems (cmd_tbl_t *cmdtp, int flag,
    			   int argc, char *argv[],
    
    {
    	void (*entry_point)(bd_t *);
    
    #if defined(CONFIG_FIT)
    	if (!images->legacy_hdr_valid) {
    		fit_unsupported_reset ("RTEMS");
    		do_reset (cmdtp, flag, argc, argv);
    	}
    #endif
    
    
    	entry_point = (void (*)(bd_t *))images->ep;
    
    
    	printf ("## Transferring control to RTEMS (at address %08lx) ...\n",
    		(ulong)entry_point);
    
    
    	show_boot_progress (15);
    
    
    	/*
    	 * RTEMS Parameters:
    	 *   r3: ptr to board info data
    	 */
    
    	(*entry_point)(gd->bd);
    
    static void do_bootm_vxworks (cmd_tbl_t *cmdtp, int flag,
    			     int argc, char *argv[],
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    	char str[80];
    
    		fit_unsupported_reset ("VxWorks");
    		do_reset (cmdtp, flag, argc, argv);
    	}
    #endif
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	sprintf(str, "%lx", images->ep); /* write entry-point into string */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	setenv("loadaddr", str);
    	do_bootvx(cmdtp, 0, 0, NULL);
    }
    
    
    static void do_bootm_qnxelf(cmd_tbl_t *cmdtp, int flag,
    			    int argc, char *argv[],
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    	char *local_args[2];
    	char str[16];
    
    
    #if defined(CONFIG_FIT)
    	if (!images->legacy_hdr_valid) {
    		fit_unsupported_reset ("QNX");
    		do_reset (cmdtp, flag, argc, argv);
    	}
    #endif
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	sprintf(str, "%lx", images->ep); /* write entry-point into string */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	local_args[0] = argv[0];
    	local_args[1] = str;	/* and provide it via the arguments */
    	do_bootelf(cmdtp, 0, 2, local_args);
    }
    
    #if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)
    static void do_bootm_artos (cmd_tbl_t *cmdtp, int flag,
    			   int argc, char *argv[],
    
    {
    	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");
    		do_reset (cmdtp, flag, argc, argv);
    	}
    #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 */
    
    	len = strlen (s);
    
    	top = (top - (len + 1)) & ~0xF;
    	cmdline = (char *)top;
    	debug ("## cmdline at 0x%08lX ", top);
    
    	strcpy (cmdline, s);
    
    	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))images->ep;
    
    	(*entry) (kbd, cmdline, fwenv, top);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    }