diff options
author | Nicolas Pitre <nico@cam.org> | 2005-10-29 16:44:56 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-10-29 16:44:56 -0400 |
commit | 37d07b72ef58f2d5ec7701ab75084fbeee0e503e (patch) | |
tree | da42fbad5b8ac6c79a258a46aff5f5d338ac138f | |
parent | f09b99799991c7c3ba441162406247f5df077322 (diff) |
[ARM] 3061/1: cleanup the XIP link address mess
Patch from Nicolas Pitre
Since vmlinux.lds.S is preprocessed, we can use the defines already
present in asm/memory.h (allowed by patch #3060) for the XIP kernel link
address instead of relying on a duplicated Makefile hardcoded value, and
also get rid of its dependency on awk to handle it at the same time.
While at it let's clean XIP stuff even further and make things clearer
in head.S with a nice code reduction.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-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 | /* |