diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 5 | ||||
| -rw-r--r-- | common/cmd_bootm.c | 143 | ||||
| -rw-r--r-- | common/cmd_fat.c | 57 | ||||
| -rw-r--r-- | common/cmd_log.c | 101 | ||||
| -rw-r--r-- | common/cmd_nvedit.c | 3 | ||||
| -rw-r--r-- | common/cmd_pxe.c | 16 | ||||
| -rw-r--r-- | common/cmd_spl.c | 188 | ||||
| -rw-r--r-- | common/env_fat.c | 156 | ||||
| -rw-r--r-- | common/image.c | 17 | 
9 files changed, 619 insertions, 67 deletions
diff --git a/common/Makefile b/common/Makefile index fd9b3b053..d9f10f3f6 100644 --- a/common/Makefile +++ b/common/Makefile @@ -54,6 +54,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_embedded.o  COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o  COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o  COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o +COBJS-$(CONFIG_ENV_IS_IN_FAT) += env_fat.o  COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o  COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o  COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o @@ -162,6 +163,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o  endif  COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o  COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o +COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o  # others  ifdef CONFIG_DDR_SPD @@ -185,6 +187,9 @@ COBJS-$(CONFIG_UPDATE_TFTP) += update.o  COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o  endif +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o +endif  COBJS-y += console.o  COBJS-y += dlmalloc.o  COBJS-y += memsize.o diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index d88f6c025..9ad2535d4 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -169,25 +169,25 @@ void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));  #define IH_INITRD_ARCH IH_ARCH_DEFAULT -static void bootm_start_lmb(void) -{  #ifdef CONFIG_LMB +static void boot_start_lmb(bootm_headers_t *images) +{  	ulong		mem_start;  	phys_size_t	mem_size; -	lmb_init(&images.lmb); +	lmb_init(&images->lmb);  	mem_start = getenv_bootm_low();  	mem_size = getenv_bootm_size(); -	lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size); +	lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); -	arch_lmb_reserve(&images.lmb); -	board_lmb_reserve(&images.lmb); +	arch_lmb_reserve(&images->lmb); +	board_lmb_reserve(&images->lmb); +}  #else -# define lmb_reserve(lmb, base, size) +static inline void boot_start_lmb(bootm_headers_t *images) { }  #endif -}  static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { @@ -197,7 +197,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  	memset((void *)&images, 0, sizeof(images));  	images.verify = getenv_yesno("verify"); -	bootm_start_lmb(); +	boot_start_lmb(&images);  	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); @@ -1518,3 +1518,128 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[],  	return 1;  }  #endif + +#ifdef CONFIG_CMD_BOOTZ + +static int __bootz_setup(void *image, void **start, void **end) +{ +	/* Please define bootz_setup() for your platform */ + +	puts("Your platform's zImage format isn't supported yet!\n"); +	return -1; +} +int bootz_setup(void *image, void **start, void **end) +	__attribute__((weak, alias("__bootz_setup"))); + +/* + * zImage booting support + */ +static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc, +			char * const argv[], bootm_headers_t *images) +{ +	int ret; +	void *zi_start, *zi_end; + +	memset(images, 0, sizeof(bootm_headers_t)); + +	boot_start_lmb(images); + +	/* Setup Linux kernel zImage entry point */ +	if (argc < 2) { +		images->ep = load_addr; +		debug("*  kernel: default image load address = 0x%08lx\n", +				load_addr); +	} else { +		images->ep = simple_strtoul(argv[1], NULL, 16); +		debug("*  kernel: cmdline image address = 0x%08lx\n", +			images->ep); +	} + +	ret = bootz_setup((void *)images->ep, &zi_start, &zi_end); +	if (ret != 0) +		return 1; + +	lmb_reserve(&images->lmb, images->ep, zi_end - zi_start); + +	/* Find ramdisk */ +	ret = boot_get_ramdisk(argc, argv, images, IH_INITRD_ARCH, +			&images->rd_start, &images->rd_end); +	if (ret) { +		puts("Ramdisk image is corrupt or invalid\n"); +		return 1; +	} + +#if defined(CONFIG_OF_LIBFDT) +	/* find flattened device tree */ +	ret = boot_get_fdt(flag, argc, argv, images, +			   &images->ft_addr, &images->ft_len); +	if (ret) { +		puts("Could not find a valid device tree\n"); +		return 1; +	} + +	set_working_fdt_addr(images->ft_addr); +#endif + +	return 0; +} + +static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	ulong		iflag; +	bootm_headers_t	images; + +	if (bootz_start(cmdtp, flag, argc, argv, &images)) +		return 1; + +	/* +	 * We have reached the point of no return: we are going to +	 * overwrite all exception vector code, so we cannot easily +	 * recover from any failures any more... +	 */ +	iflag = disable_interrupts(); + +#if defined(CONFIG_CMD_USB) +	/* +	 * turn off USB to prevent the host controller from writing to the +	 * SDRAM while Linux is booting. This could happen (at least for OHCI +	 * controller), because the HCCA (Host Controller Communication Area) +	 * lies within the SDRAM and the host controller writes continously to +	 * this area (as busmaster!). The HccaFrameNumber is for example +	 * updated every 1 ms within the HCCA structure in SDRAM! For more +	 * details see the OpenHCI specification. +	 */ +	usb_stop(); +#endif + +#ifdef CONFIG_SILENT_CONSOLE +	fixup_silent_linux(); +#endif +	arch_preboot_os(); + +	do_bootm_linux(0, argc, argv, &images); +#ifdef DEBUG +	puts("\n## Control returned to monitor - resetting...\n"); +#endif +	do_reset(cmdtp, flag, argc, argv); + +	return 1; +} + +U_BOOT_CMD( +	bootz,	CONFIG_SYS_MAXARGS,	1,	do_bootz, +	"boot Linux zImage image from memory", +	"[addr [initrd[:size]] [fdt]]\n" +	"    - boot Linux zImage stored in memory\n" +	"\tThe argument 'initrd' is optional and specifies the address\n" +	"\tof the initrd in memory. The optional argument ':size' allows\n" +	"\tspecifying the size of RAW initrd.\n" +#if defined(CONFIG_OF_LIBFDT) +	"\tWhen booting a Linux kernel which requires a flat device-tree\n" +	"\ta third argument is required which is the address of the\n" +	"\tdevice-tree blob. To boot that kernel without an initrd image,\n" +	"\tuse a '-' for the second argument. If you do not pass a third\n" +	"\ta bd_info struct will be passed instead\n" +#endif +); +#endif	/* CONFIG_CMD_BOOTZ */ diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 022049434..559a16d61 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -184,3 +184,60 @@ U_BOOT_CMD(  	"<interface> <dev[:part]>\n"  	"    - print information about filesystem from 'dev' on 'interface'"  ); + +#ifdef CONFIG_FAT_WRITE +static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag, +		int argc, char * const argv[]) +{ +	long size; +	unsigned long addr; +	unsigned long count; +	block_dev_desc_t *dev_desc = NULL; +	int dev = 0; +	int part = 1; +	char *ep; + +	if (argc < 5) +		return cmd_usage(cmdtp); + +	dev = (int)simple_strtoul(argv[2], &ep, 16); +	dev_desc = get_dev(argv[1], dev); +	if (dev_desc == NULL) { +		puts("\n** Invalid boot device **\n"); +		return 1; +	} +	if (*ep) { +		if (*ep != ':') { +			puts("\n** Invalid boot device, use `dev[:part]' **\n"); +			return 1; +		} +		part = (int)simple_strtoul(++ep, NULL, 16); +	} +	if (fat_register_device(dev_desc, part) != 0) { +		printf("\n** Unable to use %s %d:%d for fatwrite **\n", +			argv[1], dev, part); +		return 1; +	} +	addr = simple_strtoul(argv[3], NULL, 16); +	count = simple_strtoul(argv[5], NULL, 16); + +	size = file_fat_write(argv[4], (void *)addr, count); +	if (size == -1) { +		printf("\n** Unable to write \"%s\" from %s %d:%d **\n", +			argv[4], argv[1], dev, part); +		return 1; +	} + +	printf("%ld bytes written\n", size); + +	return 0; +} + +U_BOOT_CMD( +	fatwrite,	6,	0,	do_fat_fswrite, +	"write file into a dos filesystem", +	"<interface> <dev[:part]> <addr> <filename> <bytes>\n" +	"    - write file 'filename' from the address 'addr' in RAM\n" +	"      to 'dev' on 'interface'" +); +#endif diff --git a/common/cmd_log.c b/common/cmd_log.c index f9fbe002c..ee291c1b4 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -49,8 +49,8 @@  DECLARE_GLOBAL_DATA_PTR;  /* Local prototypes */ -static void logbuff_putc (const char c); -static void logbuff_puts (const char *s); +static void logbuff_putc(const char c); +static void logbuff_puts(const char *s);  static int logbuff_printk(const char *line);  static char buf[1024]; @@ -70,9 +70,10 @@ unsigned long __logbuffer_base(void)  {  	return CONFIG_SYS_SDRAM_BASE + gd->ram_size - LOGBUFF_LEN;  } -unsigned long logbuffer_base (void) __attribute__((weak, alias("__logbuffer_base"))); +unsigned long logbuffer_base(void) +__attribute__((weak, alias("__logbuffer_base"))); -void logbuff_init_ptrs (void) +void logbuff_init_ptrs(void)  {  	unsigned long tag, post_word;  	char *s; @@ -81,13 +82,13 @@ void logbuff_init_ptrs (void)  	log = (logbuff_t *)CONFIG_ALT_LH_ADDR;  	lbuf = (char *)CONFIG_ALT_LB_ADDR;  #else -	log = (logbuff_t *)(logbuffer_base ()) - 1; +	log = (logbuff_t *)(logbuffer_base()) - 1;  	lbuf = (char *)log->buf;  #endif  	/* Set up log version */  	if ((s = getenv ("logversion")) != NULL) -		log_version = (int)simple_strtoul (s, NULL, 10); +		log_version = (int)simple_strtoul(s, NULL, 10);  	if (log_version == 2)  		tag = log->v2.tag; @@ -96,9 +97,8 @@ void logbuff_init_ptrs (void)  	post_word = post_word_load();  #ifdef CONFIG_POST  	/* The post routines have setup the word so we can simply test it */ -	if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) { -		logbuff_reset (); -	} +	if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) +		logbuff_reset();  #else  	/* No post routines, so we do our own checking                    */  	if (tag != LOGBUFF_MAGIC || post_word != LOGBUFF_MAGIC) { @@ -111,15 +111,15 @@ void logbuff_init_ptrs (void)  	/* Initialize default loglevel if present */  	if ((s = getenv ("loglevel")) != NULL) -		console_loglevel = (int)simple_strtoul (s, NULL, 10); +		console_loglevel = (int)simple_strtoul(s, NULL, 10);  	gd->flags |= GD_FLG_LOGINIT;  } -void logbuff_reset (void) +void logbuff_reset(void)  {  #ifndef CONFIG_ALT_LB_ADDR -	memset (log, 0, sizeof (logbuff_t)); +	memset(log, 0, sizeof(logbuff_t));  #endif  	if (log_version == 2) {  		log->v2.tag = LOGBUFF_MAGIC; @@ -140,7 +140,7 @@ void logbuff_reset (void)  	}  } -int drv_logbuff_init (void) +int drv_logbuff_init(void)  {  	struct stdio_dev logdev;  	int rc; @@ -154,20 +154,20 @@ int drv_logbuff_init (void)  	logdev.putc  = logbuff_putc;		/* 'putc' function */  	logdev.puts  = logbuff_puts;		/* 'puts' function */ -	rc = stdio_register (&logdev); +	rc = stdio_register(&logdev);  	return (rc == 0) ? 1 : rc;  } -static void logbuff_putc (const char c) +static void logbuff_putc(const char c)  {  	char buf[2];  	buf[0] = c;  	buf[1] = '\0'; -	logbuff_printk (buf); +	logbuff_printk(buf);  } -static void logbuff_puts (const char *s) +static void logbuff_puts(const char *s)  {  	logbuff_printk (s);  } @@ -175,10 +175,12 @@ static void logbuff_puts (const char *s)  void logbuff_log(char *msg)  {  	if ((gd->flags & GD_FLG_LOGINIT)) { -		logbuff_printk (msg); +		logbuff_printk(msg);  	} else { -		/* Can happen only for pre-relocated errors as logging */ -		/* at that stage should be disabled                    */ +		/* +		 * Can happen only for pre-relocated errors as logging +		 * at that stage should be disabled +		 */  		puts (msg);  	}  } @@ -193,16 +195,16 @@ void logbuff_log(char *msg)   * Return:      None   *   */ -int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *s;  	unsigned long i, start, size; -	if (strcmp(argv[1],"append") == 0) { +	if (strcmp(argv[1], "append") == 0) {  		/* Log concatenation of all arguments separated by spaces */ -		for (i=2; i<argc; i++) { -			logbuff_printk (argv[i]); -			logbuff_putc ((i<argc-1) ? ' ' : '\n'); +		for (i = 2; i < argc; i++) { +			logbuff_printk(argv[i]); +			logbuff_putc((i < argc - 1) ? ' ' : '\n');  		}  		return 0;  	} @@ -210,34 +212,41 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	switch (argc) {  	case 2: -		if (strcmp(argv[1],"show") == 0) { +		if (strcmp(argv[1], "show") == 0) {  			if (log_version == 2) {  				start = log->v2.start;  				size = log->v2.end - log->v2.start; -			} -			else { +			} else {  				start = log->v1.start;  				size = log->v1.size;  			} -			for (i=0; i < (size&LOGBUFF_MASK); i++) { -				s = lbuf+((start+i)&LOGBUFF_MASK); -				putc (*s); +			if (size > LOGBUFF_LEN) +				size = LOGBUFF_LEN; +			for (i = 0; i < size; i++) { +				s = lbuf + ((start + i) & LOGBUFF_MASK); +				putc(*s);  			}  			return 0; -		} else if (strcmp(argv[1],"reset") == 0) { -			logbuff_reset (); +		} else if (strcmp(argv[1], "reset") == 0) { +			logbuff_reset();  			return 0; -		} else if (strcmp(argv[1],"info") == 0) { -			printf ("Logbuffer   at  %08lx\n", (unsigned long)lbuf); +		} else if (strcmp(argv[1], "info") == 0) { +			printf("Logbuffer   at  %08lx\n", (unsigned long)lbuf);  			if (log_version == 2) { -				printf ("log_start    =  %08lx\n", log->v2.start); -				printf ("log_end      =  %08lx\n", log->v2.end); -				printf ("logged_chars =  %08lx\n", log->v2.chars); +				printf("log_start    =  %08lx\n", +					log->v2.start); +				printf("log_end      =  %08lx\n", log->v2.end); +				printf("log_con      =  %08lx\n", log->v2.con); +				printf("logged_chars =  %08lx\n", +					log->v2.chars);  			}  			else { -				printf ("log_start    =  %08lx\n", log->v1.start); -				printf ("log_size     =  %08lx\n", log->v1.size); -				printf ("logged_chars =  %08lx\n", log->v1.chars); +				printf("log_start    =  %08lx\n", +					log->v1.start); +				printf("log_size     =  %08lx\n", +					log->v1.size); +				printf("logged_chars =  %08lx\n", +					log->v1.chars);  			}  			return 0;  		} @@ -264,8 +273,8 @@ static int logbuff_printk(const char *line)  	int line_feed;  	static signed char msg_level = -1; -	strcpy (buf + 3, line); -	i = strlen (line); +	strcpy(buf + 3, line); +	i = strlen(line);  	buf_end = buf + 3 + i;  	for (p = buf + 3; p < buf_end; p++) {  		msg = p; @@ -280,8 +289,9 @@ static int logbuff_printk(const char *line)  				p[0] = '<';  				p[1] = default_message_loglevel + '0';  				p[2] = '>'; -			} else +			} else {  				msg += 3; +			}  			msg_level = p[1] - '0';  		}  		line_feed = 0; @@ -292,8 +302,7 @@ static int logbuff_printk(const char *line)  				if (log->v2.end - log->v2.start > LOGBUFF_LEN)  					log->v2.start++;  				log->v2.chars++; -			} -			else { +			} else {  				lbuf[(log->v1.start + log->v1.size) &  					 LOGBUFF_MASK] = *p;  				if (log->v1.size < LOGBUFF_LEN) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 22f98218e..b1494dcb0 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -61,13 +61,14 @@ DECLARE_GLOBAL_DATA_PTR;  	!defined(CONFIG_ENV_IS_IN_DATAFLASH)	&& \  	!defined(CONFIG_ENV_IS_IN_MG_DISK)	&& \  	!defined(CONFIG_ENV_IS_IN_MMC)		&& \ +	!defined(CONFIG_ENV_IS_IN_FAT)		&& \  	!defined(CONFIG_ENV_IS_IN_NAND)		&& \  	!defined(CONFIG_ENV_IS_IN_NVRAM)	&& \  	!defined(CONFIG_ENV_IS_IN_ONENAND)	&& \  	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \  	!defined(CONFIG_ENV_IS_NOWHERE)  # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\ -SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE +SPI_FLASH|MG_DISK|NVRAM|MMC|FAT} or CONFIG_ENV_IS_NOWHERE  #endif  #define XMK_STR(x)	#x diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 8a68fa1ae..b3c1f67a3 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -318,7 +318,7 @@ static int  do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *pxefile_addr_str; -	void *pxefile_addr_r; +	unsigned long pxefile_addr_r;  	int err;  	if (argc != 1) @@ -339,10 +339,10 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	 * Keep trying paths until we successfully get a file we're looking  	 * for.  	 */ -	if (pxe_uuid_path(pxefile_addr_r) > 0 -		|| pxe_mac_path(pxefile_addr_r) > 0 -		|| pxe_ipaddr_paths(pxefile_addr_r) > 0 -		|| get_pxelinux_path("default", pxefile_addr_r) > 0) { +	if (pxe_uuid_path((void *)pxefile_addr_r) > 0 +		|| pxe_mac_path((void *)pxefile_addr_r) > 0 +		|| pxe_ipaddr_paths((void *)pxefile_addr_r) > 0 +		|| get_pxelinux_path("default", (void *)pxefile_addr_r) > 0) {  		printf("Config file found\n"); @@ -363,7 +363,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])   */  static int get_relfile_envaddr(char *file_path, char *envaddr_name)  { -	void *file_addr; +	unsigned long file_addr;  	char *envaddr;  	envaddr = from_env(envaddr_name); @@ -371,10 +371,10 @@ static int get_relfile_envaddr(char *file_path, char *envaddr_name)  	if (!envaddr)  		return -ENOENT; -	if (strict_strtoul(envaddr, 16, (unsigned long *)&file_addr) < 0) +	if (strict_strtoul(envaddr, 16, &file_addr) < 0)  		return -EINVAL; -	return get_relfile(file_path, file_addr); +	return get_relfile(file_path, (void *)file_addr);  }  /* diff --git a/common/cmd_spl.c b/common/cmd_spl.c new file mode 100644 index 000000000..9ec054af3 --- /dev/null +++ b/common/cmd_spl.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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> +#include <cmd_spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char **subcmd_list[] = { + +	[SPL_EXPORT_FDT] = (const char * []) { +#ifdef CONFIG_OF_LIBFDT +		"start", +		"loados", +	#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH +		"ramdisk", +	#endif +		"fdt", +		"cmdline", +		"bdt", +		"prep", +#endif +		NULL, +	}, +	[SPL_EXPORT_ATAGS] = (const char * []) { +#if defined(CONFIG_SETUP_MEMORY_TAGS) || \ +	defined(CONFIG_CMDLINE_TAG) || \ +	defined(CONFIG_INITRD_TAG) || \ +	defined(CONFIG_SERIAL_TAG) || \ +	defined(CONFIG_REVISION_TAG) +		"start", +		"loados", +#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH +		"ramdisk", +#endif +		"cmdline", +		"bdt", +		"prep", +#endif +		NULL, +	}, +	NULL +}; + +/* Calls bootm with the parameters given */ +static int call_bootm(int argc, char * const argv[], const char *subcommand[]) +{ +	char *bootm_argv[5]; + +	int i = 0; +	int ret = 0; +	int j; + +	/* create paramter array */ +	bootm_argv[0] = "do_bootm"; +	switch (argc) { +	case 3: +		bootm_argv[4] = argv[2]; /* fdt addr */ +	case 2: +		bootm_argv[3] = argv[1]; /* initrd addr */ +	case 1: +		bootm_argv[2] = argv[0]; /* kernel addr */ +	} + + +	/* +	 * - do the work - +	 * exec subcommands of do_bootm to init the images +	 * data structure +	 */ +	while (subcommand[i] != NULL) { +		bootm_argv[1] = (char *)subcommand[i]; +		debug("args %d: %s %s ", argc, bootm_argv[0], bootm_argv[1]); +		for (j = 0; j < argc; j++) +			debug("%s ", bootm_argv[j + 2]); +		debug("\n"); + +		ret = do_bootm(find_cmd("do_bootm"), 0, argc+2, +			bootm_argv); +		debug("Subcommand retcode: %d\n", ret); +		i++; +	} + +	if (ret) { +		printf("ERROR prep subcommand failed!\n"); +		return -1; +	} + +	return 0; +} + +static cmd_tbl_t cmd_spl_export_sub[] = { +	U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""), +	U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""), +}; + +static int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	const cmd_tbl_t *c; + +	if (argc < 2) /* no subcommand */ +		return cmd_usage(cmdtp); + +	c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0], +		ARRAY_SIZE(cmd_spl_export_sub)); +	if ((c) && ((int)c->cmd <= SPL_EXPORT_LAST)) { +		argc -= 2; +		argv += 2; +		if (call_bootm(argc, argv, subcmd_list[(int)c->cmd])) +			return -1; +		switch ((int)c->cmd) { +		case SPL_EXPORT_FDT: +			printf("Argument image is now in RAM: 0x%p\n", +				(void *)images.ft_addr); +			break; +		case SPL_EXPORT_ATAGS: +			printf("Argument image is now in RAM at: 0x%p\n", +				(void *)gd->bd->bi_boot_params); +			break; +		} +	} else { +		/* Unrecognized command */ +		return cmd_usage(cmdtp); +	} + +	return 0; +} + +static cmd_tbl_t cmd_spl_sub[] = { +	U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""), +}; + +static int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	const cmd_tbl_t *c; +	int cmd; + +	if (argc < 2) /* no subcommand */ +		return cmd_usage(cmdtp); + +	c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub)); +	if (c) { +		cmd = (int)c->cmd; +		switch (cmd) { +		case SPL_EXPORT: +			argc--; +			argv++; +			if (spl_export(cmdtp, flag, argc, argv)) +				printf("Subcommand failed\n"); +			break; +		default: +			/* unrecognized command */ +			return cmd_usage(cmdtp); +		} +	} else { +		/* Unrecognized command */ +		return cmd_usage(cmdtp); +	} +	return 0; +} + +U_BOOT_CMD( +	spl, 6 , 1, do_spl, "SPL configuration", +	"export <img=atags|fdt> [kernel_addr] [initrd_addr] " +	"[fdt_addr if <img> = fdt] - export a kernel parameter image\n" +	"\t initrd_img can be set to \"-\" if fdt_addr without initrd img is" +	"used"); diff --git a/common/env_fat.c b/common/env_fat.c new file mode 100644 index 000000000..bad92aa89 --- /dev/null +++ b/common/env_fat.c @@ -0,0 +1,156 @@ +/* + * (c) Copyright 2011 by Tigris Elektronik GmbH + * + * Author: + *  Maximilian Schwerin <mvs@tigris.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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> +#include <environment.h> +#include <linux/stddef.h> +#include <malloc.h> +#include <search.h> +#include <errno.h> +#include <fat.h> +#include <mmc.h> + +char *env_name_spec = "FAT"; + +env_t *env_ptr; + +DECLARE_GLOBAL_DATA_PTR; + +uchar env_get_char_spec(int index) +{ +	return *((uchar *)(gd->env_addr + index)); +} + +int env_init(void) +{ +	/* use default */ +	gd->env_addr = (ulong)&default_environment[0]; +	gd->env_valid = 1; + +	return 0; +} + +#ifdef CONFIG_CMD_SAVEENV +int saveenv(void) +{ +	env_t	env_new; +	ssize_t	len; +	char	*res; +	block_dev_desc_t *dev_desc = NULL; +	int dev = FAT_ENV_DEVICE; +	int part = FAT_ENV_PART; + +	res = (char *)&env_new.data; +	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); +	if (len < 0) { +		error("Cannot export environment: errno = %d\n", errno); +		return 1; +	} + +#ifdef CONFIG_MMC +	if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { +		struct mmc *mmc = find_mmc_device(dev); + +		if (!mmc) { +			printf("no mmc device at slot %x\n", dev); +			return 1; +		} + +		mmc->has_init = 0; +		mmc_init(mmc); +	} +#endif /* CONFIG_MMC */ + +	dev_desc = get_dev(FAT_ENV_INTERFACE, dev); +	if (dev_desc == NULL) { +		printf("Failed to find %s%d\n", +			FAT_ENV_INTERFACE, dev); +		return 1; +	} +	if (fat_register_device(dev_desc, part) != 0) { +		printf("Failed to register %s%d:%d\n", +			FAT_ENV_INTERFACE, dev, part); +		return 1; +	} + +	env_new.crc = crc32(0, env_new.data, ENV_SIZE); +	if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) { +		printf("\n** Unable to write \"%s\" from %s%d:%d **\n", +			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); +		return 1; +	} + +	puts("done\n"); +	return 0; +} +#endif /* CONFIG_CMD_SAVEENV */ + +void env_relocate_spec(void) +{ +	char buf[CONFIG_ENV_SIZE]; +	block_dev_desc_t *dev_desc = NULL; +	int dev = FAT_ENV_DEVICE; +	int part = FAT_ENV_PART; + +#ifdef CONFIG_MMC +	if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { +		struct mmc *mmc = find_mmc_device(dev); + +		if (!mmc) { +			printf("no mmc device at slot %x\n", dev); +			set_default_env(NULL); +			return; +		} + +		mmc->has_init = 0; +		mmc_init(mmc); +	} +#endif /* CONFIG_MMC */ + +	dev_desc = get_dev(FAT_ENV_INTERFACE, dev); +	if (dev_desc == NULL) { +		printf("Failed to find %s%d\n", +			FAT_ENV_INTERFACE, dev); +		set_default_env(NULL); +		return; +	} +	if (fat_register_device(dev_desc, part) != 0) { +		printf("Failed to register %s%d:%d\n", +			FAT_ENV_INTERFACE, dev, part); +		set_default_env(NULL); +		return; +	} + +	if (file_fat_read(FAT_ENV_FILE, (unsigned char *)&buf, CONFIG_ENV_SIZE) == -1) { +		printf("\n** Unable to read \"%s\" from %s%d:%d **\n", +			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part); +		set_default_env(NULL); +		return; +	} + +	env_import(buf, 1); +} diff --git a/common/image.c b/common/image.c index 8c644b7da..342b31591 100644 --- a/common/image.c +++ b/common/image.c @@ -797,6 +797,9 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  	ulong rd_addr, rd_load;  	ulong rd_data, rd_len;  	const image_header_t *rd_hdr; +#ifdef CONFIG_SUPPORT_RAW_INITRD +	char *end; +#endif  #if defined(CONFIG_FIT)  	void		*fit_hdr;  	const char	*fit_uname_config = NULL; @@ -994,9 +997,17 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  			break;  #endif  		default: -			puts("Wrong Ramdisk Image Format\n"); -			rd_data = rd_len = rd_load = 0; -			return 1; +#ifdef CONFIG_SUPPORT_RAW_INITRD +			if (argc >= 3 && (end = strchr(argv[2], ':'))) { +				rd_len = simple_strtoul(++end, NULL, 16); +				rd_data = rd_addr; +			} else +#endif +			{ +				puts("Wrong Ramdisk Image Format\n"); +				rd_data = rd_len = rd_load = 0; +				return 1; +			}  		}  	} else if (images->legacy_hdr_valid &&  			image_check_type(&images->legacy_hdr_os_copy,  |