aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/boot.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 5ddba727d4..a0e1110719 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -1000,20 +1000,6 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
if (info->nb_cpus == 0)
info->nb_cpus = 1;
- /*
- * We want to put the initrd far enough into RAM that when the
- * kernel is uncompressed it will not clobber the initrd. However
- * on boards without much RAM we must ensure that we still leave
- * enough room for a decent sized initrd, and on boards with large
- * amounts of RAM we must avoid the initrd being so far up in RAM
- * that it is outside lowmem and inaccessible to the kernel.
- * So for boards with less than 256MB of RAM we put the initrd
- * halfway into RAM, and for boards with 256MB of RAM or more we put
- * the initrd at 128MB.
- */
- info->initrd_start = info->loader_start +
- MIN(info->ram_size / 2, 128 * 1024 * 1024);
-
/* Assume that raw images are linux kernels, and ELF images are not. */
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
&elf_high_addr, elf_machine, as);
@@ -1065,6 +1051,26 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
}
info->entry = entry;
+
+ /*
+ * We want to put the initrd far enough into RAM that when the
+ * kernel is uncompressed it will not clobber the initrd. However
+ * on boards without much RAM we must ensure that we still leave
+ * enough room for a decent sized initrd, and on boards with large
+ * amounts of RAM we must avoid the initrd being so far up in RAM
+ * that it is outside lowmem and inaccessible to the kernel.
+ * So for boards with less than 256MB of RAM we put the initrd
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
+ * the initrd at 128MB.
+ * We also refuse to put the initrd somewhere that will definitely
+ * overlay the kernel we just loaded, though for kernel formats which
+ * don't tell us their exact size (eg self-decompressing 32-bit kernels)
+ * we might still make a bad choice here.
+ */
+ info->initrd_start = info->loader_start +
+ MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
+ info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
+
if (is_linux) {
uint32_t fixupcontext[FIXUP_MAX];