From patchwork Sun Sep 30 23:21:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 1529341 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 44061DF266 for ; Sun, 30 Sep 2012 23:51:39 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TITGC-0004kk-Cs; Sun, 30 Sep 2012 23:49:20 +0000 Received: from bombadil.infradead.org ([2001:4830:2446:ff00:4687:fcff:fea6:5117]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TITG9-0004kf-EV for linux-arm-kernel@merlin.infradead.org; Sun, 30 Sep 2012 23:49:17 +0000 Received: from quartz.orcorp.ca ([184.70.90.242]) by bombadil.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TITG5-0007hC-Q6 for linux-arm-kernel@lists.infradead.org; Sun, 30 Sep 2012 23:49:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=obsidianresearch.com; s=rsa1; h=Content-Type:MIME-Version:Message-ID:Subject:To:From:Date; bh=MMSqp2k69XqslHOwuAYTFk+oOCUnNO8/nhuIBeSxZyg=; b=kuU+EpeqCIc12MROeA8wiTsw05VSfWoqWgaA1MCchW0uTW84i6tTDZSxpqZs1F6JyOOF6jMnxNEuWVQmaqAvG6nGC9AgXyOSRl2jjxa9tnU9DcjUdbIxUHJ/Ls30d9o7leXwqVPUhVMevET50DnFnbkVi8CQQIMbvdF+BgmqNiM=; Received: from jgg by quartz.orcorp.ca with local (Exim 4.72) (envelope-from ) id 1TISp2-00082P-BB; Sun, 30 Sep 2012 17:21:16 -0600 Date: Sun, 30 Sep 2012 17:21:16 -0600 From: Jason Gunthorpe To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH] [ARM] Use AT() in the linker script to create correct program headers Message-ID: <20120930232116.GC30637@obsidianresearch.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20120930_194914_197827_DC4D24EC X-CRM114-Status: GOOD ( 14.18 ) X-Spam-Score: -0.3 (/) X-Spam-Report: SpamAssassin version 3.3.2 on bombadil.infradead.org summary: Content analysis details: (-0.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record 1.7 URIBL_BLACK Contains an URL listed in the URIBL blacklist [URIs: proc.info] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The standard linux asm-generic/vmlinux.lds.h already supports this, and it seems other architectures do as well. The goal is to create an ELF file that has correct program headers. We want to see the VirtAddr be the runtime address of the kernel with the MMU turned on, and PhysAddr be the physical load address for the section with no MMU. This allows ELF based boot loaders to properly load vmlinux: $ readelf -l vmlinux Entry point 0x8000 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x008000 0xc0008000 0x00008000 0x372244 0x3a4310 RWE 0x8000 Signed-off-by: Jason Gunthorpe --- arch/arm/include/asm/memory.h | 2 +- arch/arm/kernel/vmlinux.lds.S | 47 ++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 5f6ddcc..4ce5b6d 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -283,7 +283,7 @@ static inline __deprecated void *bus_to_virt(unsigned long x) #define arch_is_coherent() 0 #endif -#endif +#endif /* __ASSEMBLY__ */ #include diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 36ff15b..07942b6 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -3,6 +3,13 @@ * Written by Martin Mares */ +/* If we have a known, fixed physical load address then set LOAD_OFFSET + and generate an ELF that has the physical load address in the program + headers. */ +#ifndef CONFIG_ARM_PATCH_PHYS_VIRT +#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET) +#endif + #include #include #include @@ -39,7 +46,7 @@ #endif OUTPUT_ARCH(arm) -ENTRY(stext) +ENTRY(phys_start) #ifndef __ARMEB__ jiffies = jiffies_64; @@ -86,11 +93,13 @@ SECTIONS #else . = PAGE_OFFSET + TEXT_OFFSET; #endif - .head.text : { + .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) { _text = .; + phys_start = . - LOAD_OFFSET; HEAD_TEXT } - .text : { /* Real text segment */ + /* Real text segment */ + .text : AT(ADDR(.text) - LOAD_OFFSET) { _stext = .; /* Text and read-only data */ __exception_text_start = .; *(.exception.text) @@ -119,12 +128,12 @@ SECTIONS * Stack unwinding tables */ . = ALIGN(8); - .ARM.unwind_idx : { + .ARM.unwind_idx : AT(ADDR(.ARM.unwind_idx) - LOAD_OFFSET) { __start_unwind_idx = .; *(.ARM.exidx*) __stop_unwind_idx = .; } - .ARM.unwind_tab : { + .ARM.unwind_tab : AT(ADDR(.ARM.unwind_tab) - LOAD_OFFSET) { __start_unwind_tab = .; *(.ARM.extab*) __stop_unwind_tab = .; @@ -139,35 +148,35 @@ SECTIONS #endif INIT_TEXT_SECTION(8) - .exit.text : { + .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { ARM_EXIT_KEEP(EXIT_TEXT) } - .init.proc.info : { + .init.proc.info : AT(ADDR(.init.proc.info) - LOAD_OFFSET) { ARM_CPU_DISCARD(PROC_INFO) } - .init.arch.info : { + .init.arch.info : AT(ADDR(.init.arch.info) - LOAD_OFFSET) { __arch_info_begin = .; *(.arch.info.init) __arch_info_end = .; } - .init.tagtable : { + .init.tagtable : AT(ADDR(.init.tagtable) - LOAD_OFFSET) { __tagtable_begin = .; *(.taglist.init) __tagtable_end = .; } #ifdef CONFIG_SMP_ON_UP - .init.smpalt : { + .init.smpalt : AT(ADDR(.init.smpalt) - LOAD_OFFSET) { __smpalt_begin = .; *(.alt.smp.init) __smpalt_end = .; } #endif - .init.pv_table : { + .init.pv_table : AT(ADDR(.init.pv_table) - LOAD_OFFSET) { __pv_table_begin = .; *(.pv_table) __pv_table_end = .; } - .init.data : { + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { #ifndef CONFIG_XIP_KERNEL INIT_DATA #endif @@ -178,7 +187,7 @@ SECTIONS INIT_RAM_FS } #ifndef CONFIG_XIP_KERNEL - .exit.data : { + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { ARM_EXIT_KEEP(EXIT_DATA) } #endif @@ -196,7 +205,7 @@ SECTIONS __data_loc = .; #endif - .data : AT(__data_loc) { + .data : AT(__data_loc - LOAD_OFFSET) { _data = .; /* address in memory */ _sdata = .; @@ -245,7 +254,7 @@ SECTIONS * free it after init has commenced and TCM contents have * been copied to its destination. */ - .tcm_start : { + .tcm_start : AT(ADDR(.tcm_start) - LOAD_OFFSET) { . = ALIGN(PAGE_SIZE); __tcm_start = .; __itcm_start = .; @@ -257,7 +266,7 @@ SECTIONS * and we'll upload the contents from RAM to TCM and free * the used RAM after that. */ - .text_itcm ITCM_OFFSET : AT(__itcm_start) + .text_itcm ITCM_OFFSET : AT(__itcm_start - LOAD_OFFSET) { __sitcm_text = .; *(.tcm.text) @@ -272,12 +281,12 @@ SECTIONS */ . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm); - .dtcm_start : { + .dtcm_start : AT(ADDR(.dtcm_start) - LOAD_OFFSET) { __dtcm_start = .; } /* TODO: add remainder of ITCM as well, that can be used for data! */ - .data_dtcm DTCM_OFFSET : AT(__dtcm_start) + .data_dtcm DTCM_OFFSET : AT(__dtcm_start - LOAD_OFFSET) { . = ALIGN(4); __sdtcm_data = .; @@ -290,7 +299,7 @@ SECTIONS . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm); /* End marker for freeing TCM copy in linked object */ - .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){ + .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm) - LOAD_OFFSET){ . = ALIGN(PAGE_SIZE); __tcm_end = .; }