diff options
author | Eric Miao <eric.miao@canonical.com> | 2010-07-05 09:56:50 -0400 |
---|---|---|
committer | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2010-07-12 04:11:50 -0400 |
commit | e69edc7939abda1f696c482faa8168d80420f75c (patch) | |
tree | 55209745a63b2c3fd4f85827dc1969fdd2a16b7a /arch | |
parent | db7b2b4b0e0513627420940d3d62be44a37f0524 (diff) |
ARM: Auto calculate ZRELADDR and provide option for exceptions
As long as the zImage is placed within the 128MB range from the start of
memory, ZRELADDR (Address where the decompressed kernel will be placed,
usually == PHYS_OFFSET + TEXT_OFFSET) can be determined at run-time by
masking PC with 0xf80000000.
Running through all the Makefile.boot, all those zreladdr-y
addresses == 0x[0-f][08]00_0000 + TEXT_OFFSET can be determined at
run-time.
Option CONFIG_AUTO_ZRELADDR and CONFIG_ZRELADDR are introduced,
CONFIG_ZRELADDR _must_ be explicitly specified if:
- ((zreladdr-y - TEXT_OFFSET) & ~0xf8000000) != 0, which means
masking PC with 0xf8000000 will result in an incorrect address.
Currently this is only a problem on u300.
- or the assumption of the zImage being loaded by the bootloader within
the first 128MB of RAM is incorrect
- or when ZBOOT_ROM is used, where the above assumption is usually wrong.
[ukleinek: changed mask from 0xf0000000 to 0xf8000000 for mx1 and shark
+ some review fixes from the mailing list]
Original-Idea-and-Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Eric Miao <eric.miao@canonical.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 99 | ||||
-rw-r--r-- | arch/arm/boot/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/boot/compressed/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/boot/compressed/head.S | 12 |
4 files changed, 112 insertions, 10 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a53ac6570b66..0b0cf0d2872f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1490,6 +1490,105 @@ config ATAGS_PROC | |||
1490 | Should the atags used to boot the kernel be exported in an "atags" | 1490 | Should the atags used to boot the kernel be exported in an "atags" |
1491 | file in procfs. Useful with kexec. | 1491 | file in procfs. Useful with kexec. |
1492 | 1492 | ||
1493 | config AUTO_ZRELADDR | ||
1494 | bool "Auto calculation of the decompressed kernel image address" | ||
1495 | depends on !ZBOOT_ROM && !ARCH_U300 | ||
1496 | help | ||
1497 | ZRELADDR is the physical address where the decompressed kernel | ||
1498 | image will be placed. If AUTO_ZRELADDR is selected, the address | ||
1499 | will be determined at run-time by masking the current IP with | ||
1500 | 0xf8000000. This assumes the zImage being placed in the first 128MB | ||
1501 | from start of memory. | ||
1502 | |||
1503 | config ZRELADDR | ||
1504 | hex "Physical address of the decompressed kernel image" | ||
1505 | depends on !AUTO_ZRELADDR | ||
1506 | default 0x00008000 if ARCH_BCMRING ||\ | ||
1507 | ARCH_CNS3XXX ||\ | ||
1508 | ARCH_DOVE ||\ | ||
1509 | ARCH_EBSA110 ||\ | ||
1510 | ARCH_FOOTBRIDGE ||\ | ||
1511 | ARCH_INTEGRATOR ||\ | ||
1512 | ARCH_IOP13XX ||\ | ||
1513 | ARCH_IOP33X ||\ | ||
1514 | ARCH_IXP2000 ||\ | ||
1515 | ARCH_IXP23XX ||\ | ||
1516 | ARCH_IXP4XX ||\ | ||
1517 | ARCH_KIRKWOOD ||\ | ||
1518 | ARCH_KS8695 ||\ | ||
1519 | ARCH_LOKI ||\ | ||
1520 | ARCH_MMP ||\ | ||
1521 | ARCH_MV78XX0 ||\ | ||
1522 | ARCH_NOMADIK ||\ | ||
1523 | ARCH_NUC93X ||\ | ||
1524 | ARCH_NS9XXX ||\ | ||
1525 | ARCH_ORION5X ||\ | ||
1526 | ARCH_SPEAR3XX ||\ | ||
1527 | ARCH_SPEAR6XX ||\ | ||
1528 | ARCH_U8500 ||\ | ||
1529 | ARCH_VERSATILE ||\ | ||
1530 | ARCH_W90X900 | ||
1531 | default 0x08008000 if ARCH_MX1 ||\ | ||
1532 | ARCH_SHARK | ||
1533 | default 0x10008000 if ARCH_MSM ||\ | ||
1534 | ARCH_OMAP1 ||\ | ||
1535 | ARCH_RPC | ||
1536 | default 0x20008000 if ARCH_S5P6440 ||\ | ||
1537 | ARCH_S5P6442 ||\ | ||
1538 | ARCH_S5PC100 ||\ | ||
1539 | ARCH_S5PV210 | ||
1540 | default 0x30008000 if ARCH_S3C2410 ||\ | ||
1541 | ARCH_S3C2400 ||\ | ||
1542 | ARCH_S3C2412 ||\ | ||
1543 | ARCH_S3C2416 ||\ | ||
1544 | ARCH_S3C2440 ||\ | ||
1545 | ARCH_S3C2443 | ||
1546 | default 0x40008000 if ARCH_STMP378X ||\ | ||
1547 | ARCH_STMP37XX ||\ | ||
1548 | ARCH_SH7372 ||\ | ||
1549 | ARCH_SH7377 | ||
1550 | default 0x50008000 if ARCH_S3C64XX ||\ | ||
1551 | ARCH_SH7367 | ||
1552 | default 0x60008000 if ARCH_VEXPRESS | ||
1553 | default 0x80008000 if ARCH_MX25 ||\ | ||
1554 | ARCH_MX3 ||\ | ||
1555 | ARCH_NETX ||\ | ||
1556 | ARCH_OMAP2PLUS ||\ | ||
1557 | ARCH_PNX4008 | ||
1558 | default 0x90008000 if ARCH_MX5 ||\ | ||
1559 | ARCH_MX91231 | ||
1560 | default 0xa0008000 if ARCH_IOP32X ||\ | ||
1561 | ARCH_PXA ||\ | ||
1562 | MACH_MX27 | ||
1563 | default 0xc0008000 if ARCH_LH7A40X ||\ | ||
1564 | MACH_MX21 | ||
1565 | default 0xf0008000 if ARCH_AAEC2000 ||\ | ||
1566 | ARCH_L7200 | ||
1567 | default 0xc0028000 if ARCH_CLPS711X | ||
1568 | default 0x70008000 if ARCH_AT91 && (ARCH_AT91CAP9 || ARCH_AT91SAM9G45) | ||
1569 | default 0x20008000 if ARCH_AT91 && !(ARCH_AT91CAP9 || ARCH_AT91SAM9G45) | ||
1570 | default 0xc0008000 if ARCH_DAVINCI && ARCH_DAVINCI_DA8XX | ||
1571 | default 0x80008000 if ARCH_DAVINCI && !ARCH_DAVINCI_DA8XX | ||
1572 | default 0x00008000 if ARCH_EP93XX && EP93XX_SDCE3_SYNC_PHYS_OFFSET | ||
1573 | default 0xc0008000 if ARCH_EP93XX && EP93XX_SDCE0_PHYS_OFFSET | ||
1574 | default 0xd0008000 if ARCH_EP93XX && EP93XX_SDCE1_PHYS_OFFSET | ||
1575 | default 0xe0008000 if ARCH_EP93XX && EP93XX_SDCE2_PHYS_OFFSET | ||
1576 | default 0xf0008000 if ARCH_EP93XX && EP93XX_SDCE3_ASYNC_PHYS_OFFSET | ||
1577 | default 0x00008000 if ARCH_GEMINI && GEMINI_MEM_SWAP | ||
1578 | default 0x10008000 if ARCH_GEMINI && !GEMINI_MEM_SWAP | ||
1579 | default 0x70008000 if ARCH_REALVIEW && REALVIEW_HIGH_PHYS_OFFSET | ||
1580 | default 0x00008000 if ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET | ||
1581 | default 0xc0208000 if ARCH_SA1100 && SA1111 | ||
1582 | default 0xc0008000 if ARCH_SA1100 && !SA1111 | ||
1583 | default 0x30108000 if ARCH_S3C2410 && PM_H1940 | ||
1584 | default 0x28E08000 if ARCH_U300 && MACH_U300_SINGLE_RAM | ||
1585 | default 0x48008000 if ARCH_U300 && !MACH_U300_SINGLE_RAM | ||
1586 | help | ||
1587 | ZRELADDR is the physical address where the decompressed kernel | ||
1588 | image will be placed. ZRELADDR has to be specified when the | ||
1589 | assumption of AUTO_ZRELADDR is not valid, or when ZBOOT_ROM is | ||
1590 | selected. | ||
1591 | |||
1493 | endmenu | 1592 | endmenu |
1494 | 1593 | ||
1495 | menu "CPU Power Management" | 1594 | menu "CPU Power Management" |
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 4a590f4113e2..f705213caa88 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile | |||
@@ -14,18 +14,16 @@ | |||
14 | MKIMAGE := $(srctree)/scripts/mkuboot.sh | 14 | MKIMAGE := $(srctree)/scripts/mkuboot.sh |
15 | 15 | ||
16 | ifneq ($(MACHINE),) | 16 | ifneq ($(MACHINE),) |
17 | include $(srctree)/$(MACHINE)/Makefile.boot | 17 | -include $(srctree)/$(MACHINE)/Makefile.boot |
18 | endif | 18 | endif |
19 | 19 | ||
20 | # Note: the following conditions must always be true: | 20 | # Note: the following conditions must always be true: |
21 | # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) | ||
22 | # PARAMS_PHYS must be within 4MB of ZRELADDR | 21 | # PARAMS_PHYS must be within 4MB of ZRELADDR |
23 | # INITRD_PHYS must be in RAM | 22 | # INITRD_PHYS must be in RAM |
24 | ZRELADDR := $(zreladdr-y) | ||
25 | PARAMS_PHYS := $(params_phys-y) | 23 | PARAMS_PHYS := $(params_phys-y) |
26 | INITRD_PHYS := $(initrd_phys-y) | 24 | INITRD_PHYS := $(initrd_phys-y) |
27 | 25 | ||
28 | export ZRELADDR INITRD_PHYS PARAMS_PHYS | 26 | export INITRD_PHYS PARAMS_PHYS |
29 | 27 | ||
30 | targets := Image zImage xipImage bootpImage uImage | 28 | targets := Image zImage xipImage bootpImage uImage |
31 | 29 | ||
@@ -67,7 +65,7 @@ quiet_cmd_uimage = UIMAGE $@ | |||
67 | ifeq ($(CONFIG_ZBOOT_ROM),y) | 65 | ifeq ($(CONFIG_ZBOOT_ROM),y) |
68 | $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) | 66 | $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT) |
69 | else | 67 | else |
70 | $(obj)/uImage: LOADADDR=$(ZRELADDR) | 68 | $(obj)/uImage: LOADADDR=$(CONFIG_ZRELADDR) |
71 | endif | 69 | endif |
72 | 70 | ||
73 | ifeq ($(CONFIG_THUMB2_KERNEL),y) | 71 | ifeq ($(CONFIG_THUMB2_KERNEL),y) |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 2a80c9de6eaf..cc8380b879fe 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # create a compressed vmlinuz image from the original vmlinux | 4 | # create a compressed vmlinuz image from the original vmlinux |
5 | # | 5 | # |
6 | 6 | ||
7 | AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) | ||
7 | HEAD = head.o | 8 | HEAD = head.o |
8 | OBJS = misc.o decompress.o | 9 | OBJS = misc.o decompress.o |
9 | FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c | 10 | FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c |
@@ -79,8 +80,6 @@ endif | |||
79 | EXTRA_CFLAGS := -fpic -fno-builtin | 80 | EXTRA_CFLAGS := -fpic -fno-builtin |
80 | EXTRA_AFLAGS := -Wa,-march=all | 81 | EXTRA_AFLAGS := -Wa,-march=all |
81 | 82 | ||
82 | # Supply ZRELADDR to the decompressor via a linker symbol. | ||
83 | LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR) | ||
84 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) | 83 | ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) |
85 | LDFLAGS_vmlinux += --be8 | 84 | LDFLAGS_vmlinux += --be8 |
86 | endif | 85 | endif |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index d27faa131796..abf4d65acf62 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -170,9 +170,16 @@ not_angel: | |||
170 | 170 | ||
171 | .text | 171 | .text |
172 | adr r0, LC0 | 172 | adr r0, LC0 |
173 | ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp}) | 173 | ARM( ldmia r0, {r1, r2, r3, r5, r6, r11, ip, sp}) |
174 | THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} ) | 174 | THUMB( ldmia r0, {r1, r2, r3, r5, r6, r11, ip} ) |
175 | THUMB( ldr sp, [r0, #32] ) | 175 | THUMB( ldr sp, [r0, #32] ) |
176 | #ifdef CONFIG_AUTO_ZRELADDR | ||
177 | @ determine final kernel image address | ||
178 | and r4, pc, #0xf8000000 | ||
179 | add r4, r4, #TEXT_OFFSET | ||
180 | #else | ||
181 | ldr r4, =CONFIG_ZRELADDR | ||
182 | #endif | ||
176 | subs r0, r0, r1 @ calculate the delta offset | 183 | subs r0, r0, r1 @ calculate the delta offset |
177 | 184 | ||
178 | @ if delta is zero, we are | 185 | @ if delta is zero, we are |
@@ -310,7 +317,6 @@ wont_overwrite: mov r0, r4 | |||
310 | LC0: .word LC0 @ r1 | 317 | LC0: .word LC0 @ r1 |
311 | .word __bss_start @ r2 | 318 | .word __bss_start @ r2 |
312 | .word _end @ r3 | 319 | .word _end @ r3 |
313 | .word zreladdr @ r4 | ||
314 | .word _start @ r5 | 320 | .word _start @ r5 |
315 | .word _image_size @ r6 | 321 | .word _image_size @ r6 |
316 | .word _got_start @ r11 | 322 | .word _got_start @ r11 |