image: android: handle default kernel address

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>
This commit is contained in:
Maxime Ripard 2015-04-24 12:53:12 +02:00 committed by Tom Rini
parent a67da8fd67
commit 87f02d5aee

View File

@ -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,