Commit f05ee516 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

[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
parent 457450ab
...@@ -110,8 +110,9 @@ endif ...@@ -110,8 +110,9 @@ endif
TEXTADDR := $(textaddr-y) TEXTADDR := $(textaddr-y)
ifeq ($(CONFIG_XIP_KERNEL),y) ifeq ($(CONFIG_XIP_KERNEL),y)
DATAADDR := $(TEXTADDR) DATAADDR := $(TEXTADDR)
xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000
xipaddr-y ?= 0xbf000000
# Replace phys addr with virt addr while keeping offset from base. # Replace phys addr with virt addr while keeping offset from base.
xipaddr-y ?= 0xe8000000
TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \
awk --non-decimal-data '/[:xdigit:]/ \ awk --non-decimal-data '/[:xdigit:]/ \
{ printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' )
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* *
* Module allocation method suggested by Andi Kleen. * Module allocation method suggested by Andi Kleen.
*/ */
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/elf.h> #include <linux/elf.h>
...@@ -19,6 +20,18 @@ ...@@ -19,6 +20,18 @@
#include <asm/pgtable.h> #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) void *module_alloc(unsigned long size)
{ {
struct vm_struct *area; struct vm_struct *area;
......
...@@ -433,7 +433,7 @@ static void __init create_mapping(struct map_desc *md) ...@@ -433,7 +433,7 @@ static void __init create_mapping(struct map_desc *md)
pgprot_t prot_pte; pgprot_t prot_pte;
long off; 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 " printk(KERN_WARNING "BUG: not creating mapping for "
"0x%08lx at 0x%08lx in user region\n", "0x%08lx at 0x%08lx in user region\n",
md->physical, md->virtual); md->physical, md->virtual);
...@@ -532,6 +532,14 @@ void __init memtable_init(struct meminfo *mi) ...@@ -532,6 +532,14 @@ void __init memtable_init(struct meminfo *mi)
init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE); 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++) { for (i = 0; i < mi->nr_banks; i++) {
if (mi->bank[i].size == 0) if (mi->bank[i].size == 0)
continue; continue;
...@@ -543,14 +551,6 @@ void __init memtable_init(struct meminfo *mi) ...@@ -543,14 +551,6 @@ void __init memtable_init(struct meminfo *mi)
p ++; 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 #ifdef FLUSH_BASE
p->physical = FLUSH_BASE_PHYS; p->physical = FLUSH_BASE_PHYS;
p->virtual = FLUSH_BASE; p->virtual = FLUSH_BASE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment