diff mbox

[U-Boot,RFC,2/2] arm: Adds saving of Kernel boot args to NAND flash

Message ID 1310124687-11494-2-git-send-email-simonschwarzcor@gmail.com
State Superseded
Headers show

Commit Message

Simon Schwarz July 8, 2011, 11:31 a.m. UTC
Adds the saving of either ATAGS or FDT kernel argument image to NAND flash
This image then can be used in SPL boot.

Command savebp is added to achieve this. This inits a partial run of bootm
utilizing subcommands. The result then is saved to NAND flash.

This adds the following defines to board configuration:
CONFIG_CMD_SAVEBP                   activates the command
CONFIG_CMD_SAVEBP_ARGS_NAND_OFS   	defines the offset in NAND flash where
									the image is saved

For OMAP34XX the image is saved with hw-ecc.

---
For RFC: the FDT implementation is todo

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
---
 arch/arm/lib/Makefile        |    1 +
 arch/arm/lib/savebp.c        |  100 ++++++++++++++++++++++++++++++++++++++++++
 common/Makefile              |    2 +-
 common/cmd_savebp.c          |   97 ++++++++++++++++++++++++++++++++++++++++
 include/configs/devkit8000.h |    4 ++
 5 files changed, 203 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/lib/savebp.c
 create mode 100644 common/cmd_savebp.c
diff mbox

Patch

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 03b1b5e..ccaae4f 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -44,6 +44,7 @@  COBJS-y	+= cache-cp15.o
 endif
 COBJS-y	+= interrupts.o
 COBJS-y	+= reset.o
+COBJS-$(CONFIG_CMD_SAVEBP) += savebp.o
 SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o
 SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
 
diff --git a/arch/arm/lib/savebp.c b/arch/arm/lib/savebp.c
new file mode 100644
index 0000000..8394994
--- /dev/null
+++ b/arch/arm/lib/savebp.c
@@ -0,0 +1,100 @@ 
+/* 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 <fdt.h>*/
+/*#include <libfdt.h>*/
+/*#include <fdt_support.h>*/
+
+#ifdef CONFIG_CMD_SAVEBP
+#include <nand.h>
+#ifdef CONFIG_OMAP34XX
+#include <asm/arch/sys_proto.h>
+#endif
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+extern bootm_headers_t images; /* Struct of the Image header */
+
+/* This function writes given bootparams to NAND flash
+ *  adr: Start adress of Kernel parameter image (ATAGS, FDT)
+ *  length: length of the image in byte
+ *	off: offset in NAND flash
+ *
+ * borrowd heavily from common/cmd_nand.c
+ */
+void boot_params_to_nand(u_char *adr, size_t length, loff_t off)
+{
+    nand_info_t *nand = &nand_info[nand_curr_device]; /* use current dev */
+    nand_erase_options_t opts;
+
+#ifdef CONFIG_OMAP34XX
+    omap_nand_switch_ecc(1); /* use hw ecc on omap for SPL compat */
+#endif
+    /* erase */
+    memset(&opts, 0, sizeof(opts));
+    opts.offset = off;
+    opts.length = length;
+    opts.quiet = 1;
+    opts.spread = 1;
+    nand_erase_opts(nand, &opts);
+
+    /* write */
+    if (nand_write_skip_bad(nand, off, &length, adr, 0))
+        printf("FAILED!\n");
+
+    printf("Written to offset 0x%llX, size: %d bytes\n",
+        off, length);
+}
+
+/* Saves FDT to NAND */
+int do_savebp_fdt(loff_t offset)
+{
+	printf(">>>do_save_params_fdt()");
+	printf("NOT IMPLEMENTED YET!");
+	printf("<<<do_save_params_fdt()");
+	return 0;
+}
+
+
+/* Saves ATAGS to NAND */
+int do_savebp_atags(loff_t offset, bootm_headers_t *images)
+{
+	/* Vars */
+	struct tag *t;
+	size_t size = 0;
+	bd_t *bd = gd->bd;
+
+    printf("write ATAGS to NAND...\n");
+
+    /* get size of atags */
+    for_each_tag(t, (struct tag *)(bd->bi_boot_params))
+        size += t->hdr.size;
+    size += 2; /* ATAG_NONE has size 0 */
+    size *= 4;  /*  words -> byte! */
+
+	/* save em */
+    boot_params_to_nand((u_char *)bd->bi_boot_params, size, offset);
+
+	return 0;
+}
diff --git a/common/Makefile b/common/Makefile
index 224b7cc..d7719bc 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -160,6 +160,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_SAVEBP) += cmd_savebp.o 
 
 # others
 COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
@@ -174,7 +175,6 @@  COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
 COBJS-$(CONFIG_UPDATE_TFTP) += update.o
 COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 
-
 COBJS	:= $(sort $(COBJS-y))
 XCOBJS	:= $(sort $(XCOBJS-y))
 SRCS	:= $(COBJS:.o=.c) $(XCOBJS:.o=.c)
diff --git a/common/cmd_savebp.c b/common/cmd_savebp.c
new file mode 100644
index 0000000..b8233f8
--- /dev/null
+++ b/common/cmd_savebp.c
@@ -0,0 +1,97 @@ 
+/* 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>
+
+#define TYPE_FDT	0
+#define TYPE_ATAGS	1
+
+extern bootm_headers_t images;
+
+static inline int str2off(const char *p, loff_t *num)
+{
+    char *endptr;
+
+    *num = simple_strtoull(p, &endptr, 16);
+    return *p != '\0' && *endptr == '\0';
+}
+
+int do_savebp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	loff_t offset;
+	char * bootm_argsv[] = {"do_bootm","xxxxxxx"};
+
+	/* - Validate args - */
+	if (argc == 2) {
+		if (!str2off(argv[2], &offset)) {
+			printf("'%s' is not a number\n",argv[2]);
+			return cmd_usage(cmdtp);
+		}
+	} else if (argc == 1) {
+		offset = (loff_t)CONFIG_CMD_SAVEBP_NAND_OFS;
+		printf("using standard destination at: 0x%x\n", (uint32_t)offset);
+	} else
+		return cmd_usage(cmdtp);
+
+	/* - do the work - */
+	/* exec bootm_start as subcommand of do_bootm to init the images
+	 * data structure */
+	bootm_argsv[1] = "start";
+	if(do_bootm(find_cmd("do_bootm"),0,2,bootm_argsv))
+		printf("ERROR: subcommand start of bootm failed\n");
+
+	bootm_argsv[1] = "loados";
+	if(do_bootm(find_cmd("do_bootm"),0,2,bootm_argsv))
+		printf("ERROR: subcommand loados of bootm failed\n");
+
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+    bootm_argsv[1] = "ramdisk";
+	if(do_bootm(find_cmd("do_bootm"),0,2,bootm_argsv))
+		printf("ERROR: subcommand ramdisk of bootm failed\n");
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+    bootm_argsv[1] = "fdt";
+	if(do_bootm(find_cmd("do_bootm"),0,2,bootm_argsv))
+		printf("ERROR: subcommand fdt of bootm failed\n");
+#endif
+
+	/*subcommand cmdline and bdt are not implemented*/
+
+	bootm_argsv[1] = "prep";
+	if(do_bootm(find_cmd("do_bootm"),0,2,bootm_argsv))
+		printf("ERROR: subcommand prep of bootm failed\n");
+
+	/* call arch specific handlers */
+#ifdef CONFIG_OF_LIBFDT
+	/*do_savebp_fdt(offset);*/
+#else
+	do_savebp_atags(offset, &images);
+#endif
+	return 0;
+}
+
+U_BOOT_CMD(
+	savebp,3,1,do_savebp,"save boot params to NAND flash",
+	"[nand_offset] saves the parameter image to NAND. \
+		Kernel image has to be in RAM!");
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 1bf6bea..ff6d750 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -194,6 +194,7 @@ 
 #define CONFIG_CMD_MTDPARTS		/* Enable MTD parts commands	*/
 #define CONFIG_CMD_NAND			/* NAND support			*/
 #define CONFIG_CMD_NAND_LOCK_UNLOCK	/* nand (un)lock commands	*/
+#define CONFIG_CMD_SAVEBP	/* Save kernel params command */
 
 #undef CONFIG_CMD_FPGA			/* FPGA configuration Support	*/
 #undef CONFIG_CMD_IMI			/* iminfo			*/
@@ -345,4 +346,7 @@ 
 		                                         CONFIG_SYS_INIT_RAM_SIZE - \
 		                                         GENERATED_GBL_DATA_SIZE)
 
+/* Direct OS boot options */
+#define CONFIG_CMD_SAVEBP_NAND_OFS			0x700000
+
 #endif /* __CONFIG_H */