diff options
author | David Turner <digit@google.com> | 2015-01-29 10:45:10 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2015-01-29 10:45:10 +0000 |
commit | 1a5713b3f1c5e27da7dedf27c2667aa3f92d21c1 (patch) | |
tree | 3d9dc09d03d55f598f44e90737db0902a5853ef0 | |
parent | f9429f18700e29e85aa1bd1148a23f9e766cbdf0 (diff) | |
parent | e5032154b6c89c89879048e51f09a8085b4ed042 (diff) | |
download | qemu-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.c | 28 | ||||
-rw-r--r-- | include/hw/arm/arm.h | 1 |
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; }; |