From patchwork Thu Mar 9 07:28:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 95067 Delivered-To: patch@linaro.org Received: by 10.140.82.71 with SMTP id g65csp237371qgd; Wed, 8 Mar 2017 23:30:03 -0800 (PST) X-Received: by 10.223.128.202 with SMTP id 68mr9356338wrl.108.1489044603376; Wed, 08 Mar 2017 23:30:03 -0800 (PST) Return-Path: Received: from lists.denx.de (dione.denx.de. [81.169.180.215]) by mx.google.com with ESMTP id g13si3273063wmd.11.2017.03.08.23.30.02; Wed, 08 Mar 2017 23:30:03 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) client-ip=81.169.180.215; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of u-boot-bounces@lists.denx.de designates 81.169.180.215 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by lists.denx.de (Postfix, from userid 105) id 89104C21C70; Thu, 9 Mar 2017 07:29:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B046DC21C30; Thu, 9 Mar 2017 07:29:56 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 94FCEC21C30; Thu, 9 Mar 2017 07:29:54 +0000 (UTC) Received: from conuserg-09.nifty.com (conuserg-09.nifty.com [210.131.2.76]) by lists.denx.de (Postfix) with ESMTPS id 5192AC21C2E for ; Thu, 9 Mar 2017 07:29:53 +0000 (UTC) Received: from pug.jp.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v297SVZU014102; Thu, 9 Mar 2017 16:28:31 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v297SVZU014102 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1489044512; bh=9UEUPMaclSFz5eTBL393ycp2X3OVTaVZgYHuOMO/1Uw=; h=From:To:Cc:Subject:Date:From; b=e7yRQdTrBDfQQKBWTFcTBSAPOTUYtQNPiTC4CaInRqA+RFyD/XGwaTIrrMtxGB8Ce d/MTQ6sW2J2Bm3nb/Hs2orjJGm5poJi6I+RksuibY8JAhcFPfJmvNmFyGp4fJTe4Ef eUfrSi6LABJ8mHJL2NMoQfwLPCJ8Jn7P9Ojf6Hl2AWg4sALiB1EtjqTZmicE6F3Fp7 XnnEEZQLbEsp6D+bWx2xZvYC15bEN5LKwpYKLjPBleVMRpx3WC+ei5B/Q6CXiYN6OH J+kv2mo3G2F2SWMIe9ufBsU0QumtPAKC/Y2QQ1mZbrOxWp8u0HYY5penxCDIQ8ENR0 GiXa7uKyMk4XA== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Thu, 9 Mar 2017 16:28:25 +0900 Message-Id: <1489044506-31797-1-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 Cc: Tom Rini , Scott Wood Subject: [U-Boot] [PATCH v3] arm64: booti: allow to place kernel image anywhere in physical memory X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" At first, the ARM64 Linux booting requirement recommended that the kernel image be placed text_offset bytes from 2MB aligned base near the start of usable system RAM because memory below that base address was unusable at that time. This requirement was relaxed by Linux commit a7f8de168ace ("arm64: allow kernel Image to be loaded anywhere in physical memory"). Since then, the bit 3 of the flags field indicates the tolerance of the kernel physical placement. If this bit is set, the 2MB aligned base may be anywhere in physical memory. For details, see Documentation/arm64/booting.txt of Linux. The booti command should be also relaxed. If the bit 3 is set, images->ep is respected, and the image is placed at the nearest bootable location. Otherwise, it is relocated to the start of the system RAM to keep the original behavior. Another wrinkle we need to take care of is the unknown endianness of text_offset for a kernel older than commit a2c1d73b94ed (i.e. v3.16). We can detect this based on the image_size field. If the field is zero, just use a fixed offset 0x80000. Signed-off-by: Masahiro Yamada --- Changes in v3: - Use a fixed offset 0x80000 for old kernel Changes in v2: - Use le64_to_cpu() for correct endian-ness - Check the bit 3 cmd/booti.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/cmd/booti.c b/cmd/booti.c index bff87a8..da6fb01 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -20,7 +22,7 @@ struct Image_header { uint32_t code1; /* Executable code */ uint64_t text_offset; /* Image load offset, LE */ uint64_t image_size; /* Effective Image size, LE */ - uint64_t res1; /* reserved */ + uint64_t flags; /* Kernel flags, LE */ uint64_t res2; /* reserved */ uint64_t res3; /* reserved */ uint64_t res4; /* reserved */ @@ -34,7 +36,7 @@ static int booti_setup(bootm_headers_t *images) { struct Image_header *ih; uint64_t dst; - uint64_t image_size; + uint64_t image_size, text_offset; ih = (struct Image_header *)map_sysmem(images->ep, 0); @@ -42,19 +44,33 @@ static int booti_setup(bootm_headers_t *images) puts("Bad Linux ARM64 Image magic!\n"); return 1; } - + + /* + * Prior to Linux commit a2c1d73b94ed, the text_offset field + * is of unknown endianness. In these cases, the image_size + * field is zero, and we can assume a fixed value of 0x80000. + */ if (ih->image_size == 0) { puts("Image lacks image_size field, assuming 16MiB\n"); image_size = 16 << 20; + text_offset = 0x80000; } else { image_size = le64_to_cpu(ih->image_size); + text_offset = le64_to_cpu(ih->text_offset); } /* - * If we are not at the correct run-time location, set the new - * correct location and then move the image there. + * If bit 3 of the flags field is set, the 2MB aligned base of the + * kernel image can be anywhere in physical memory, so respect + * images->ep. Otherwise, relocate the image to the base of RAM + * since memory below it is not accessible via the linear mapping. */ - dst = gd->bd->bi_dram[0].start + le64_to_cpu(ih->text_offset); + if (le64_to_cpu(ih->flags) & BIT(3)) + dst = images->ep - text_offset; + else + dst = gd->bd->bi_dram[0].start; + + dst = ALIGN(dst, SZ_2M) + text_offset; unmap_sysmem(ih);