diff options
| -rw-r--r-- | arch/arm/Makefile | 14 | ||||
| -rw-r--r-- | arch/arm/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/head.S | 54 | ||||
| -rw-r--r-- | arch/arm/kernel/vmlinux.lds.S | 11 | ||||
| -rw-r--r-- | include/asm-arm/memory.h | 7 |
5 files changed, 36 insertions, 52 deletions
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 @@ | |||
| 8 | # Copyright (C) 1995-2001 by Russell King | 8 | # Copyright (C) 1995-2001 by Russell King |
| 9 | 9 | ||
| 10 | LDFLAGS_vmlinux :=-p --no-undefined -X | 10 | LDFLAGS_vmlinux :=-p --no-undefined -X |
| 11 | CPPFLAGS_vmlinux.lds = -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) | 11 | CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR) |
| 12 | OBJCOPYFLAGS :=-O binary -R .note -R .comment -S | 12 | OBJCOPYFLAGS :=-O binary -R .note -R .comment -S |
| 13 | GZFLAGS :=-9 | 13 | GZFLAGS :=-9 |
| 14 | #CFLAGS +=-pipe | 14 | #CFLAGS +=-pipe |
| @@ -108,27 +108,19 @@ export CFLAGS_3c589_cs.o | |||
| 108 | endif | 108 | endif |
| 109 | 109 | ||
| 110 | TEXTADDR := $(textaddr-y) | 110 | TEXTADDR := $(textaddr-y) |
| 111 | ifeq ($(CONFIG_XIP_KERNEL),y) | ||
| 112 | DATAADDR := $(TEXTADDR) | ||
| 113 | xipaddr-$(CONFIG_ARCH_CO285) := 0x5f000000 | ||
| 114 | xipaddr-y ?= 0xbf000000 | ||
| 115 | # Replace phys addr with virt addr while keeping offset from base. | ||
| 116 | TEXTADDR := $(shell echo $(CONFIG_XIP_PHYS_ADDR) $(xipaddr-y) | \ | ||
| 117 | awk --non-decimal-data '/[:xdigit:]/ \ | ||
| 118 | { printf("0x%x\n", and($$1, 0x000fffff) + $$2) }' ) | ||
| 119 | endif | ||
| 120 | 111 | ||
| 121 | ifeq ($(incdir-y),) | 112 | ifeq ($(incdir-y),) |
| 122 | incdir-y := $(machine-y) | 113 | incdir-y := $(machine-y) |
| 123 | endif | 114 | endif |
| 124 | INCDIR := arch-$(incdir-y) | 115 | INCDIR := arch-$(incdir-y) |
| 116 | |||
| 125 | ifneq ($(machine-y),) | 117 | ifneq ($(machine-y),) |
| 126 | MACHINE := arch/arm/mach-$(machine-y)/ | 118 | MACHINE := arch/arm/mach-$(machine-y)/ |
| 127 | else | 119 | else |
| 128 | MACHINE := | 120 | MACHINE := |
| 129 | endif | 121 | endif |
| 130 | 122 | ||
| 131 | export TEXTADDR DATAADDR GZFLAGS | 123 | export TEXTADDR GZFLAGS |
| 132 | 124 | ||
| 133 | # Do we have FASTFPE? | 125 | # Do we have FASTFPE? |
| 134 | FASTFPE :=arch/arm/fastfpe | 126 | 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 @@ | |||
| 2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) | 5 | AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR) |
| 6 | 6 | ||
| 7 | # Object file lists. | 7 | # Object file lists. |
| 8 | 8 | ||
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 @@ | |||
| 34 | #define MACHINFO_PGOFFIO 12 | 34 | #define MACHINFO_PGOFFIO 12 |
| 35 | #define MACHINFO_NAME 16 | 35 | #define MACHINFO_NAME 16 |
| 36 | 36 | ||
| 37 | #ifndef CONFIG_XIP_KERNEL | ||
| 38 | /* | 37 | /* |
| 39 | * We place the page tables 16K below TEXTADDR. Therefore, we must make sure | 38 | * swapper_pg_dir is the virtual address of the initial page table. |
| 40 | * that TEXTADDR is correctly set. Currently, we expect the least significant | 39 | * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must |
| 41 | * 16 bits to be 0x8000, but we could probably relax this restriction to | 40 | * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect |
| 42 | * TEXTADDR >= PAGE_OFFSET + 0x4000 | 41 | * the least significant 16 bits to be 0x8000, but we could probably |
| 43 | * | 42 | * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000. |
| 44 | * Note that swapper_pg_dir is the virtual address of the page tables, and | ||
| 45 | * pgtbl gives us a position-independent reference to these tables. We can | ||
| 46 | * do this because stext == TEXTADDR | ||
| 47 | */ | 43 | */ |
| 48 | #if (TEXTADDR & 0xffff) != 0x8000 | 44 | #if (KERNEL_RAM_ADDR & 0xffff) != 0x8000 |
| 49 | #error TEXTADDR must start at 0xXXXX8000 | 45 | #error KERNEL_RAM_ADDR must start at 0xXXXX8000 |
| 50 | #endif | 46 | #endif |
| 51 | 47 | ||
| 52 | .globl swapper_pg_dir | 48 | .globl swapper_pg_dir |
| 53 | .equ swapper_pg_dir, TEXTADDR - 0x4000 | 49 | .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000 |
| 54 | 50 | ||
| 55 | .macro pgtbl, rd, phys | 51 | .macro pgtbl, rd |
| 56 | adr \rd, stext | 52 | ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000)) |
| 57 | sub \rd, \rd, #0x4000 | ||
| 58 | .endm | 53 | .endm |
| 59 | #else | ||
| 60 | /* | ||
| 61 | * XIP Kernel: | ||
| 62 | * | ||
| 63 | * We place the page tables 16K below DATAADDR. Therefore, we must make sure | ||
| 64 | * that DATAADDR is correctly set. Currently, we expect the least significant | ||
| 65 | * 16 bits to be 0x8000, but we could probably relax this restriction to | ||
| 66 | * DATAADDR >= PAGE_OFFSET + 0x4000 | ||
| 67 | * | ||
| 68 | * Note that pgtbl is meant to return the physical address of swapper_pg_dir. | ||
| 69 | * We can't make it relative to the kernel position in this case since | ||
| 70 | * the kernel can physically be anywhere. | ||
| 71 | */ | ||
| 72 | #if (DATAADDR & 0xffff) != 0x8000 | ||
| 73 | #error DATAADDR must start at 0xXXXX8000 | ||
| 74 | #endif | ||
| 75 | |||
| 76 | .globl swapper_pg_dir | ||
| 77 | .equ swapper_pg_dir, DATAADDR - 0x4000 | ||
| 78 | 54 | ||
| 79 | .macro pgtbl, rd, phys | 55 | #ifdef CONFIG_XIP_KERNEL |
| 80 | ldr \rd, =((DATAADDR - 0x4000) - PAGE_OFFSET) | 56 | #define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) |
| 81 | add \rd, \rd, \phys | 57 | #else |
| 82 | .endm | 58 | #define TEXTADDR KERNEL_RAM_ADDR |
| 83 | #endif | 59 | #endif |
| 84 | 60 | ||
| 85 | /* | 61 | /* |
| @@ -280,7 +256,7 @@ __turn_mmu_on: | |||
| 280 | .type __create_page_tables, %function | 256 | .type __create_page_tables, %function |
| 281 | __create_page_tables: | 257 | __create_page_tables: |
| 282 | ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram | 258 | ldr r5, [r8, #MACHINFO_PHYSRAM] @ physram |
| 283 | pgtbl r4, r5 @ page table address | 259 | pgtbl r4 @ page table address |
| 284 | 260 | ||
| 285 | /* | 261 | /* |
| 286 | * Clear the 16K level 1 swapper page table | 262 | * 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 @@ | |||
| 6 | #include <asm-generic/vmlinux.lds.h> | 6 | #include <asm-generic/vmlinux.lds.h> |
| 7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
| 8 | #include <asm/thread_info.h> | 8 | #include <asm/thread_info.h> |
| 9 | #include <asm/memory.h> | ||
| 9 | 10 | ||
| 10 | OUTPUT_ARCH(arm) | 11 | OUTPUT_ARCH(arm) |
| 11 | ENTRY(stext) | 12 | ENTRY(stext) |
| 13 | |||
| 12 | #ifndef __ARMEB__ | 14 | #ifndef __ARMEB__ |
| 13 | jiffies = jiffies_64; | 15 | jiffies = jiffies_64; |
| 14 | #else | 16 | #else |
| 15 | jiffies = jiffies_64 + 4; | 17 | jiffies = jiffies_64 + 4; |
| 16 | #endif | 18 | #endif |
| 19 | |||
| 20 | #ifdef CONFIG_XIP_KERNEL | ||
| 21 | #define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) | ||
| 22 | #else | ||
| 23 | #define TEXTADDR KERNEL_RAM_ADDR | ||
| 24 | #endif | ||
| 25 | |||
| 17 | SECTIONS | 26 | SECTIONS |
| 18 | { | 27 | { |
| 19 | . = TEXTADDR; | 28 | . = TEXTADDR; |
| @@ -95,7 +104,7 @@ SECTIONS | |||
| 95 | 104 | ||
| 96 | #ifdef CONFIG_XIP_KERNEL | 105 | #ifdef CONFIG_XIP_KERNEL |
| 97 | __data_loc = ALIGN(4); /* location in binary */ | 106 | __data_loc = ALIGN(4); /* location in binary */ |
| 98 | . = DATAADDR; | 107 | . = KERNEL_RAM_ADDR; |
| 99 | #else | 108 | #else |
| 100 | . = ALIGN(THREAD_SIZE); | 109 | . = ALIGN(THREAD_SIZE); |
| 101 | __data_loc = .; | 110 | __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 @@ | |||
| 68 | #error Top of user space clashes with start of module space | 68 | #error Top of user space clashes with start of module space |
| 69 | #endif | 69 | #endif |
| 70 | 70 | ||
| 71 | /* | ||
| 72 | * The XIP kernel gets mapped at the bottom of the module vm area. | ||
| 73 | * Since we use sections to map it, this macro replaces the physical address | ||
| 74 | * with its virtual address while keeping offset from the base section. | ||
| 75 | */ | ||
| 76 | #define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff)) | ||
| 77 | |||
| 71 | #ifndef __ASSEMBLY__ | 78 | #ifndef __ASSEMBLY__ |
| 72 | 79 | ||
| 73 | /* | 80 | /* |
