From: Simon Schwarz <simonschwarz...@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 <simonschwarz...@gmail.com> CC: Tom Rini <tom.r...@gmail.com> CC: Stefano Babic <sba...@denx.de> CC: Wolfgang Denk <w...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot