[U-Boot] [PATCH V12 05/14] omap-common/spl: Add linux boot to SPL
Stefano Babic
sbabic at denx.de
Wed Jan 4 09:25:09 CET 2012
From: Simon Schwarz <simonschwarzcor at googlemail.com>
This adds Linux booting to the SPL
This depends on CONFIG_MACH_TYPE patch by Igor Grinberg
(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
Related CONFIGs:
CONFIG_SPL_OS_BOOT
Activates/Deactivates the OS booting feature
CONFIG_SPL_OS_BOOT_KEY
defines the IO-pin number u-boot switch - if pressed u-boot is
booted
CONFIG_SYS_NAND_SPL_KERNEL_OFFS
Offset in NAND of direct boot kernel image to use in SPL
CONFIG_SYS_SPL_ARGS_ADDR
Address where the kernel boot arguments are expected - this is
normaly RAM-begin + 0x100
Signed-off-by: Simon Schwarz <simonschwarzcor at gmail.com>
CC: Tom Rini <tom.rini at gmail.com>
CC: Stefano Babic <sbabic at denx.de>
CC: Wolfgang Denk <wd at denx.de>
---
V2 changes:
nothing
V3 changes:
nothing
V4 changes:
CHG Using CONFIG_MACH_TYPE now.
DEL CONFIG_SYS_SPL_MACHID
CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch
depending on the patch linked above
V5 changes:
FIX compile errors for OMAP4
REBASE u-boot-ti adapted new general gpio interface
V6 changes:
nothing
V7 changes:
FIX multiline comment style
(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
V8 changes:
REBASE on u-boot
V9 changes:
nothing
V10 changes:
CHG used short form to mark not returning function
DEL devkit8000 config changes from this patch
CHG spl_uboot_key renamed to spl_start_uboot and defined weak to be
implemented board specific
CHG If the Linux image for the direct OS boot is not found the SPL tries
to load a u-boot image
CHG %X in %p in debug message
V11 changes:
U-Boot was always started instead of Linux
arch/arm/cpu/armv7/omap-common/spl.c | 49 +++++++++++++++++++++++++-
arch/arm/cpu/armv7/omap-common/spl_nand.c | 53 ++++++++++++++++------------
arch/arm/include/asm/omap_common.h | 1 +
3 files changed, 78 insertions(+), 25 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index 9c35a09..955a83b 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -35,6 +35,7 @@
#include <i2c.h>
#include <image.h>
#include <malloc.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,25 @@ void board_init_f(ulong dummy)
relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
}
+/*
+ * Default function to determine if u-boot or the OS should
+ * be started. This implementation always returns 1.
+ *
+ * Please implement your own board specific funcion to do this.
+ *
+ * RETURN
+ * 0 to not start u-boot
+ * positive if u-boot should start
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+__weak int spl_start_uboot(void)
+{
+ printf("SPL: Please implement spl_start_uboot() for your board\n");
+ printf("SPL: Direct Linux boot not active!\n");
+ return 1;
+}
+#endif
+
void spl_parse_image_header(const struct image_header *header)
{
u32 header_size = sizeof(struct image_header);
@@ -91,7 +111,25 @@ void spl_parse_image_header(const struct image_header *header)
}
}
-static void jump_to_image_no_args(void)
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ * arg: Pointer to paramter image in RAM
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+__noreturn void jump_to_image_linux(void *arg)
+{
+ debug("Entering kernel arg pointer: 0x%p\n", arg);
+ typedef void (*image_entry_arg_t)(int, int, void *)
+ __attribute__ ((noreturn));
+ image_entry_arg_t image_entry =
+ (image_entry_arg_t) spl_image.entry_point;
+ /* cleanup_before_linux(); */ /*write SPL function for that*/
+ image_entry(0, CONFIG_MACH_TYPE, arg);
+}
+#endif
+
+void jump_to_image_no_args(void)
{
typedef void (*image_entry_noargs_t)(u32 *)__attribute__ ((noreturn));
image_entry_noargs_t image_entry =
@@ -105,8 +143,8 @@ static void jump_to_image_no_args(void)
u32 boot_params_ptr_addr = (u32)&boot_params_ptr;
image_entry((u32 *)boot_params_ptr_addr);
}
-
void jump_to_image_no_args(void) __attribute__ ((noreturn));
+
void board_init_r(gd_t *id, ulong dummy)
{
u32 boot_device;
@@ -146,6 +184,13 @@ void board_init_r(gd_t *id, ulong dummy)
debug("Jumping to U-Boot\n");
jump_to_image_no_args();
break;
+#ifdef CONFIG_SPL_OS_BOOT
+ case IH_OS_LINUX:
+ debug("Jumping to Linux\n");
+ spl_board_prepare_for_linux();
+ jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+ break;
+#endif
default:
puts("Unsupported OS image.. Jumping nevertheless..\n");
jump_to_image_no_args();
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
index 2a66214..1295e88 100644
--- a/arch/arm/cpu/armv7/omap-common/spl_nand.c
+++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
@@ -29,7 +29,6 @@
#include <version.h>
#include <asm/omap_common.h>
-
void spl_nand_load_image(void)
{
struct image_header *header;
@@ -50,7 +49,7 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
#ifdef CONFIG_SPL_OS_BOOT
- if (!spl_uboot_key()) {
+ if (!spl_start_uboot()) {
/*
* load parameter image
* load to temp position since nand_spl_load_image reads
@@ -74,31 +73,39 @@ void spl_nand_load_image(void)
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header);
- nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
- } else
+ if (header->ih_os == IH_OS_LINUX) {
+ /* happy - was a linux */
+ nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+ spl_image.size, (void *)spl_image.load_addr);
+ nand_deselect();
+ return;
+ } else {
+ printf("The Expected Linux image was not"
+ "found. Please check your NAND"
+ "configuration.\n");
+ printf("Trying to start u-boot now...\n");
+ }
+ }
#endif
- {
#ifdef CONFIG_NAND_ENV_DST
- nand_spl_load_image(CONFIG_ENV_OFFSET,
- CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
- spl_parse_image_header(header);
- nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
- (void *)spl_image.load_addr);
+ nand_spl_load_image(CONFIG_ENV_OFFSET,
+ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+ spl_parse_image_header(header);
+ nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
+ (void *)spl_image.load_addr);
#ifdef CONFIG_ENV_OFFSET_REDUND
- nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
- CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
- spl_parse_image_header(header);
- nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
- (void *)spl_image.load_addr);
+ nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
+ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+ spl_parse_image_header(header);
+ nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
+ (void *)spl_image.load_addr);
#endif
#endif
- /* Load u-boot */
- nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
- CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
- spl_parse_image_header(header);
- nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
- }
+ /* Load u-boot */
+ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+ CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+ spl_parse_image_header(header);
+ nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+ spl_image.size, (void *)spl_image.load_addr);
nand_deselect();
}
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 62200e5..8a7d1e5 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -89,6 +89,7 @@ void spl_parse_image_header(const struct image_header *header);
void omap_rev_string(char *omap_rev_string);
int spl_uboot_key(void);
void spl_board_prepare_for_linux(void);
+int spl_start_uboot(void);
/* NAND SPL functions */
void spl_nand_load_image(void);
--
1.7.5.4
More information about the U-Boot
mailing list