aboot: improve appended device tree support
Extends the device tree by 1024 bytes to allow for extra
stuff added by the bootloader.
Copies the device tree over the tags since the tags get thrown
out if DTB is preset anyway.
Clears out the old DTB magic so if kernel turns on the
APPENDED_DTB config option, it won't find the wrong one.
Change-Id: I8ab2920ed6b0f8a57a90127cd1cba41dc8549339
Signed-off-by: Dima Zavin <dima@android.com>
Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 9a45feb..55e8aeb 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -106,8 +106,6 @@
/* Assuming unauthorized kernel image by default */
static int auth_kernel_img = 0;
-static uint32_t app_dev_tree = 0;
-
static device_info device = {DEVICE_MAGIC, 0, 0};
static struct udc_device surf_udc_device = {
@@ -466,7 +464,6 @@
unsigned offset = 0;
unsigned long long ptn = 0;
const char *cmdline;
- void *tags;
int index = INVALID_PTN;
unsigned char *image_addr = 0;
@@ -611,15 +608,18 @@
/* Read device device tree in the "tags_add */
memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry_ptr->offset, dt_entry_ptr->size);
} else {
- /*
- * Look for appended device tree if DTB is not found in boot image
- * If found load the kernel & boot up
- */
- app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
- if (!app_dev_tree) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
+ /*
+ * If appended dev tree is found, update the atags with
+ * memory address to the DTB appended location on RAM.
+ * Else update with the atags address in the kernel header
+ */
+ void *dtb;
+ dtb = dev_tree_appended((void*) hdr->kernel_addr,
+ (void *)hdr->tags_addr);
+ if (!dtb) {
+ dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+ return -1;
+ }
}
#endif
/* Make sure everything from scratch address is read before next step!*/
@@ -705,15 +705,18 @@
return -1;
}
} else {
- /*
- * Look for appended device tree if DTB is not found in boot image
- * If found load the kernel & boot up
- */
- app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
- if (!app_dev_tree) {
- dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
- return -1;
- }
+ /*
+ * If appended dev tree is found, update the atags with
+ * memory address to the DTB appended location on RAM.
+ * Else update with the atags address in the kernel header
+ */
+ void *dtb;
+ dtb = dev_tree_appended((void*) hdr->kernel_addr,
+ (void *)hdr->tags_addr);
+ if (!dtb) {
+ dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
+ return -1;
+ }
}
#endif
}
@@ -726,17 +729,7 @@
cmdline = DEFAULT_CMDLINE;
}
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- if (app_dev_tree)
- tags = (void *)app_dev_tree;
- else
- tags = (void *)hdr->tags_addr;
-
- boot_linux((void *)hdr->kernel_addr, (unsigned *)tags,
+ boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
(const char *)cmdline, board_machtype(),
(void *)hdr->ramdisk_addr, hdr->ramdisk_size);
@@ -1188,12 +1181,14 @@
dt_entry_ptr->size);
} else {
/*
- * Look for appended device tree if DTB is not found in boot image
- * If found load the kernel & boot up
+ * If appended dev tree is found, update the atags with
+ * memory address to the DTB appended location on RAM.
+ * Else update with the atags address in the kernel header
*/
- memmove((void*) hdr->kernel_addr, boot_image_start + page_size, hdr->kernel_size);
- app_dev_tree = dev_tree_appended((void*) hdr->kernel_addr);
- if (!app_dev_tree) {
+ void *dtb;
+ dtb = dev_tree_appended((void *)hdr->kernel_addr,
+ (void *)hdr->tags_addr);
+ if (!dtb) {
dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
return -1;
}
@@ -1210,7 +1205,6 @@
unsigned ramdisk_actual;
struct boot_img_hdr *hdr;
char *ptr = ((char*) data);
- void *tags;
if (sz < sizeof(hdr)) {
fastboot_fail("invalid bootimage header");
@@ -1241,6 +1235,9 @@
return;
}
+ memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
+ memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
+
#if DEVICE_TREE
/* find correct dtb and copy it to right location */
if(copy_dtb(data))
@@ -1253,20 +1250,7 @@
fastboot_okay("");
udc_stop();
- memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
- memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
-
- /*
- * If appended dev tree is found, update the atags with
- * memory address to the DTB appended location on RAM.
- * Else update with the atags address in the kernel header
- */
- if (app_dev_tree)
- tags = (void *)app_dev_tree;
- else
- tags = (void *)hdr->tags_addr;
-
- boot_linux((void*) hdr->kernel_addr, (void*) tags,
+ boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
(const char*) hdr->cmdline, board_machtype(),
(void*) hdr->ramdisk_addr, hdr->ramdisk_size);
}
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 6a06a12..bb3bf64 100644
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -40,25 +40,37 @@
extern uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset);
/*
- * Argument: Start address of the kernel loaded in RAM
+ * Will relocate the DTB to the tags addr if the device tree is found and return
+ * its address
+ *
+ * Arguments: kernel - Start address of the kernel loaded in RAM
+ * tags - Start address of the tags loaded in RAM
* Return Value: DTB address : If appended device tree is found
- * '0' : Otherwise
+ * 'NULL' : Otherwise
*/
-uint32_t dev_tree_appended(void *kernel)
+void *dev_tree_appended(void *kernel, void *tags)
{
uint32_t app_dtb_offset = 0;
uint32_t dtb_magic = 0;
- uint32_t dtb = 0;
memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));
memcpy((void*) &dtb_magic, (void*) (kernel + app_dtb_offset), sizeof(uint32_t));
if (dtb_magic == DTB_MAGIC) {
+ void *dtb;
+ int rc;
+
dprintf(INFO, "Found Appeneded Flattened Device tree\n");
- dtb = (uint32_t) (kernel + app_dtb_offset);
+ dtb = kernel + app_dtb_offset;
+ rc = fdt_open_into(dtb, tags, fdt_totalsize(dtb) + DTB_PAD_SIZE);
+ if (rc == 0) {
+ /* clear out the old DTB magic so kernel doesn't find it */
+ *((uint32_t *)dtb) = 0;
+ return tags;
+ }
}
- return dtb;
+ return NULL;
}
/* Function to return the pointer to the start of the correct device tree
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
index 389ab49..a27fafd 100644
--- a/platform/msm_shared/include/dev_tree.h
+++ b/platform/msm_shared/include/dev_tree.h
@@ -40,6 +40,8 @@
#define DTB_MAGIC 0xedfe0dd0
#define DTB_OFFSET 0x2C
+#define DTB_PAD_SIZE 1024
+
struct dt_entry
{
uint32_t platform_id;
@@ -65,5 +67,5 @@
struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *);
int update_device_tree(void *, const char *, void *, unsigned);
int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t size, uint32_t addr);
-uint32_t dev_tree_appended(void *);
+void *dev_tree_appended(void *kernel, void *tags);
#endif