aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Turner <digit@google.com>2015-01-29 10:45:10 +0000
committerandroid-build-merger <android-build-merger@google.com>2015-01-29 10:45:10 +0000
commit1a5713b3f1c5e27da7dedf27c2667aa3f92d21c1 (patch)
tree3d9dc09d03d55f598f44e90737db0902a5853ef0
parentf9429f18700e29e85aa1bd1148a23f9e766cbdf0 (diff)
parente5032154b6c89c89879048e51f09a8085b4ed042 (diff)
downloadqemu-master-soong.tar.gz
Merge "Backport arm_boot: Change initrd load address to "halfway through RAM"" into studio-1.2-dev automerge: f912613master-soong
automerge: e503215 * commit 'e5032154b6c89c89879048e51f09a8085b4ed042': Backport arm_boot: Change initrd load address to "halfway through RAM"
-rw-r--r--hw/arm/boot.c28
-rw-r--r--include/hw/arm/arm.h1
2 files changed, 21 insertions, 8 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 4c901485f8..b4fb9e9a58 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -13,7 +13,6 @@
#define KERNEL_ARGS_ADDR 0x100
#define KERNEL_LOAD_ADDR 0x00010000
-#define INITRD_LOAD_ADDR 0x00800000
/* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */
static uint32_t bootloader[] = {
@@ -80,7 +79,7 @@ static void set_kernel_args(const struct arm_boot_info *info,
/* ATAG_INITRD2 */
WRITE_WORD(p, 4);
WRITE_WORD(p, 0x54420005);
- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR);
+ WRITE_WORD(p, info->initrd_start);
WRITE_WORD(p, initrd_size);
}
if (info->kernel_cmdline && *info->kernel_cmdline) {
@@ -156,10 +155,11 @@ static void set_kernel_args_old(const struct arm_boot_info *info,
/* pages_in_vram */
WRITE_WORD(p, 0);
/* initrd_start */
- if (initrd_size)
- WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR);
- else
+ if (initrd_size) {
+ WRITE_WORD(p, info->initrd_start);
+ } else {
WRITE_WORD(p, 0);
+ }
/* initrd_size */
WRITE_WORD(p, initrd_size);
/* rd_start */
@@ -203,6 +203,19 @@ void arm_load_kernel(CPUARMState *env, struct arm_boot_info *info)
nb_cpus = info->nb_cpus ? info->nb_cpus : 1;
env->boot_info = info;
+ /* 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 = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL);
entry = elf_entry;
@@ -228,9 +241,8 @@ void arm_load_kernel(CPUARMState *env, struct arm_boot_info *info)
} else {
if (info->initrd_filename) {
initrd_size = load_image_targphys(info->initrd_filename,
- info->loader_start
- + INITRD_LOAD_ADDR,
- ram_size - INITRD_LOAD_ADDR);
+ info->initrd_start,
+ ram_size - info->initrd_start);
if (initrd_size < 0) {
fprintf(stderr, "qemu: could not load initrd '%s'\n",
info->initrd_filename);
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index a4983331dc..2a11ee84b2 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -37,6 +37,7 @@ struct arm_boot_info {
int (*atag_board)(const struct arm_boot_info *info, void *p);
/* Used internally by arm_boot.c */
int is_linux;
+ hwaddr initrd_start;
hwaddr initrd_size;
hwaddr entry;
};