[U-Boot] [PATCH] arm: Adds saving of Kernel boot args to NAND flash

Simon Schwarz simonschwarzcor at googlemail.com
Tue Jul 5 15:20:39 CEST 2011


Adds the saving of either ATAGS or FDT kernel argument image to NAND flash.
This image then can be used in SPL boot.

This adds two CONFIG_ paramter to board configuration (in this RFC as example added to devkit8000.h):
CONFIG_SAVE_BOOT_ARGS		makes the feature active
CONFIG_BOOT_ARGS_NAND_OFS	defines the offset in NAND flash where the image
	is saved

For OMAP34XX the image is saved with hw-ecc.

Signed-off-by: Simon Schwarz <simonschwarzcor at gmail.com>
---
This is an RFC on how this can be done.

What I don't like here is the omap specific hw ecc switch. But the nand-spl has just hw-ecc yet - at least afaik.

Belonging discussion: http://marc.info/?t=130942998000003

Regards
Simon

 arch/arm/lib/bootm.c         |   64 ++++++++++++++++++++++++++++++++++++++++++
 include/configs/devkit8000.h |    4 ++
 2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 802e833..57e08d3 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -5,6 +5,10 @@
  *
  * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw at its.tudelft.nl)
  *
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz at corscience.de>
+ * - added saving of kernel-parameter-image to NAND flash
+ *
  * 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
@@ -30,6 +34,14 @@
 #include <libfdt.h>
 #include <fdt_support.h>
 
+#ifdef CONFIG_SAVE_BOOT_ARGS
+#include <nand.h>
+#include <asm/setup.h>
+#ifdef CONFIG_OMAP34XX
+#include <asm/arch/sys_proto.h>
+#endif
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined (CONFIG_SETUP_MEMORY_TAGS) || \
@@ -58,6 +70,38 @@ static ulong get_sp(void);
 static int bootm_linux_fdt(int machid, bootm_headers_t *images);
 #endif
 
+#ifdef CONFIG_SAVE_BOOT_ARGS
+/* This function writes given bootparams to NAND flash
+ *  adr: Start adress of Kernel parameter image (ATAGS, FDT)
+ *  length: length of the image in byte
+ *
+ * borrowd heavily from common/cmd_nand.c
+ */
+void boot_params_to_nand(u_char *adr, size_t length) {
+	nand_info_t *nand = &nand_info[nand_curr_device]; /* use current dev */
+	loff_t off = CONFIG_BOOT_ARGS_NAND_OFS;
+	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);
+}
+#endif /* CONFIG_SAVE_BOOT_ARGS */
+
 void arch_lmb_reserve(struct lmb *lmb)
 {
 	ulong sp;
@@ -104,6 +148,10 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 	char *commandline = getenv ("bootargs");
 #endif
 
+#ifdef CONFIG_SAVE_BOOT_ARGS
+	struct tag *t;
+	size_t size=0;
+#endif
 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
 		return 1;
 
@@ -150,6 +198,17 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 	setup_end_tag(bd);
 #endif
 
+#ifdef CONFIG_SAVE_BOOT_ARGS
+	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! */
+	boot_params_to_nand((u_char *)bd->bi_boot_params, size);
+#endif
+
 	announce_and_cleanup();
 
 	kernel_entry(0, machid, bd->bi_boot_params);
@@ -208,6 +267,11 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images)
 
 	fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
 
+#ifdef CONFIG_SAVE_BOOT_ARGS
+	printf("write FDT to NAND...\n");
+	boot_params_to_nand((u_char *)(*of_flat_tree),of_size);
+#endif
+
 	announce_and_cleanup();
 
 	kernel_entry(0, machid, *of_flat_tree);
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 1bf6bea..3061fc2 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -345,4 +345,8 @@
 		                                         CONFIG_SYS_INIT_RAM_SIZE - \
 		                                         GENERATED_GBL_DATA_SIZE)
 
+/* Direct OS boot options */
+#define CONFIG_SAVE_BOOT_ARGS
+#define CONFIG_BOOT_ARGS_NAND_OFS			0x700000
+
 #endif /* __CONFIG_H */
-- 
1.7.4.1



More information about the U-Boot mailing list