[PATCH] boot an arm linux kernel direct from nand_spl code
Heiko Schocher
hs at denx.de
Mon May 30 08:26:10 CEST 2011
you need 2 images in Flash:
- Linux image @CONFIG_SYS_NAND_LINUX_OFFS
- ATAG image @CONFIG_SYS_NAND_ATAG_OFFS
ATAG image is just a copy from the ATAG info u-boot
created, before booting an arm linux kernel ...
ToDo/suggestions:
- we should define a struct, which contains the 3 values
offset, size, destination, so we can create a "nand_load_list"
which can contain n entries, that could be processed in
a while loop ... so no need for the CONFIG_SYS_BOOT_LINUX
define ;-)
For example:
{
{CONFIG_SYS_NAND_LINUX_OFFS,
CONFIG_SYS_NAND_LINUX_SIZE,
CONFIG_SYS_NAND_LINUX_DST},
{CONFIG_SYS_NAND_ATAG_OFFS,
CONFIG_SYS_NAND_ATAG_SIZE,
CONFIG_SYS_NAND_ATAG_DST},
{}
} nand_load_list_linux;
{
{CONFIG_SYS_NAND_U_BOOT_OFFS,
CONFIG_SYS_NAND_U_BOOT_SIZE,
CONFIG_SYS_NAND_U_BOOT_DST},
#ifdef CONFIG_NAND_ENV_DST
{CONFIG_ENV_OFFSET,
CONFIG_ENV_SIZE,
CONFIG_NAND_ENV_DST},
#ifdef CONFIG_ENV_OFFSET_REDUND
{CONFIG_ENV_OFFSET_REDUND,
CONFIG_ENV_SIZE,
CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE},
#endif
#endif
{}
}nand_load_list_uboot;
in nand_boot() we can now for example get the state from a GPIO
pin, and boot "linux/atag" or the "u-boot/env/env-red" case, or
others (for example "powerpclinux/dtb")
if (gpio == bootlinux)
nand_list = &nand_load_list_linux;
else
nand_list = &nand_load_list_uboot
while (nand_list) {
nand_load((&nand_info,
nand_list->off,
nand_list->size,
nand_list->dest);
}
Signed-off-by: Heiko Schocher <hs at denx.de>
---
diff --git a/include/configs/board_config.h b/include/configs/board_config.h
index fed8ac1..6f304f5 100644
--- a/include/configs/board_config.h
+++ b/include/configs/board_config.h
@@ -342,6 +342,19 @@ was ist das?
* and in nand_spl mode cpu setup is
* done in board_init_f from c code.
*/
+#define CONFIG_SYS_BOOT_LINUX
+#if defined(CONFIG_SYS_BOOT_LINUX)
+#define CONFIG_SYS_NAND_LINUX_OFFS 0x400000
+#define CONFIG_SYS_NAND_LINUX_SIZE 0x240000
+#define CONFIG_SYS_NAND_LINUX_DST 0x80008000
+
+#define CONFIG_SYS_NAND_ATAG_OFFS (CONFIG_SYS_NAND_LINUX_OFFS + CONFIG_SYS_NAND_LINUX_SIZE)
+#define CONFIG_SYS_NAND_ATAG_SIZE (CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_ATAG_DST (0x80000100)
+
+#define CONFIG_SYS_NAND_SPL_MACHID MACH_TYPE_DAVINCI_DM365_EVM
+#endif
+
/* for UBL header */
diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index c0e56e7..f78b39d 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -242,6 +239,8 @@ static int nand_load(struct mtd_info *mtd, unsigned int offs,
nand_read_page(mtd, block, page, dst);
dst += CONFIG_SYS_NAND_PAGE_SIZE;
page++;
+ if (uboot_size == CONFIG_SYS_NAND_PAGE_SIZE)
+ break;
}
page = 0;
@@ -280,6 +279,30 @@ void nand_boot(void)
if (nand_chip.select_chip)
nand_chip.select_chip(&nand_info, 0);
+#if defined(CONFIG_SYS_BOOT_LINUX)
+ {
+ __attribute__((noreturn)) void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))CONFIG_SYS_NAND_LINUX_DST;
+ /*
+ * Load Linux image from NAND into RAM
+ */
+ puts("load Linux image ...\n");
+ ret = nand_load(&nand_info, CONFIG_SYS_NAND_LINUX_OFFS, CONFIG_SYS_NAND_LINUX_SIZE,
+ (uchar *)CONFIG_SYS_NAND_LINUX_DST);
+ /*
+ * Load ATAG image from NAND into RAM
+ */
+ puts("load ATAG image ...\n");
+ ret = nand_load(&nand_info, CONFIG_SYS_NAND_ATAG_OFFS, CONFIG_SYS_NAND_ATAG_SIZE,
+ (uchar *)CONFIG_SYS_NAND_ATAG_DST);
+
+
+ puts("booting Linux ....\n");
+ (kernel_entry)(0, CONFIG_SYS_NAND_SPL_MACHID, CONFIG_SYS_NAND_ATAG_DST);
+ }
+#else
+
/*
* Load U-Boot image from NAND into RAM
*/
@@ -304,4 +327,5 @@ void nand_boot(void)
*/
uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
(*uboot)();
+#endif
}
--
1.7.4.4
bye,
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
More information about the U-Boot
mailing list