[U-Boot] [PATCH V6] BOOT: Add "bootz" command to boot Linux zImage on ARM
Rob Herring
robherring2 at gmail.com
Thu Mar 15 19:51:46 CET 2012
On 03/15/2012 02:52 AM, Marek Vasut wrote:
> From: Marek Vasut <marek.vasut at gmail.com>
>
> This command boots Linux zImage from where the zImage is loaded to. Passing
> initrd and fdt is supported.
>
This is great! However, the initrd is still in the u-boot image format,
right?
If a raw initrd is supported, then we could get rid of flash-kernel on
disk-based debian/ubuntu systems. The file size is known from the
filesystem, but then needs to get to the bootz command somehow.
Rob
> Tested on i.MX28 based DENX M28EVK
> Tested on PXA270 based Voipac PXA270.
>
> NOTE: This currently only supports ARM, but other architectures can be easily
> added by defining bootz_setup().
>
> Signed-off-by: Marek Vasut <marek.vasut at gmail.com>
> Cc: Tom Warren <TWarren at nvidia.com>
> Cc: albert.u.boot at aribaud.net
> Cc: afleming at gmail.com,
> Cc: Simon Glass <sjg at chromium.org>,
> Cc: Stephen Warren <swarren at nvidia.com>
> Cc: Nicolas Pitre <nico at fluxnic.net>
> Cc: Wolfgang Denk <wd at denx.de>
> Cc: Detlev Zundel <dzu at denx.de>
> ---
> README | 8 +++
> arch/arm/lib/bootm.c | 30 ++++++++++
> common/cmd_bootm.c | 141 +++++++++++++++++++++++++++++++++++++++++++---
> include/config_cmd_all.h | 1 +
> 4 files changed, 171 insertions(+), 9 deletions(-)
>
> V2: Use CONFIG_BOOTZ_MAX_KERNEL_LMB_SIZE to reserve kernel LMB
> V3: Compute the LMB size at runtime (obsoletes V2)
> Move shared code to image.c/image.h
> Sync with latest U-Boot
> V4: Add all this into cmd_bootm. Therefore, this is part of cmd_bootm (basically
> it's stripped-down version). Also, separate out arm-specific component into
> arm-specific location.
> V5: Staticize bootz_setup(), add information into README.
> V6: Make cmd_bootz() static.
>
> diff --git a/README b/README
> index 4021715..b273070 100644
> --- a/README
> +++ b/README
> @@ -3594,6 +3594,7 @@ go - start application at address 'addr'
> run - run commands in an environment variable
> bootm - boot application image from memory
> bootp - boot image via network using BootP/TFTP protocol
> +bootz - boot zImage from memory
> tftpboot- boot image via network using TFTP protocol
> and env variables "ipaddr" and "serverip"
> (and eventually "gatewayip")
> @@ -4414,6 +4415,13 @@ U-Boot supports the following image types:
> useful when you configure U-Boot to use a real shell (hush)
> as command interpreter.
>
> +Booting the Linux zImage:
> +-------------------------
> +
> +On some platforms, it's possible to boot Linux zImage. This is done
> +using the "bootz" command. The syntax of "bootz" command is the same
> +as the syntax of "bootm" command.
> +
>
> Standalone HOWTO:
> =================
> diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
> index afa0093..ec46d76 100644
> --- a/arch/arm/lib/bootm.c
> +++ b/arch/arm/lib/bootm.c
> @@ -344,3 +344,33 @@ static ulong get_sp(void)
> asm("mov %0, sp" : "=r"(ret) : );
> return ret;
> }
> +
> +#ifdef CONFIG_CMD_BOOTZ
> +
> +struct zimage_header {
> + uint32_t code[9];
> + uint32_t zi_magic;
> + uint32_t zi_start;
> + uint32_t zi_end;
> +};
> +
> +#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
> +
> +int bootz_setup(void *image, void **start, void **end)
> +{
> + struct zimage_header *zi = (struct zimage_header *)image;
> +
> + if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
> + puts("Bad Linux ARM zImage magic!\n");
> + return 1;
> + }
> +
> + *start = (void *)zi->zi_start;
> + *end = (void *)zi->zi_end;
> +
> + debug("Kernel image @ 0x%08x [ 0x%08x - 0x%08x ]\n",
> + (uint32_t)image, (uint32_t)*start, (uint32_t)*end);
> +
> + return 0;
> +}
> +#endif /* CONFIG_CMD_BOOTZ */
> diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
> index d5745b1..b49d4f7 100644
> --- a/common/cmd_bootm.c
> +++ b/common/cmd_bootm.c
> @@ -169,25 +169,25 @@ void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
>
> #define IH_INITRD_ARCH IH_ARCH_DEFAULT
>
> -static void bootm_start_lmb(void)
> -{
> #ifdef CONFIG_LMB
> +static void boot_start_lmb(bootm_headers_t *images)
> +{
> ulong mem_start;
> phys_size_t mem_size;
>
> - lmb_init(&images.lmb);
> + lmb_init(&images->lmb);
>
> mem_start = getenv_bootm_low();
> mem_size = getenv_bootm_size();
>
> - lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size);
> + lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
>
> - arch_lmb_reserve(&images.lmb);
> - board_lmb_reserve(&images.lmb);
> + arch_lmb_reserve(&images->lmb);
> + board_lmb_reserve(&images->lmb);
> +}
> #else
> -# define lmb_reserve(lmb, base, size)
> +static inline void boot_start_lmb(bootm_headers_t *images) { }
> #endif
> -}
>
> static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> {
> @@ -197,7 +197,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
> memset((void *)&images, 0, sizeof(images));
> images.verify = getenv_yesno("verify");
>
> - bootm_start_lmb();
> + boot_start_lmb(&images);
>
> /* get kernel image header, start address and length */
> os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
> @@ -1523,3 +1523,126 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[],
> return 1;
> }
> #endif
> +
> +#ifdef CONFIG_CMD_BOOTZ
> +
> +static int __bootz_setup(void *image, void **start, void **end)
> +{
> + /* Please define bootz_setup() for your platform */
> +
> + puts("Your platform's zImage format isn't supported yet!\n");
> + return -1;
> +}
> +int bootz_setup(void *image, void **start, void **end)
> + __attribute__((weak, alias("__bootz_setup")));
> +
> +/*
> + * zImage booting support
> + */
> +static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[], bootm_headers_t *images)
> +{
> + int ret;
> + void *zi_start, *zi_end;
> +
> + memset(images, 0, sizeof(bootm_headers_t));
> +
> + boot_start_lmb(images);
> +
> + /* Setup Linux kernel zImage entry point */
> + if (argc < 2) {
> + images->ep = load_addr;
> + debug("* kernel: default image load address = 0x%08lx\n",
> + load_addr);
> + } else {
> + images->ep = simple_strtoul(argv[1], NULL, 16);
> + debug("* kernel: cmdline image address = 0x%08lx\n",
> + images->ep);
> + }
> +
> + ret = bootz_setup((void *)images->ep, &zi_start, &zi_end);
> + if (ret != 0)
> + return 1;
> +
> + lmb_reserve(&images->lmb, images->ep, zi_end - zi_start);
> +
> + /* Find ramdisk */
> + ret = boot_get_ramdisk(argc, argv, images, IH_INITRD_ARCH,
> + &images->rd_start, &images->rd_end);
> + if (ret) {
> + puts("Ramdisk image is corrupt or invalid\n");
> + return 1;
> + }
> +
> +#if defined(CONFIG_OF_LIBFDT)
> + /* find flattened device tree */
> + ret = boot_get_fdt(flag, argc, argv, images,
> + &images->ft_addr, &images->ft_len);
> + if (ret) {
> + puts("Could not find a valid device tree\n");
> + return 1;
> + }
> +
> + set_working_fdt_addr(images->ft_addr);
> +#endif
> +
> + return 0;
> +}
> +
> +static int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> + ulong iflag;
> + bootm_headers_t images;
> +
> + if (bootz_start(cmdtp, flag, argc, argv, &images))
> + return 1;
> +
> + /*
> + * We have reached the point of no return: we are going to
> + * overwrite all exception vector code, so we cannot easily
> + * recover from any failures any more...
> + */
> + iflag = disable_interrupts();
> +
> +#if defined(CONFIG_CMD_USB)
> + /*
> + * turn off USB to prevent the host controller from writing to the
> + * SDRAM while Linux is booting. This could happen (at least for OHCI
> + * controller), because the HCCA (Host Controller Communication Area)
> + * lies within the SDRAM and the host controller writes continously to
> + * this area (as busmaster!). The HccaFrameNumber is for example
> + * updated every 1 ms within the HCCA structure in SDRAM! For more
> + * details see the OpenHCI specification.
> + */
> + usb_stop();
> +#endif
> +
> +#ifdef CONFIG_SILENT_CONSOLE
> + fixup_silent_linux();
> +#endif
> + arch_preboot_os();
> +
> + do_bootm_linux(0, argc, argv, &images);
> +#ifdef DEBUG
> + puts("\n## Control returned to monitor - resetting...\n");
> +#endif
> + do_reset(cmdtp, flag, argc, argv);
> +
> + return 1;
> +}
> +
> +U_BOOT_CMD(
> + bootz, CONFIG_SYS_MAXARGS, 1, do_bootz,
> + "boot Linux zImage image from memory",
> + "[addr [initrd] [fdt]]\n - boot Linux zImage stored in memory\n"
> + "\tThe argument 'initrd' is optional and specifies the address\n"
> + "\tof the initrd in memory.\n"
> +#if defined(CONFIG_OF_LIBFDT)
> + "\tWhen booting a Linux kernel which requires a flat device-tree\n"
> + "\ta third argument is required which is the address of the\n"
> + "\tdevice-tree blob. To boot that kernel without an initrd image,\n"
> + "\tuse a '-' for the second argument. If you do not pass a third\n"
> + "\ta bd_info struct will be passed instead\n"
> +#endif
> +);
> +#endif /* CONFIG_CMD_BOOTZ */
> diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
> index 9716f9c..2c6b829 100644
> --- a/include/config_cmd_all.h
> +++ b/include/config_cmd_all.h
> @@ -20,6 +20,7 @@
> #define CONFIG_CMD_BEDBUG /* Include BedBug Debugger */
> #define CONFIG_CMD_BMP /* BMP support */
> #define CONFIG_CMD_BOOTD /* bootd */
> +#define CONFIG_CMD_BOOTZ /* boot zImage */
> #define CONFIG_CMD_BSP /* Board Specific functions */
> #define CONFIG_CMD_CACHE /* icache, dcache */
> #define CONFIG_CMD_CDP /* Cisco Discovery Protocol */
More information about the U-Boot
mailing list