omap-common/spl: Add linux boot to SPL

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@gmail.com>
CC: Tom Rini <tom.rini@gmail.com>
CC: Stefano Babic <sbabic@denx.de>
CC: Wolfgang Denk <wd@denx.de>
This commit is contained in:
Simon Schwarz 2012-03-15 04:01:38 +00:00 committed by Albert ARIBAUD
parent 9e70c08b6f
commit 379c19ab70
3 changed files with 79 additions and 27 deletions

View File

@ -65,6 +65,25 @@ void board_init_f(ulong dummy)
relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); 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) void spl_parse_image_header(const struct image_header *header)
{ {
u32 header_size = sizeof(struct image_header); u32 header_size = sizeof(struct image_header);
@ -92,6 +111,24 @@ void spl_parse_image_header(const struct image_header *header)
} }
} }
/*
* 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
static void __noreturn 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
static void __noreturn jump_to_image_no_args(void) static void __noreturn jump_to_image_no_args(void)
{ {
typedef void __noreturn (*image_entry_noargs_t)(u32 *); typedef void __noreturn (*image_entry_noargs_t)(u32 *);
@ -149,6 +186,13 @@ void board_init_r(gd_t *id, ulong dummy)
debug("Jumping to U-Boot\n"); debug("Jumping to U-Boot\n");
jump_to_image_no_args(); jump_to_image_no_args();
break; 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: default:
puts("Unsupported OS image.. Jumping nevertheless..\n"); puts("Unsupported OS image.. Jumping nevertheless..\n");
jump_to_image_no_args(); jump_to_image_no_args();

View File

@ -29,7 +29,6 @@
#include <version.h> #include <version.h>
#include <asm/omap_common.h> #include <asm/omap_common.h>
void spl_nand_load_image(void) void spl_nand_load_image(void)
{ {
struct image_header *header; struct image_header *header;
@ -50,7 +49,7 @@ void spl_nand_load_image(void)
/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
#ifdef CONFIG_SPL_OS_BOOT #ifdef CONFIG_SPL_OS_BOOT
if (!spl_uboot_key()) { if (!spl_start_uboot()) {
/* /*
* load parameter image * load parameter image
* load to temp position since nand_spl_load_image reads * 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, nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
spl_parse_image_header(header); spl_parse_image_header(header);
nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, if (header->ih_os == IH_OS_LINUX) {
spl_image.size, (void *)spl_image.load_addr); /* happy - was a linux */
} else nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
#endif spl_image.size, (void *)spl_image.load_addr);
{ nand_deselect();
#ifdef CONFIG_NAND_ENV_DST return;
nand_spl_load_image(CONFIG_ENV_OFFSET, } else {
CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); printf("The Expected Linux image was not"
spl_parse_image_header(header); "found. Please check your NAND"
nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, "configuration.\n");
(void *)spl_image.load_addr); printf("Trying to start u-boot now...\n");
#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);
#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);
} }
#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);
#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);
#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);
nand_deselect(); nand_deselect();
} }

View File

@ -93,6 +93,7 @@ u32 omap_boot_mode(void);
void spl_parse_image_header(const struct image_header *header); void spl_parse_image_header(const struct image_header *header);
void omap_rev_string(void); void omap_rev_string(void);
void spl_board_prepare_for_linux(void); void spl_board_prepare_for_linux(void);
int spl_start_uboot(void);
/* NAND SPL functions */ /* NAND SPL functions */
void spl_nand_load_image(void); void spl_nand_load_image(void);