public inbox for u-boot@lists.denx.de
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox