All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lukasz Majewski <l.majewski@samsung.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 3/5] image: add support for Android's boot image format
Date: Tue, 15 Apr 2014 15:59:14 +0200	[thread overview]
Message-ID: <20140415155914.34dfac04@amdc2363> (raw)
In-Reply-To: <1397157488-8695-4-git-send-email-robherring2@gmail.com>

Hi Rob,

> From: Sebastian Siewior <bigeasy@linutronix.de>
> 
> This patch adds support for the Android boot-image format. The header
> file is from the Android project and got slightly alterted so the
> struct + its defines are not generic but have something like a
> namespace. The header file is from
> bootloader/legacy/include/boot/bootimg.h. The header parsing has been
> written from scratch and I looked at
> bootloader/legacy/usbloader/usbloader.c for some details. The image
> contains the physical address (load address) of the kernel and
> ramdisk. This address is considered only for the kernel image. The
> "second image" is currently ignored. I haven't found anything that is
> creating this.
> 
> v3 (Rob Herring):
> This is based on http://patchwork.ozlabs.org/patch/126797/ with the
> following changes:
> - Rebased to current mainline
> - Moved android image handling to separate functions in
>   common/image-android.c
> - s/u8/char/ in header to fix string function warnings
> - Use SPDX identifiers for licenses
> - Cleaned-up file source information:
>   android_image.h is from file include/boot/bootimg.h in repository:
>   https://android.googlesource.com/platform/bootable/bootloader/legacy
>   The git commit hash is 4205b865141ff2e255fe1d3bd16de18e217ef06a
>   usbloader.c would be from the same commit, but it does not appear
>   to have been used for any actual code.
> 
> Cc: Wolfgang Denk <wd@denx.de>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
>  common/Makefile         |  1 +
>  common/cmd_bootm.c      | 23 +++++++++++++-
>  common/image-android.c  | 84
> +++++++++++++++++++++++++++++++++++++++++++++++++
> common/image.c          | 20 +++++++++--- include/android_image.h |
> 69 ++++++++++++++++++++++++++++++++++++++++ include/image.h         |
> 13 ++++++++ 6 files changed, 204 insertions(+), 6 deletions(-)
>  create mode 100644 common/image-android.c
>  create mode 100644 include/android_image.h
> 
> diff --git a/common/Makefile b/common/Makefile
> index cecd81a..da208f3 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -236,6 +236,7 @@ obj-y += console.o
>  obj-$(CONFIG_CROS_EC) += cros_ec.o
>  obj-y += dlmalloc.o
>  obj-y += image.o
> +obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
>  obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
>  obj-$(CONFIG_FIT) += image-fit.o
>  obj-$(CONFIG_FIT_SIGNATURE) += image-sig.o
> diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
> index 9751edc..b6c8288 100644
> --- a/common/cmd_bootm.c
> +++ b/common/cmd_bootm.c
> @@ -223,6 +223,8 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int
> flag, int argc, {
>  	const void *os_hdr;
>  
> +	images.ep = ~0UL;
> +
>  	/* get kernel image header, start address and length */
>  	os_hdr = boot_get_kernel(cmdtp, flag, argc, argv,
>  			&images, &images.os.image_start,
> &images.os.image_len); @@ -274,6 +276,17 @@ static int
> bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, }
>  		break;
>  #endif
> +#ifdef CONFIG_ANDROID_BOOT_IMAGE
> +	case IMAGE_FORMAT_ANDROID:
> +		images.os.type = IH_TYPE_KERNEL;
> +		images.os.comp = IH_COMP_NONE;
> +		images.os.os = IH_OS_LINUX;
> +		images.ep = images.os.load;
> +
> +		images.os.end = android_image_get_end(os_hdr);
> +		images.os.load = android_image_get_kload(os_hdr);
> +		break;
> +#endif
>  	default:
>  		puts("ERROR: unknown image format type!\n");
>  		return 1;
> @@ -293,7 +306,7 @@ static int bootm_find_os(cmd_tbl_t *cmdtp, int
> flag, int argc, return 1;
>  		}
>  #endif
> -	} else {
> +	} else if (images.ep == ~0UL) {
>  		puts("Could not find kernel entry point!\n");
>  		return 1;
>  	}
> @@ -1002,6 +1015,14 @@ static const void *boot_get_kernel(cmd_tbl_t
> *cmdtp, int flag, int argc, images->fit_noffset_os = os_noffset;
>  		break;
>  #endif
> +#ifdef CONFIG_ANDROID_BOOT_IMAGE
> +	case IMAGE_FORMAT_ANDROID:
> +		printf("## Booting Android Image at 0x%08lx ...\n",
> img_addr);
> +		if (android_image_get_kernel((void *)img_addr,
> images->verify,
> +					     os_data, os_len))
> +			return NULL;
> +		break;
> +#endif
>  	default:
>  		printf("Wrong Image Format for %s command\n",
> cmdtp->name); bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
> diff --git a/common/image-android.c b/common/image-android.c
> new file mode 100644
> index 0000000..ec6fb3d
> --- /dev/null
> +++ b/common/image-android.c
> @@ -0,0 +1,84 @@
> +/*
> + * Copyright (c) 2011 Sebastian Andrzej Siewior
> <bigeasy@linutronix.de>
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <image.h>
> +#include <android_image.h>
> +
> +static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
> +
> +int android_image_get_kernel(const struct andr_img_hdr *hdr, int
> verify,
> +			     ulong *os_data, ulong *os_len)
> +{
> +	/*
> +	 * Not all Android tools use the id field for signing the
> image with
> +	 * sha1 (or anything) so we don't check it. It is not
> obvious that the
> +	 * string is null terminated so we take care of this.
> +	 */
> +	strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
> +	andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
> +	if (strlen(andr_tmp_str))
> +		printf("Android's image name: %s\n", andr_tmp_str);
> +
> +	printf("Kernel load addr 0x%08x size %u KiB\n",
> +	       hdr->kernel_addr, DIV_ROUND_UP(hdr->kernel_size,
> 1024));
> +	strncpy(andr_tmp_str, hdr->cmdline, ANDR_BOOT_ARGS_SIZE);
> +	andr_tmp_str[ANDR_BOOT_ARGS_SIZE] = '\0';
> +	if (strlen(andr_tmp_str)) {
> +		printf("Kernel command line: %s\n", andr_tmp_str);
> +		setenv("bootargs", andr_tmp_str);
> +	}
> +	if (hdr->ramdisk_size)
> +		printf("RAM disk load addr 0x%08x size %u KiB\n",
> +		       hdr->ramdisk_addr,
> +		       DIV_ROUND_UP(hdr->ramdisk_size, 1024));
> +
> +	if (os_data) {
> +		*os_data = (ulong)hdr;
> +		*os_data += hdr->page_size;
> +	}
> +	if (os_len)
> +		*os_len = hdr->kernel_size;
> +	return 0;
> +}
> +
> +int android_image_check_header(const struct andr_img_hdr *hdr)
> +{
> +	return memcmp(ANDR_BOOT_MAGIC, hdr->magic,
> ANDR_BOOT_MAGIC_SIZE); +}
> +
> +ulong android_image_get_end(const struct andr_img_hdr *hdr)
> +{
> +	u32 size = 0;
> +	/*
> +	 * The header takes a full page, the remaining components
> are aligned
> +	 * on page boundary
> +	 */
> +	size += hdr->page_size;
> +	size += ALIGN(hdr->kernel_size, hdr->page_size);
> +	size += ALIGN(hdr->ramdisk_size, hdr->page_size);
> +	size += ALIGN(hdr->second_size, hdr->page_size);
> +
> +	return size;
> +}
> +
> +ulong android_image_get_kload(const struct andr_img_hdr *hdr)
> +{
> +	return hdr->kernel_addr;
> +}
> +
> +int andriod_image_get_ramdisk(const struct andr_img_hdr *hdr,
> +			      ulong *rd_data, ulong *rd_len)
> +{
> +	if (!hdr->ramdisk_size)
> +		return -1;
> +	*rd_data = (unsigned long)hdr;
> +	*rd_data += hdr->page_size;
> +	*rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
> +
> +	*rd_len = hdr->ramdisk_size;
> +	return 0;
> +}
> diff --git a/common/image.c b/common/image.c
> index afbf806..b6063f6 100644
> --- a/common/image.c
> +++ b/common/image.c
> @@ -676,10 +676,12 @@ int genimg_get_format(const void *img_addr)
>  	if (image_check_magic(hdr))
>  		format = IMAGE_FORMAT_LEGACY;
>  #if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
> -	else {
> -		if (fdt_check_header(img_addr) == 0)
> -			format = IMAGE_FORMAT_FIT;
> -	}
> +	else if (fdt_check_header(img_addr) == 0)
> +		format = IMAGE_FORMAT_FIT;
> +#endif
> +#ifdef CONFIG_ANDROID_BOOT_IMAGE
> +	else if (android_image_check_header(img_addr) == 0)
> +		format = IMAGE_FORMAT_ANDROID;
>  #endif
>  
>  	return format;
> @@ -949,7 +951,15 @@ int boot_get_ramdisk(int argc, char * const
> argv[], bootm_headers_t *images, (ulong)images->legacy_hdr_os);
>  
>  		image_multi_getimg(images->legacy_hdr_os, 1,
> &rd_data, &rd_len);
> -	} else {
> +	}
> +#ifdef CONFIG_ANDROID_BOOT_IMAGE
> +	else if ((genimg_get_format(images) == IMAGE_FORMAT_ANDROID)
> &&
> +		 (!andriod_image_get_ramdisk((void
> *)images->os.start,
> +		    &rd_data, &rd_len))) {
> +		/* empty */
> +	}
> +#endif
> +	else {
>  		/*
>  		 * no initrd image
>  		 */
> diff --git a/include/android_image.h b/include/android_image.h
> new file mode 100644
> index 0000000..094d60a
> --- /dev/null
> +++ b/include/android_image.h
> @@ -0,0 +1,69 @@
> +/*
> + * This is from the Android Project,
> + * Repository:
> https://android.googlesource.com/platform/bootable/bootloader/legacy
> + * File: include/boot/bootimg.h
> + * Commit: 4205b865141ff2e255fe1d3bd16de18e217ef06a
> + *
> + * Copyright (C) 2008 The Android Open Source Project
> + *
> + * SPDX-License-Identifier: BSD-2-Clause
> + */
> +
> +#ifndef _ANDROID_IMAGE_H_
> +#define _ANDROID_IMAGE_H_
> +
> +#define ANDR_BOOT_MAGIC "ANDROID!"
> +#define ANDR_BOOT_MAGIC_SIZE 8
> +#define ANDR_BOOT_NAME_SIZE 16
> +#define ANDR_BOOT_ARGS_SIZE 512
> +
> +struct andr_img_hdr {
> +	char magic[ANDR_BOOT_MAGIC_SIZE];
> +
> +	u32 kernel_size;	/* size in bytes */
> +	u32 kernel_addr;	/* physical load addr */
> +
> +	u32 ramdisk_size;	/* size in bytes */
> +	u32 ramdisk_addr;	/* physical load addr */
> +
> +	u32 second_size;	/* size in bytes */
> +	u32 second_addr;	/* physical load addr */
> +
> +	u32 tags_addr;		/* physical addr for kernel
> tags */
> +	u32 page_size;		/* flash page size we assume */
> +	u32 unused[2];		/* future expansion: should be
> 0 */ +
> +	char name[ANDR_BOOT_NAME_SIZE]; /* asciiz product name */
> +
> +	char cmdline[ANDR_BOOT_ARGS_SIZE];
> +
> +	u32 id[8]; /* timestamp / checksum / sha1 / etc */
> +};
> +
> +/*
> + * +-----------------+
> + * | boot header     | 1 page
> + * +-----------------+
> + * | kernel          | n pages
> + * +-----------------+
> + * | ramdisk         | m pages
> + * +-----------------+
> + * | second stage    | o pages
> + * +-----------------+
> + *
> + * n = (kernel_size + page_size - 1) / page_size
> + * m = (ramdisk_size + page_size - 1) / page_size
> + * o = (second_size + page_size - 1) / page_size
> + *
> + * 0. all entities are page_size aligned in flash
> + * 1. kernel and ramdisk are required (size != 0)
> + * 2. second is optional (second_size == 0 -> no second)
> + * 3. load each element (kernel, ramdisk, second) at
> + *    the specified physical address (kernel_addr, etc)
> + * 4. prepare tags at tag_addr.  kernel_args[] is
> + *    appended to the kernel commandline in the tags.
> + * 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
> + * 6. if second_size != 0: jump to second_addr
> + *    else: jump to kernel_addr
> + */
> +#endif
> diff --git a/include/image.h b/include/image.h
> index 6afd57b..b123860 100644
> --- a/include/image.h
> +++ b/include/image.h
> @@ -403,6 +403,7 @@ enum fit_load_op {
>  #define IMAGE_FORMAT_INVALID	0x00
>  #define IMAGE_FORMAT_LEGACY	0x01	/* legacy
> image_header based format */ #define IMAGE_FORMAT_FIT
> 0x02	/* new, libfdt based format */ +#define
> IMAGE_FORMAT_ANDROID	0x03	/* Android boot image */ 
>  int genimg_get_format(const void *img_addr);
>  int genimg_has_config(bootm_headers_t *images);
> @@ -996,4 +997,16 @@ static inline int
> fit_image_check_target_arch(const void *fdt, int node) #endif /*
> CONFIG_FIT_VERBOSE */ #endif /* CONFIG_FIT */
>  
> +#if defined(CONFIG_ANDROID_BOOT_IMAGE)
> +struct andr_img_hdr;
> +int android_image_check_header(const struct andr_img_hdr *hdr);
> +int android_image_get_kernel(const struct andr_img_hdr *hdr, int
> verify,
> +			     ulong *os_data, ulong *os_len);
> +int andriod_image_get_ramdisk(const struct andr_img_hdr *hdr,
> +			      ulong *rd_data, ulong *rd_len);
> +ulong android_image_get_end(const struct andr_img_hdr *hdr);
> +ulong android_image_get_kload(const struct andr_img_hdr *hdr);
> +
> +#endif /* CONFIG_ANDROID_BOOT_IMAGE */
> +
>  #endif	/* __IMAGE_H__ */

Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>

-- 
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

  parent reply	other threads:[~2014-04-15 13:59 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-10 19:18 [U-Boot] [PATCH v3 0/5] Android Fastboot support Rob Herring
2014-04-10 19:18 ` [U-Boot] [PATCH v3 1/5] common: introduce maximum load size Rob Herring
2014-04-11 14:46   ` Tom Rini
2014-04-15 12:55   ` Lukasz Majewski
2014-04-15 21:59   ` Wolfgang Denk
2014-04-15 23:54     ` Rob Herring
2014-04-16  7:27       ` Wolfgang Denk
2014-04-10 19:18 ` [U-Boot] [PATCH v3 2/5] usb: handle NULL table in usb_gadget_get_string Rob Herring
2014-04-11 14:46   ` Tom Rini
2014-04-11 21:39   ` Marek Vasut
2014-04-15 13:00   ` Lukasz Majewski
2014-04-10 19:18 ` [U-Boot] [PATCH v3 3/5] image: add support for Android's boot image format Rob Herring
2014-04-11 14:46   ` Tom Rini
2014-04-11 21:44   ` Marek Vasut
2014-04-12 21:54     ` Rob Herring
2014-04-13 16:55       ` Marek Vasut
2014-04-15 13:59   ` Lukasz Majewski [this message]
2014-04-10 19:18 ` [U-Boot] [PATCH v3 4/5] usb/gadget: add the fastboot gadget Rob Herring
2014-04-11  7:14   ` Bo Shen
2014-04-11 12:55     ` Rob Herring
2014-04-11 22:13       ` Marek Vasut
2014-04-14  6:51         ` Lukasz Majewski
2014-04-14  2:28       ` Bo Shen
2014-04-11  7:30   ` Lukasz Majewski
2014-04-11 14:46   ` Tom Rini
2014-04-11 22:08   ` Marek Vasut
2014-04-15 15:41   ` Lukasz Majewski
2014-04-15 16:01     ` Rob Herring
2014-04-10 19:18 ` [U-Boot] [PATCH v3 5/5] arm: beagle: enable Android fastboot support Rob Herring
2014-04-11 14:46   ` Tom Rini
2014-04-10 19:18 ` [U-Boot] [PATCH 5/5] beagle: " Rob Herring
2014-04-10 19:42   ` Rob Herring
2014-04-11  7:04 ` [U-Boot] [PATCH v3 0/5] Android Fastboot support Sebastian Andrzej Siewior
2014-04-11 14:15   ` Tom Rini
2014-04-11 14:45 ` Tom Rini
2014-04-14 12:19   ` Rob Herring
2014-04-18 13:54 ` [U-Boot] [PATCH v4 " Rob Herring
2014-04-18 13:54   ` [U-Boot] [PATCH v4 1/5] usb: handle NULL table in usb_gadget_get_string Rob Herring
2014-04-18 13:54   ` [U-Boot] [PATCH v4 2/5] image: add support for Android's boot image format Rob Herring
2014-04-18 13:54   ` [U-Boot] [PATCH v4 3/5] usb: musb: fill in usb_gadget_unregister_driver Rob Herring
2014-04-23  9:46     ` Lukasz Majewski
2014-04-18 13:54   ` [U-Boot] [PATCH v4 4/5] usb/gadget: add the fastboot gadget Rob Herring
2014-04-23 11:02     ` Lukasz Majewski
2014-04-23 12:25       ` Marek Vasut
2014-04-24 15:02       ` Rob Herring
2014-04-25  5:26         ` Lukasz Majewski
2014-04-25 13:30           ` Rob Herring
2014-04-28  7:00             ` Lukasz Majewski
2014-04-18 13:54   ` [U-Boot] [PATCH v4 5/5] arm: beagle: enable Android fastboot support Rob Herring
2014-04-18 16:14   ` [U-Boot] [PATCH v4 0/5] Android Fastboot support Wolfgang Denk
2014-04-21 15:13     ` Marek Vasut
2014-04-23 14:36       ` Rob Herring
2014-04-23 16:57         ` Marek Vasut
2014-05-05 20:08   ` [U-Boot] [PATCH v5 0/3] " Rob Herring
2014-05-05 20:08     ` [U-Boot] [PATCH v5 1/3] image: add support for Android's boot image format Rob Herring
2014-05-05 20:08     ` [U-Boot] [PATCH v5 2/3] usb/gadget: add the fastboot gadget Rob Herring
2014-05-05 20:08     ` [U-Boot] [PATCH v5 3/3] arm: beagle: enable Android fastboot support Rob Herring
2014-05-05 20:21     ` [U-Boot] [PATCH v5 0/3] Android Fastboot support Marek Vasut
2014-05-07  6:35     ` Lukasz Majewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140415155914.34dfac04@amdc2363 \
    --to=l.majewski@samsung.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.