diff options
-rw-r--r-- | arch/powerpc/boot/crt0.S | 116 | ||||
-rwxr-xr-x | arch/powerpc/boot/wrapper | 9 | ||||
-rw-r--r-- | arch/powerpc/boot/zImage.coff.lds.S | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/zImage.lds.S | 57 |
4 files changed, 118 insertions, 70 deletions
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index f1c4dfc635be..0f7428a37efb 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -6,16 +6,28 @@ | |||
6 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License, or (at your option) any later version. |
8 | * | 8 | * |
9 | * NOTE: this code runs in 32 bit mode and is packaged as ELF32. | 9 | * NOTE: this code runs in 32 bit mode, is position-independent, |
10 | * and is packaged as ELF32. | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #include "ppc_asm.h" | 13 | #include "ppc_asm.h" |
13 | 14 | ||
14 | .text | 15 | .text |
15 | /* a procedure descriptor used when booting this as a COFF file */ | 16 | /* A procedure descriptor used when booting this as a COFF file. |
17 | * When making COFF, this comes first in the link and we're | ||
18 | * linked at 0x500000. | ||
19 | */ | ||
16 | .globl _zimage_start_opd | 20 | .globl _zimage_start_opd |
17 | _zimage_start_opd: | 21 | _zimage_start_opd: |
18 | .long _zimage_start, 0, 0, 0 | 22 | .long 0x500000, 0, 0, 0 |
23 | |||
24 | p_start: .long _start | ||
25 | p_etext: .long _etext | ||
26 | p_bss_start: .long __bss_start | ||
27 | p_end: .long _end | ||
28 | |||
29 | .weak _platform_stack_top | ||
30 | p_pstack: .long _platform_stack_top | ||
19 | 31 | ||
20 | .weak _zimage_start | 32 | .weak _zimage_start |
21 | .globl _zimage_start | 33 | .globl _zimage_start |
@@ -24,37 +36,65 @@ _zimage_start: | |||
24 | _zimage_start_lib: | 36 | _zimage_start_lib: |
25 | /* Work out the offset between the address we were linked at | 37 | /* Work out the offset between the address we were linked at |
26 | and the address where we're running. */ | 38 | and the address where we're running. */ |
27 | bl 1f | 39 | bl .+4 |
28 | 1: mflr r0 | 40 | p_base: mflr r10 /* r10 now points to runtime addr of p_base */ |
29 | lis r9,1b@ha | 41 | /* grab the link address of the dynamic section in r11 */ |
30 | addi r9,r9,1b@l | 42 | addis r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha |
31 | subf. r0,r9,r0 | 43 | lwz r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11) |
32 | beq 3f /* if running at same address as linked */ | 44 | cmpwi r11,0 |
45 | beq 3f /* if not linked -pie */ | ||
46 | /* get the runtime address of the dynamic section in r12 */ | ||
47 | .weak __dynamic_start | ||
48 | addis r12,r10,(__dynamic_start-p_base)@ha | ||
49 | addi r12,r12,(__dynamic_start-p_base)@l | ||
50 | subf r11,r11,r12 /* runtime - linktime offset */ | ||
51 | |||
52 | /* The dynamic section contains a series of tagged entries. | ||
53 | * We need the RELA and RELACOUNT entries. */ | ||
54 | RELA = 7 | ||
55 | RELACOUNT = 0x6ffffff9 | ||
56 | li r9,0 | ||
57 | li r0,0 | ||
58 | 9: lwz r8,0(r12) /* get tag */ | ||
59 | cmpwi r8,0 | ||
60 | beq 10f /* end of list */ | ||
61 | cmpwi r8,RELA | ||
62 | bne 11f | ||
63 | lwz r9,4(r12) /* get RELA pointer in r9 */ | ||
64 | b 12f | ||
65 | 11: addis r8,r8,(-RELACOUNT)@ha | ||
66 | cmpwi r8,RELACOUNT@l | ||
67 | bne 12f | ||
68 | lwz r0,4(r12) /* get RELACOUNT value in r0 */ | ||
69 | 12: addi r12,r12,8 | ||
70 | b 9b | ||
33 | 71 | ||
34 | /* The .got2 section contains a list of addresses, so add | 72 | /* The relocation section contains a list of relocations. |
35 | the address offset onto each entry. */ | 73 | * We now do the R_PPC_RELATIVE ones, which point to words |
36 | lis r9,__got2_start@ha | 74 | * which need to be initialized with addend + offset. |
37 | addi r9,r9,__got2_start@l | 75 | * The R_PPC_RELATIVE ones come first and there are RELACOUNT |
38 | lis r8,__got2_end@ha | 76 | * of them. */ |
39 | addi r8,r8,__got2_end@l | 77 | 10: /* skip relocation if we don't have both */ |
40 | subf. r8,r9,r8 | 78 | cmpwi r0,0 |
41 | beq 3f | 79 | beq 3f |
42 | srwi. r8,r8,2 | 80 | cmpwi r9,0 |
43 | mtctr r8 | 81 | beq 3f |
44 | add r9,r0,r9 | 82 | |
45 | 2: lwz r8,0(r9) | 83 | add r9,r9,r11 /* Relocate RELA pointer */ |
46 | add r8,r8,r0 | 84 | mtctr r0 |
47 | stw r8,0(r9) | 85 | 2: lbz r0,4+3(r9) /* ELF32_R_INFO(reloc->r_info) */ |
48 | addi r9,r9,4 | 86 | cmpwi r0,22 /* R_PPC_RELATIVE */ |
87 | bne 3f | ||
88 | lwz r12,0(r9) /* reloc->r_offset */ | ||
89 | lwz r0,8(r9) /* reloc->r_addend */ | ||
90 | add r0,r0,r11 | ||
91 | stwx r0,r11,r12 | ||
92 | addi r9,r9,12 | ||
49 | bdnz 2b | 93 | bdnz 2b |
50 | 94 | ||
51 | /* Do a cache flush for our text, in case the loader didn't */ | 95 | /* Do a cache flush for our text, in case the loader didn't */ |
52 | 3: lis r9,_start@ha | 96 | 3: lwz r9,p_start-p_base(r10) /* note: these are relocated now */ |
53 | addi r9,r9,_start@l | 97 | lwz r8,p_etext-p_base(r10) |
54 | add r9,r0,r9 | ||
55 | lis r8,_etext@ha | ||
56 | addi r8,r8,_etext@l | ||
57 | add r8,r0,r8 | ||
58 | 4: dcbf r0,r9 | 98 | 4: dcbf r0,r9 |
59 | icbi r0,r9 | 99 | icbi r0,r9 |
60 | addi r9,r9,0x20 | 100 | addi r9,r9,0x20 |
@@ -64,27 +104,19 @@ _zimage_start_lib: | |||
64 | isync | 104 | isync |
65 | 105 | ||
66 | /* Clear the BSS */ | 106 | /* Clear the BSS */ |
67 | lis r9,__bss_start@ha | 107 | lwz r9,p_bss_start-p_base(r10) |
68 | addi r9,r9,__bss_start@l | 108 | lwz r8,p_end-p_base(r10) |
69 | add r9,r0,r9 | 109 | li r0,0 |
70 | lis r8,_end@ha | 110 | 5: stw r0,0(r9) |
71 | addi r8,r8,_end@l | ||
72 | add r8,r0,r8 | ||
73 | li r10,0 | ||
74 | 5: stw r10,0(r9) | ||
75 | addi r9,r9,4 | 111 | addi r9,r9,4 |
76 | cmplw cr0,r9,r8 | 112 | cmplw cr0,r9,r8 |
77 | blt 5b | 113 | blt 5b |
78 | 114 | ||
79 | /* Possibly set up a custom stack */ | 115 | /* Possibly set up a custom stack */ |
80 | .weak _platform_stack_top | 116 | lwz r8,p_pstack-p_base(r10) |
81 | lis r8,_platform_stack_top@ha | ||
82 | addi r8,r8,_platform_stack_top@l | ||
83 | cmpwi r8,0 | 117 | cmpwi r8,0 |
84 | beq 6f | 118 | beq 6f |
85 | add r8,r0,r8 | ||
86 | lwz r1,0(r8) | 119 | lwz r1,0(r8) |
87 | add r1,r0,r1 | ||
88 | li r0,0 | 120 | li r0,0 |
89 | stwu r0,-16(r1) /* establish a stack frame */ | 121 | stwu r0,-16(r1) /* establish a stack frame */ |
90 | 6: | 122 | 6: |
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index cb97e7511d7e..fef527867811 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
@@ -39,6 +39,7 @@ dts= | |||
39 | cacheit= | 39 | cacheit= |
40 | binary= | 40 | binary= |
41 | gzip=.gz | 41 | gzip=.gz |
42 | pie= | ||
42 | 43 | ||
43 | # cross-compilation prefix | 44 | # cross-compilation prefix |
44 | CROSS= | 45 | CROSS= |
@@ -157,9 +158,10 @@ pmac|chrp) | |||
157 | platformo=$object/of.o | 158 | platformo=$object/of.o |
158 | ;; | 159 | ;; |
159 | coff) | 160 | coff) |
160 | platformo=$object/of.o | 161 | platformo="$object/crt0.o $object/of.o" |
161 | lds=$object/zImage.coff.lds | 162 | lds=$object/zImage.coff.lds |
162 | link_address='0x500000' | 163 | link_address='0x500000' |
164 | pie= | ||
163 | ;; | 165 | ;; |
164 | miboot|uboot) | 166 | miboot|uboot) |
165 | # miboot and U-boot want just the bare bits, not an ELF binary | 167 | # miboot and U-boot want just the bare bits, not an ELF binary |
@@ -208,6 +210,7 @@ ps3) | |||
208 | ksection=.kernel:vmlinux.bin | 210 | ksection=.kernel:vmlinux.bin |
209 | isection=.kernel:initrd | 211 | isection=.kernel:initrd |
210 | link_address='' | 212 | link_address='' |
213 | pie= | ||
211 | ;; | 214 | ;; |
212 | ep88xc|ep405|ep8248e) | 215 | ep88xc|ep405|ep8248e) |
213 | platformo="$object/fixed-head.o $object/$platform.o" | 216 | platformo="$object/fixed-head.o $object/$platform.o" |
@@ -310,9 +313,9 @@ fi | |||
310 | 313 | ||
311 | if [ "$platform" != "miboot" ]; then | 314 | if [ "$platform" != "miboot" ]; then |
312 | if [ -n "$link_address" ] ; then | 315 | if [ -n "$link_address" ] ; then |
313 | text_start="-Ttext $link_address --defsym _start=$link_address" | 316 | text_start="-Ttext $link_address" |
314 | fi | 317 | fi |
315 | ${CROSS}ld -m elf32ppc -T $lds $text_start -o "$ofile" \ | 318 | ${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \ |
316 | $platformo $tmp $object/wrapper.a | 319 | $platformo $tmp $object/wrapper.a |
317 | rm $tmp | 320 | rm $tmp |
318 | fi | 321 | fi |
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S index 856dc78b14ef..de4c9e3c9344 100644 --- a/arch/powerpc/boot/zImage.coff.lds.S +++ b/arch/powerpc/boot/zImage.coff.lds.S | |||
@@ -3,13 +3,13 @@ ENTRY(_zimage_start_opd) | |||
3 | EXTERN(_zimage_start_opd) | 3 | EXTERN(_zimage_start_opd) |
4 | SECTIONS | 4 | SECTIONS |
5 | { | 5 | { |
6 | _start = .; | ||
7 | .text : | 6 | .text : |
8 | { | 7 | { |
8 | _start = .; | ||
9 | *(.text) | 9 | *(.text) |
10 | *(.fixup) | 10 | *(.fixup) |
11 | _etext = .; | ||
11 | } | 12 | } |
12 | _etext = .; | ||
13 | . = ALIGN(4096); | 13 | . = ALIGN(4096); |
14 | .data : | 14 | .data : |
15 | { | 15 | { |
@@ -17,9 +17,7 @@ SECTIONS | |||
17 | *(.data*) | 17 | *(.data*) |
18 | *(__builtin_*) | 18 | *(__builtin_*) |
19 | *(.sdata*) | 19 | *(.sdata*) |
20 | __got2_start = .; | ||
21 | *(.got2) | 20 | *(.got2) |
22 | __got2_end = .; | ||
23 | 21 | ||
24 | _dtb_start = .; | 22 | _dtb_start = .; |
25 | *(.kernel:dtb) | 23 | *(.kernel:dtb) |
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 0962d62bdb50..2bd8731f1365 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S | |||
@@ -3,49 +3,64 @@ ENTRY(_zimage_start) | |||
3 | EXTERN(_zimage_start) | 3 | EXTERN(_zimage_start) |
4 | SECTIONS | 4 | SECTIONS |
5 | { | 5 | { |
6 | _start = .; | ||
7 | .text : | 6 | .text : |
8 | { | 7 | { |
8 | _start = .; | ||
9 | *(.text) | 9 | *(.text) |
10 | *(.fixup) | 10 | *(.fixup) |
11 | _etext = .; | ||
11 | } | 12 | } |
12 | _etext = .; | ||
13 | . = ALIGN(4096); | 13 | . = ALIGN(4096); |
14 | .data : | 14 | .data : |
15 | { | 15 | { |
16 | *(.rodata*) | 16 | *(.rodata*) |
17 | *(.data*) | 17 | *(.data*) |
18 | *(.sdata*) | 18 | *(.sdata*) |
19 | __got2_start = .; | ||
20 | *(.got2) | 19 | *(.got2) |
21 | __got2_end = .; | ||
22 | } | 20 | } |
21 | .dynsym : { *(.dynsym) } | ||
22 | .dynstr : { *(.dynstr) } | ||
23 | .dynamic : | ||
24 | { | ||
25 | __dynamic_start = .; | ||
26 | *(.dynamic) | ||
27 | } | ||
28 | .hash : { *(.hash) } | ||
29 | .interp : { *(.interp) } | ||
30 | .rela.dyn : { *(.rela*) } | ||
23 | 31 | ||
24 | . = ALIGN(8); | 32 | . = ALIGN(8); |
25 | _dtb_start = .; | 33 | .kernel:dtb : |
26 | .kernel:dtb : { *(.kernel:dtb) } | 34 | { |
27 | _dtb_end = .; | 35 | _dtb_start = .; |
28 | 36 | *(.kernel:dtb) | |
29 | . = ALIGN(4096); | 37 | _dtb_end = .; |
30 | _vmlinux_start = .; | 38 | } |
31 | .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } | ||
32 | _vmlinux_end = .; | ||
33 | 39 | ||
34 | . = ALIGN(4096); | 40 | . = ALIGN(4096); |
35 | _initrd_start = .; | 41 | .kernel:vmlinux.strip : |
36 | .kernel:initrd : { *(.kernel:initrd) } | 42 | { |
37 | _initrd_end = .; | 43 | _vmlinux_start = .; |
44 | *(.kernel:vmlinux.strip) | ||
45 | _vmlinux_end = .; | ||
46 | } | ||
38 | 47 | ||
39 | . = ALIGN(4096); | 48 | . = ALIGN(4096); |
40 | _edata = .; | 49 | .kernel:initrd : |
50 | { | ||
51 | _initrd_start = .; | ||
52 | *(.kernel:initrd) | ||
53 | _initrd_end = .; | ||
54 | } | ||
41 | 55 | ||
42 | . = ALIGN(4096); | 56 | . = ALIGN(4096); |
43 | __bss_start = .; | ||
44 | .bss : | 57 | .bss : |
45 | { | 58 | { |
46 | *(.sbss) | 59 | _edata = .; |
47 | *(.bss) | 60 | __bss_start = .; |
61 | *(.sbss) | ||
62 | *(.bss) | ||
63 | *(COMMON) | ||
64 | _end = . ; | ||
48 | } | 65 | } |
49 | . = ALIGN(4096); | ||
50 | _end = . ; | ||
51 | } | 66 | } |