From patchwork Fri Oct 26 14:19:07 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 12546 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id F0EF223EF8 for ; Fri, 26 Oct 2012 14:19:15 +0000 (UTC) Received: from mail-ia0-f180.google.com (mail-ia0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 603C4A19252 for ; Fri, 26 Oct 2012 14:19:15 +0000 (UTC) Received: by mail-ia0-f180.google.com with SMTP id f6so2132694iag.11 for ; Fri, 26 Oct 2012 07:19:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-gm-message-state; bh=6n3IYhJKB7nBEzAYzJUXThPgMa9USaF+9eZ+7cJDuj8=; b=mz5fITrCBN2v/YbwCrt1Py6UmRe5iQCeknb3qfJyQPaA/3FJqi1L6/Ciw3+Q2zxBYl b8LQK0wvQDh4Iy8AfnQU3L/qtIaz67c4aBb8P6bYpFGt1kOe5eTtB9cDrbD8YHOGiX3M 8jrZ4BuFfDD4YdaNUdEw9WuQElfj5Z2Ov3f0NNNxN5dgd3lx9yQ3fxVvZ0xQICkCZGGH +fzAQl4xAbMY0QT53/UJPIF+utSa2IF56X1cqHW78kQHYL+DcXyD0DTIQoaIk31nqJ13 7MoeGwsPoF4jxQK8gXPKZfoFUBVKj8d8QWABdbl0NWUTRXfXXMBqOnFTcBGtvRvXy7hZ I4hQ== Received: by 10.50.161.169 with SMTP id xt9mr2241990igb.62.1351261154788; Fri, 26 Oct 2012 07:19:14 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.67.148 with SMTP id n20csp259310igt; Fri, 26 Oct 2012 07:19:13 -0700 (PDT) Received: by 10.216.197.166 with SMTP id t38mr13220408wen.109.1351261152911; Fri, 26 Oct 2012 07:19:12 -0700 (PDT) Received: from mnementh.archaic.org.uk (1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.d.1.0.0.b.8.0.1.0.0.2.ip6.arpa. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id d43si1327377weq.109.2012.10.26.07.19.12 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 26 Oct 2012 07:19:12 -0700 (PDT) Received-SPF: neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) client-ip=2001:8b0:1d0::1; Authentication-Results: mx.google.com; spf=neutral (google.com: 2001:8b0:1d0::1 is neither permitted nor denied by best guess record for domain of pm215@archaic.org.uk) smtp.mail=pm215@archaic.org.uk Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1TRkkd-0003aX-EB; Fri, 26 Oct 2012 15:19:07 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Cole Robinson , Peter Crosthwaite Subject: [PATCH] arm_boot: Change initrd load address to "halfway through RAM" Date: Fri, 26 Oct 2012 15:19:07 +0100 Message-Id: <1351261147-13770-1-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 X-Gm-Message-State: ALoCoQnTspW1guVUlDkI1+eHbZpvpxpdBiMj4R6Kx8NL22ZgWg55fg/csIO9webzyVu/+wXP3MK0 To avoid continually having to bump the initrd load address to account for larger kernel images, put the initrd halfway through RAM. This allows large kernels on new boards with lots of RAM to work OK, without breaking existing usecases for boards with only 32MB of RAM. Note that this change fixes in passing a bug where we were passing an overly large max_size to load_image_targphys() for the initrd, which meant that we wouldn't correctly refuse to load an enormous initrd that didn't actually fit into RAM. Signed-off-by: Peter Maydell --- Cole: does this fix the problems you see? hw/arm-misc.h | 1 + hw/arm_boot.c | 35 ++++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/hw/arm-misc.h b/hw/arm-misc.h index d02f7f0..adb1665 100644 --- a/hw/arm-misc.h +++ b/hw/arm-misc.h @@ -56,6 +56,7 @@ struct arm_boot_info { const struct arm_boot_info *info); /* Used internally by arm_boot.c */ int is_linux; + hwaddr initrd_start; hwaddr initrd_size; hwaddr entry; }; diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 09bf6c5..83bdf16 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -18,7 +18,6 @@ #define KERNEL_ARGS_ADDR 0x100 #define KERNEL_LOAD_ADDR 0x00010000 -#define INITRD_LOAD_ADDR 0x00d00000 /* The worlds second smallest bootloader. Set r0-r2, then jump to kernel. */ static uint32_t bootloader[] = { @@ -109,7 +108,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) { @@ -185,10 +184,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 */ @@ -281,14 +281,13 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo) if (binfo->initrd_size) { rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", - binfo->loader_start + INITRD_LOAD_ADDR); + binfo->initrd_start); if (rc < 0) { fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n"); } rc = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", - binfo->loader_start + INITRD_LOAD_ADDR + - binfo->initrd_size); + binfo->initrd_start + binfo->initrd_size); if (rc < 0) { fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n"); } @@ -375,6 +374,14 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) big_endian = 0; #endif + /* Put the initrd halfway through RAM; this means that on + * most boards we will not be in danger of overlapping the + * initrd with the kernel, but will still work OK on models + * with only small amounts of RAM (which can be assumed to + * have correspondingly small kernels). + */ + info->initrd_start = info->loader_start + (info->ram_size / 2); + /* Assume that raw images are linux kernels, and ELF images are not. */ kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry, NULL, NULL, big_endian, ELF_MACHINE, 1); @@ -398,10 +405,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) if (is_linux) { if (info->initrd_filename) { initrd_size = load_image_targphys(info->initrd_filename, - info->loader_start - + INITRD_LOAD_ADDR, - info->ram_size - - INITRD_LOAD_ADDR); + info->initrd_start, + info->ram_size - + info->initrd_start); if (initrd_size < 0) { fprintf(stderr, "qemu: could not load initrd '%s'\n", info->initrd_filename); @@ -419,9 +425,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) */ if (info->dtb_filename) { /* Place the DTB after the initrd in memory */ - hwaddr dtb_start = TARGET_PAGE_ALIGN(info->loader_start - + INITRD_LOAD_ADDR - + initrd_size); + hwaddr dtb_start = TARGET_PAGE_ALIGN(info->initrd_start + + initrd_size); if (load_dtb(dtb_start, info)) { exit(1); }