summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile5
-rw-r--r--common/cmd_bootm.c143
-rw-r--r--common/cmd_fat.c57
-rw-r--r--common/cmd_log.c101
-rw-r--r--common/cmd_nvedit.c3
-rw-r--r--common/cmd_pxe.c16
-rw-r--r--common/cmd_spl.c188
-rw-r--r--common/env_fat.c156
-rw-r--r--common/image.c17
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,