diff mbox

[U-Boot] image: android: handle default kernel address

Message ID 1429872792-29332-1-git-send-email-maxime.ripard@free-electrons.com
State Accepted
Delegated to: Tom Rini
Headers show

Commit Message

Maxime Ripard April 24, 2015, 10:53 a.m. UTC
The two tools that create android boot images, mkbootimg and the fastboot
client, set the kernel address by default to 0x10008000.

U-boot always honors this field, and will try to relocate the kernel to
whatever value is set in the header, which won't be mapped to the actual RAM on
most platforms, resulting in the kernel obviously not booting.

All the targets in U-Boot right now will download the android boot image to
CONFIG_SYS_LOAD_ADDR, which means that it will already have been downloaded to
some location that is suitable for execution.

In order to have the kernel booting even with the default boot image kernel
address, if that address is used, just execute the kernel where it is.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 common/image-android.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

Comments

Tom Rini May 10, 2015, 2:07 p.m. UTC | #1
On Fri, Apr 24, 2015 at 12:53:12PM +0200, Maxime Ripard wrote:

> The two tools that create android boot images, mkbootimg and the fastboot
> client, set the kernel address by default to 0x10008000.
> 
> U-boot always honors this field, and will try to relocate the kernel to
> whatever value is set in the header, which won't be mapped to the actual RAM on
> most platforms, resulting in the kernel obviously not booting.
> 
> All the targets in U-Boot right now will download the android boot image to
> CONFIG_SYS_LOAD_ADDR, which means that it will already have been downloaded to
> some location that is suitable for execution.
> 
> In order to have the kernel booting even with the default boot image kernel
> address, if that address is used, just execute the kernel where it is.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

Applied to u-boot/master, thanks!
diff mbox

Patch

diff --git a/common/image-android.c b/common/image-android.c
index 59079fc32b51..d946c2f814c1 100644
--- a/common/image-android.c
+++ b/common/image-android.c
@@ -10,8 +10,29 @@ 
 #include <malloc.h>
 #include <errno.h>
 
+#define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR	0x10008000
+
 static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
 
+static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
+{
+	/*
+	 * All the Android tools that generate a boot.img use this
+	 * address as the default.
+	 *
+	 * Even though it doesn't really make a lot of sense, and it
+	 * might be valid on some platforms, we treat that adress as
+	 * the default value for this field, and try to execute the
+	 * kernel in place in such a case.
+	 *
+	 * Otherwise, we will return the actual value set by the user.
+	 */
+	if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
+		return (ulong)hdr + hdr->page_size;
+
+	return hdr->kernel_addr;
+}
+
 /**
  * android_image_get_kernel() - processes kernel part of Android boot images
  * @hdr:	Pointer to image header, which is at the start
@@ -30,6 +51,8 @@  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)
 {
+	u32 kernel_addr = android_image_get_kernel_addr(hdr);
+
 	/*
 	 * 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
@@ -41,7 +64,7 @@  int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
 		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));
+	       kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
 
 	int len = 0;
 	if (*hdr->cmdline) {
@@ -101,7 +124,7 @@  ulong android_image_get_end(const struct andr_img_hdr *hdr)
 
 ulong android_image_get_kload(const struct andr_img_hdr *hdr)
 {
-	return hdr->kernel_addr;
+	return android_image_get_kernel_addr(hdr);
 }
 
 int android_image_get_ramdisk(const struct andr_img_hdr *hdr,