aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot
diff options
context:
space:
mode:
authorSebastian Siewior <bigeasy@linutronix.de>2008-10-12 19:15:26 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 00:17:47 -0400
commitc10c178a92b032ea3dd7259dcbbd1b9331c05c41 (patch)
treed539b62ebf4f6821f7b4b2159982ba1214c30d68 /arch/powerpc/boot
parentc1075fb7ec62b7ac0ac6baee2ceeb77270206aef (diff)
powerpc/boot: Compare _start against ei.loadsize instead ei.memsize
If the vmlinux binary in memory is larger than 4 MiB than it collides with the initial boot code which is linked at 4 MiB in case of cuBoot. If the the uncompressed image size (on disk size) is less than 4 MiB then it would fit. The difference between those two sizes is the bss section. In cuBoot we have the dtb embedded right after the data section so it is very likely that the reset of the bss section (in kernel's start up code) will overwrite the dtb blob. Therefore we reallocate the dtb. Something similar is allready done to the initrd. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Acked-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/boot')
-rw-r--r--arch/powerpc/boot/libfdt-wrapper.c16
-rw-r--r--arch/powerpc/boot/main.c14
2 files changed, 20 insertions, 10 deletions
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c
index c541fd8a95d..1daa73f08ba 100644
--- a/arch/powerpc/boot/libfdt-wrapper.c
+++ b/arch/powerpc/boot/libfdt-wrapper.c
@@ -165,6 +165,7 @@ static unsigned long fdt_wrapper_finalize(void)
165void fdt_init(void *blob) 165void fdt_init(void *blob)
166{ 166{
167 int err; 167 int err;
168 int bufsize;
168 169
169 dt_ops.finddevice = fdt_wrapper_finddevice; 170 dt_ops.finddevice = fdt_wrapper_finddevice;
170 dt_ops.getprop = fdt_wrapper_getprop; 171 dt_ops.getprop = fdt_wrapper_getprop;
@@ -178,16 +179,15 @@ void fdt_init(void *blob)
178 179
179 /* Make sure the dt blob is the right version and so forth */ 180 /* Make sure the dt blob is the right version and so forth */
180 fdt = blob; 181 fdt = blob;
181 err = fdt_open_into(fdt, fdt, fdt_totalsize(blob)); 182 bufsize = fdt_totalsize(fdt) + 4;
182 if (err == -FDT_ERR_NOSPACE) { 183 buf = malloc(bufsize);
183 int bufsize = fdt_totalsize(fdt) + 4; 184 if(!buf)
184 buf = malloc(bufsize); 185 fatal("malloc failed. can't relocate the device tree\n\r");
185 err = fdt_open_into(fdt, buf, bufsize); 186
186 } 187 err = fdt_open_into(fdt, buf, bufsize);
187 188
188 if (err != 0) 189 if (err != 0)
189 fatal("fdt_init(): %s\n\r", fdt_strerror(err)); 190 fatal("fdt_init(): %s\n\r", fdt_strerror(err));
190 191
191 if (buf) 192 fdt = buf;
192 fdt = buf;
193} 193}
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 9e7f3ddd991..ae32801ebd6 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -56,9 +56,19 @@ static struct addr_range prep_kernel(void)
56 if (platform_ops.vmlinux_alloc) { 56 if (platform_ops.vmlinux_alloc) {
57 addr = platform_ops.vmlinux_alloc(ei.memsize); 57 addr = platform_ops.vmlinux_alloc(ei.memsize);
58 } else { 58 } else {
59 if ((unsigned long)_start < ei.memsize) 59 /*
60 * Check if the kernel image (without bss) would overwrite the
61 * bootwrapper. The device tree has been moved in fdt_init()
62 * to an area allocated with malloc() (somewhere past _end).
63 */
64 if ((unsigned long)_start < ei.loadsize)
60 fatal("Insufficient memory for kernel at address 0!" 65 fatal("Insufficient memory for kernel at address 0!"
61 " (_start=%p)\n\r", _start); 66 " (_start=%p, uncomressed size=%08x)\n\r",
67 _start, ei.loadsize);
68
69 if ((unsigned long)_end < ei.memsize)
70 fatal("The final kernel image would overwrite the "
71 "device tree\n\r");
62 } 72 }
63 73
64 /* Finally, gunzip the kernel */ 74 /* Finally, gunzip the kernel */