diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 299bc0468702..64cf480b0b02 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -8,7 +8,7 @@ # Copyright (C) 1995-2001 by Russell King LDFLAGS_vmlinux :=-p --no-undefined -X -CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) +CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 #CFLAGS +=-pipe @@ -108,27 +108,19 @@ export CFLAGS_3c589_cs.o endif TEXTADDR := $(textaddr-y) -ifeq ($(CONFIG_XIP_KERNEL),y) - DATAADDR := $(TEXTADDR) - xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000 - xipaddr-y ?= 0xbf000000 - # Replace phys addr with virt addr while keeping offset from base. - TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ - awk --non-decimal-data '/[:xdigit:]/ \ - { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) -endif ifeq ($(incdir-y),) incdir-y := $(machine-y) endif INCDIR := arch-$(incdir-y) + ifneq ($(machine-y),) MACHINE := arch/arm/mach-$(machine-y)/ else MACHINE := endif -export TEXTADDR DATAADDR GZFLAGS +export TEXTADDR GZFLAGS # Do we have FASTFPE? FASTFPE :=arch/arm/fastfpe diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 3e1b0327e4d7..c11169b5ed9a 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) +AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR) # Object file lists. diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index dd5d0f07d358..8d8748407cbe 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -34,52 +34,28 @@ #define MACHINFO_PGOFFIO 12 #define MACHINFO_NAME 16 -#ifndef CONFIG_XIP_KERNEL /* - * We place the page tables 16K below TEXTADDR. Therefore, we must make sure - * that TEXTADDR is correctly set. Currently, we expect the least significant - * 16 bits to be 0x8000, but we could probably relax this restriction to - * TEXTADDR >= PAGE_OFFSET + 0x4000 - * - * Note that swapper_pg_dir is the virtual address of the page tables, and - * pgtbl gives us a position-independent reference to these tables. We can - * do this because stext == TEXTADDR + * swapper_pg_dir is the virtual address of the initial page table. + * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must + * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect + * the least significant 16 bits to be 0x8000, but we could probably + * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000. */ -#if (TEXTADDR & 0xffff) != 0x8000 -#error TEXTADDR must start at 0xXXXX8000 +#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000 +#error KERNEL_RAM_ADDR must start at 0xXXXX8000 #endif .globl swapper_pg_dir - .equ swapper_pg_dir, TEXTADDR - 0x4000 + .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000 - .macro pgtbl, rd, phys - adr \rd, stext - sub \rd, \rd, #0x4000 + .macro pgtbl, rd + ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000)) .endm + +#ifdef CONFIG_XIP_KERNEL +#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) #else -/* - * XIP Kernel: - * - * We place the page tables 16K below DATAADDR. Therefore, we must make sure - * that DATAADDR is correctly set. Currently, we expect the least significant - * 16 bits to be 0x8000, but we could probably relax this restriction to - * DATAADDR >= PAGE_OFFSET + 0x4000 - * - * Note that pgtbl is meant to return the physical address of swapper_pg_dir. - * We can't make it relative to the kernel position in this case since - * the kernel can physically be anywhere. - */ -#if (DATAADDR & 0xffff) != 0x8000 -#error DATAADDR must start at 0xXXXX8000 -#endif - - .globl swapper_pg_dir - .equ swapper_pg_dir, DATAADDR - 0x4000 - - .macro pgtbl, rd, phys - ldr \rd, =((DATAADDR - 0x4000) - PAGE_OFFSET) - add \rd, \rd, \phys - .endm +#define TEXTADDR KERNEL_RAM_ADDR #endif /* @@ -280,7 +256,7 @@ __turn_mmu_on: .type __create_page_tables, %function __create_page_tables: ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram - pgtbl r4, r5 @ page table address + pgtbl r4 @ page table address /* * Clear the 16K level 1 swapper page table diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 0d5db5279c5c..80c8e4c8cefa 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -6,14 +6,23 @@ #include #include #include +#include OUTPUT_ARCH(arm) ENTRY(stext) + #ifndef __ARMEB__ jiffies = jiffies_64; #else jiffies = jiffies_64 + 4; #endif + +#ifdef CONFIG_XIP_KERNEL +#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) +#else +#define TEXTADDR KERNEL_RAM_ADDR +#endif + SECTIONS { . = TEXTADDR; @@ -95,7 +104,7 @@ SECTIONS #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ - . = DATAADDR; + . = KERNEL_RAM_ADDR; #else . = ALIGN(THREAD_SIZE); __data_loc = .; diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h index bee10fcf7e83..a547ee598c6c 100644 --- a/include/asm-arm/memory.h +++ b/include/asm-arm/memory.h @@ -68,6 +68,13 @@ #error Top of user space clashes with start of module space #endif +/* + * The XIP kernel gets mapped at the bottom of the module vm area. + * Since we use sections to map it, this macro replaces the physical address + * with its virtual address while keeping offset from the base section. + */ +#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff)) + #ifndef __ASSEMBLY__ /*