summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2015-04-24 12:53:12 +0200
committerTom Rini <trini@konsulko.com>2015-05-08 17:24:17 -0400
commit87f02d5aeef53bc2028b433a4c02ef2b2eea8c87 (patch)
treed1b88574aefe8312b3aaf7ac9b0a07962f6b67e8 /common
parenta67da8fd67911ef87f296622b3758d04b1b76e2c (diff)
downloadtalos-obmc-uboot-87f02d5aeef53bc2028b433a4c02ef2b2eea8c87.tar.gz
talos-obmc-uboot-87f02d5aeef53bc2028b433a4c02ef2b2eea8c87.zip
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>
Diffstat (limited to 'common')
-rw-r--r--common/image-android.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/common/image-android.c b/common/image-android.c
index 59079fc32b..d946c2f814 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,
OpenPOWER on IntegriCloud