
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@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@its.tudelft.nl) * + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz schwarz@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 */