diff options
| author | Nicolas Pitre <nico@org.rmk.(none)> | 2004-11-10 14:52:03 +0000 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2004-11-10 14:52:03 +0000 |
| commit | f05ee51620a2a45f41ade10a1ce6bc378f8870a8 (patch) | |
| tree | 9bda241d30d8a3626e085df8dc8ea4ca7300eed4 | |
| parent | 457450ab3b946006299131970d8e1296db494a1e (diff) | |
[ARM PATCH] 2160/1: allow modules to work with XIP kernel
Patch from Nicolas Pitre
This should be applied on top of patch #2154/1.
This maps the XIP kernel in the same virtual area as used for kernel
modules instead of the previous arbitrary location. Doing so has the
advantage of having a well defined kernel address not conflicting
with the different definitions for VMALLOC_END, as well as making
modules loadable without any indirect long branch calls. The work
on XIPable MTD also requires this with code marked __xipram for the
same reason.
This of course reduces the space available for kernel modules from
16MB to either 14MB or 12MB depending on the size of the resulting
kernel but that shouldn't be a real issue at all, given that the
whole purpose behind XIP is to execute as much stuff from flash,
which is better achieved by compiling drivers in the kernel directly.
Signed-off-by: Nicolas Pitre
Signed-off-by: Russell King
| -rw-r--r-- | arch/arm/Makefile | 3 | ||||
| -rw-r--r-- | arch/arm/kernel/module.c | 13 | ||||
| -rw-r--r-- | arch/arm/mm/mm-armv.c | 18 |
3 files changed, 24 insertions, 10 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 56ebbcca7fa1..8b9760b93ee7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -110,8 +110,9 @@ 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. - xipaddr-y ?= 0xe8000000 TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ awk --non-decimal-data '/[:xdigit:]/ \ { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index a16951f49457..eb9240e9a7d5 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -9,6 +9,7 @@ * * Module allocation method suggested by Andi Kleen. */ +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/elf.h> @@ -19,6 +20,18 @@ #include <asm/pgtable.h> +#ifdef CONFIG_XIP_KERNEL +/* + * The XIP kernel text is mapped in the module area for modules and + * some other stuff to work without any indirect relocations. + * MODULE_START is redefined here and not in asm/memory.h to avoid + * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. + */ +extern void _etext; +#undef MODULE_START +#define MODULE_START (((unsigned long)&_etext + ~PGDIR_MASK) & PGDIR_MASK) +#endif + void *module_alloc(unsigned long size) { struct vm_struct *area; diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 77529a36653e..ebc696090222 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -433,7 +433,7 @@ static void __init create_mapping(struct map_desc *md) pgprot_t prot_pte; long off; - if (md->virtual != vectors_base() && md->virtual < PAGE_OFFSET) { + if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " "0x%08lx at 0x%08lx in user region\n", md->physical, md->virtual); @@ -532,6 +532,14 @@ void __init memtable_init(struct meminfo *mi) init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); +#ifdef CONFIG_XIP_KERNEL + p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; + p->virtual = (unsigned long)&_stext & PMD_MASK; + p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; + p->type = MT_ROM; + p ++; +#endif + for (i = 0; i < mi->nr_banks; i++) { if (mi->bank[i].size == 0) continue; @@ -543,14 +551,6 @@ void __init memtable_init(struct meminfo *mi) p ++; } -#ifdef CONFIG_XIP_KERNEL - p->physical = CONFIG_XIP_PHYS_ADDR & PMD_MASK; - p->virtual = (unsigned long)&_stext & PMD_MASK; - p->length = ((unsigned long)&_etext - p->virtual + ~PMD_MASK) & PMD_MASK; - p->type = MT_ROM; - p ++; -#endif - #ifdef FLUSH_BASE p->physical = FLUSH_BASE_PHYS; p->virtual = FLUSH_BASE; |
