Hi Heiko, just one more thing I forgot to mention...
On Tue, Jan 12, 2016 at 10:08:21AM +0100, Heiko Schocher wrote: > Am 11.01.2016 um 13:58 schrieb Ladislav Michl: [...] > >All that ubispl_info structure is board specific and there is not much left > >besides initializing it. Also volumes can differ per board basis, so > >providing common function is somewhat questionable. However here it is, > >just to show how does it look like. Suggestions are very welcome as silence > >around this part of patch is a bit suspicious ;-) > > Questions are coming if there are users ;-) > > I vote for bringing this in, and we will see, where we have to make > things more configurable ... some nitpicks below ... I wouldn't make payload loading function completely board specific as we would face danger of copying similar pattern over and over for every board wanting to support ubispl without anyone even considering consolidation. History of U-Boot proves that happens :) So lets's make payload loading function decently generic which will force users to improve it and eventuelly provide their own as a last option. Also let's not pretend code works on anything but NAND, so patch would boil down to something like this: commit 9fd0671cb68e14d3238867173a8ecdaf0f4695af Author: Ladislav Michl <la...@linux-mips.org> Date: Mon Jan 11 13:08:10 2016 +0100 spl: support loading from UBI volumes Add support for loading from UBI volumes on the top of NAND. Signed-off-by: Ladislav Michl <la...@linux-mips.org> diff --git a/common/spl/Makefile b/common/spl/Makefile index 10a4589..36e5338 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -12,8 +12,11 @@ ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_FRAMEWORK) += spl.o obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +ifndef CONFIG_SPL_UBI obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +endif obj-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o +obj-$(CONFIG_SPL_UBI) += spl_ubi.o obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o diff --git a/common/spl/spl.c b/common/spl/spl.c index 6e6dee7..7665105 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -288,8 +288,12 @@ static int spl_load_image(u32 boot_device) #endif #ifdef CONFIG_SPL_NAND_SUPPORT case BOOT_DEVICE_NAND: +#ifdef CONFIG_SPL_UBI + return spl_ubi_load_image(boot_device); +#else return spl_nand_load_image(); #endif +#endif #ifdef CONFIG_SPL_ONENAND_SUPPORT case BOOT_DEVICE_ONENAND: return spl_onenand_load_image(); diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c new file mode 100644 index 0000000..7b6eb31 --- /dev/null +++ b/common/spl/spl_ubi.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 + * Ladislav Michl <la...@linux-mips.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <config.h> +#include <nand.h> +#include <ubispl.h> +#include <spl.h> + +int spl_ubi_load_image(u32 boot_device) +{ + int ret; + struct image_header *header; + struct ubispl_info info; + struct ubispl_load volumes[2]; + +#ifdef CONFIG_SPL_NAND_SUPPORT + if (boot_device == BOOT_DEVICE_NAND) + nand_init(); +#endif + info.ubi = (struct ubi_scan_info *) CONFIG_SPL_UBI_INFO_ADDR; + info.fastmap = 1; + info.read = nand_spl_read_block; + + info.peb_offset = CONFIG_SPL_UBI_PEB_OFFSET; + info.peb_size = CONFIG_SYS_NAND_BLOCK_SIZE; + info.vid_offset = CONFIG_SPL_UBI_VID_OFFSET; + info.leb_start = CONFIG_SPL_UBI_LEB_START; + info.peb_count = CONFIG_SPL_UBI_MAX_PEBS - info.peb_offset; + +#ifdef CONFIG_SPL_OS_BOOT + if (!spl_start_uboot()) { + volumes[0].name = "kernel"; + volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_KERNEL_ID; + volumes[0].load_addr = (void *)CONFIG_SYS_LOAD_ADDR; + volumes[1].name = "args"; + volumes[1].vol_id = CONFIG_SPL_UBI_LOAD_ARGS_ID; + volumes[1].load_addr = (void *)CONFIG_SYS_SPL_ARGS_ADDR; + + ret = ubispl_load_volumes(&info, volumes, 2); + if (!ret) { + header = (struct image_header *) volumes[0].load_addr; + spl_parse_image_header(header); + puts("Linux loaded.\n"); + goto out; + } + puts("Loading Linux failed, falling back to U-Boot.\n"); + } +#endif + header = (struct image_header *) + (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); + volumes[0].name = "monitor"; + volumes[0].vol_id = CONFIG_SPL_UBI_LOAD_MONITOR_ID; + volumes[0].load_addr = (void *)header; + + ret = ubispl_load_volumes(&info, volumes, 1); + if (!ret) + spl_parse_image_header(header); +#ifdef CONFIG_SPL_OS_BOOT +out: +#endif +#ifdef CONFIG_SPL_NAND_SUPPORT + if (boot_device == BOOT_DEVICE_NAND) + nand_deselect(); +#endif + return ret; +} diff --git a/include/spl.h b/include/spl.h index 92cdc04..1ab9295 100644 --- a/include/spl.h +++ b/include/spl.h @@ -40,6 +40,7 @@ u32 spl_boot_mode(void); void spl_set_header_raw_uboot(void); void spl_parse_image_header(const struct image_header *header); void spl_board_prepare_for_linux(void); +int spl_board_ubi_load_image(u32 boot_device); void __noreturn jump_to_image_linux(void *arg); int spl_start_uboot(void); void spl_display_print(void); @@ -53,6 +54,9 @@ int spl_onenand_load_image(void); /* NOR SPL functions */ int spl_nor_load_image(void); +/* UBI SPL functions */ +int spl_ubi_load_image(u32 boot_device); + /* MMC SPL functions */ int spl_mmc_load_image(u32 boot_device); _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot