Hello Simon, Simon Schwarz wrote: > for my bachelor thesis I will implement a direct Linux boot from U-Boot SPL. > My current plan is to utilize do_bootm_[OS]. > > Simplest solution is to direct boot Linux/other OS and just boot > u-boot when a key is pressed. In addition i will also have some tests > (header check/CRC) - if they fail start u-boot. > > IMHO this may also be of interest for the new SPL architecture. > > Are there already implementations I am not aware of? Any comments on > what I should also add? Problems I may not see?
I tried this on an davinci dm368 based board (not in mainline yet, but patches for the board support coming soon), with the following patch: >From 684cb207b14585f9d83f2c4c6f72b5b8bd4fd1a0 Mon Sep 17 00:00:00 2001 From: Heiko Schocher <h...@denx.de> Date: Mon, 30 May 2011 08:26:10 +0200 Subject: [PATCH] boot an arm linux kernel direct from nand_spl code 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 <h...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot