summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2014-05-01 12:42:05 +0200
committerSimon Horman <horms@verge.net.au>2014-05-02 11:08:10 +0900
commitceb4fb0dce020117269e8ab3adae414ace9f6987 (patch)
tree27a1cdbd8c179fac95d1ece316678b4432ab7254
parent91f5b9c0175ef02019f7d7208816373ff7ca8811 (diff)
downloadkexec-tools-ceb4fb0dce020117269e8ab3adae414ace9f6987.tar.gz
zImage-arm: get rid of static offset
The code in arch/arm/kexec-zImage-arm.c currently enforces a hard limit on the maximum size a dtb blob can occupy. This limit is set to 32k, which is quite low for device tree blobs nowadays. Get rid of this assumption, and calculate the added size dynamically. For this, we need to slurp in the dtb file earlier in order to determine its size, because the memory hole allocation for 'base' takes this size into account. For ATAGs, we keep the current value of 32k, which should in fact be enough. With this change in place, the 'DTB too large!' error message can go away. Successfully tested on a AM335x board. Signed-off-by: Daniel Mack <zonque@gmail.com> [s.neumann@raumfeld.com: Fix ATAGs case] Reported-and-tested-by: Sven Neumann <s.neumann@raumfeld.com> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/arch/arm/kexec-zImage-arm.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c
index bfbf290..220826e 100644
--- a/kexec/arch/arm/kexec-zImage-arm.c
+++ b/kexec/arch/arm/kexec-zImage-arm.c
@@ -282,7 +282,7 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
{
unsigned long base;
unsigned int atag_offset = 0x1000; /* 4k offset from memory start */
- unsigned int offset = 0x8000; /* 32k offset from memory start */
+ unsigned int extra_size = 0;
const char *command_line;
char *modified_cmdline = NULL;
off_t command_line_len;
@@ -360,6 +360,13 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
ramdisk_buf = slurp_file(ramdisk, &initrd_size);
}
+ if (dtb_file) {
+ dtb_buf = slurp_file(dtb_file, &dtb_length);
+ extra_size = _ALIGN(dtb_length, getpagesize());
+ } else if (use_atags) {
+ extra_size = 0x8000; /* 32k should be plenty for ATAGs */
+ }
+
/*
* If we are loading a dump capture kernel, we need to update kernel
* command line and also add some additional segments.
@@ -398,7 +405,8 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
}
base = start;
} else {
- base = locate_hole(info,len+offset,0,0,ULONG_MAX,INT_MAX);
+ base = locate_hole(info, len + extra_size, 0, 0,
+ ULONG_MAX, INT_MAX);
}
if (base == ULONG_MAX)
@@ -428,8 +436,6 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
* Read a user-specified DTB file.
*/
if (dtb_file) {
- dtb_buf = slurp_file(dtb_file, &dtb_length);
-
if (fdt_check_header(dtb_buf) != 0) {
fprintf(stderr, "Invalid FDT buffer.\n");
return -1;
@@ -452,11 +458,6 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
create_flatten_tree(&dtb_buf, &dtb_length, command_line);
}
- if (base + atag_offset + dtb_length > base + offset) {
- fprintf(stderr, "DTB too large!\n");
- return -1;
- }
-
if (ramdisk) {
add_segment(info, ramdisk_buf, initrd_size,
initrd_base, initrd_size);
@@ -485,9 +486,9 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len,
dtb_offset, dtb_length);
}
- add_segment(info, buf, len, base + offset, len);
+ add_segment(info, buf, len, base + extra_size, len);
- info->entry = (void*)base + offset;
+ info->entry = (void*)base + extra_size;
return 0;
}