aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2012-05-05 04:18:41 -0400
committerMichal Marek <mmarek@suse.cz>2012-05-05 15:19:33 -0400
commit1f2bfbd00e466ff3489b2ca5cc75b1cccd14c123 (patch)
tree6c630d3ee90a34d17f85d5c07dde67d4c27883a8 /scripts
parent95698570510b7be9ab1542a4a908242c05a9b0ed (diff)
kbuild: link of vmlinux moved to a script
Move the final link of vmlinux to a script to improve readability and maintainability of the code. The Makefile fragments used to link vmlinux has over the years seen far too many changes and the logic had become hard to follow. As the process by nature is serialized there was nothing gained including this in the Makefile. "um" has special link requirments - and the only way to handle this was to hard-code the linking of "um" in the script. This was better than trying to modularize it only for the benefit of "um" anyway. The shell script has been improved after input from: Arnaud Lacombe <lacombar@gmail.com> Nick Bowler <nbowler@elliptictech.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Cc: Arnaud Lacombe <lacombar@gmail.com> Cc: Nick Bowler <nbowler@elliptictech.com> Cc: Richard Weinberger <richard@nod.at> Signed-off-by: Michal Marek <mmarek@suse.cz>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/link-vmlinux.sh211
1 files changed, 211 insertions, 0 deletions
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
new file mode 100644
index 000000000000..26c5b658c2d5
--- /dev/null
+++ b/scripts/link-vmlinux.sh
@@ -0,0 +1,211 @@
1#!/bin/sh
2#
3# link vmlinux
4#
5# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and
6# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories
7# in the kernel tree, others are specified in arch/$(ARCH)/Makefile.
8# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first.
9#
10# vmlinux
11# ^
12# |
13# +-< $(KBUILD_VMLINUX_INIT)
14# | +--< init/version.o + more
15# |
16# +--< $(KBUILD_VMLINUX_MAIN)
17# | +--< drivers/built-in.o mm/built-in.o + more
18# |
19# +-< ${kallsymso} (see description in KALLSYMS section)
20#
21# vmlinux version (uname -v) cannot be updated during normal
22# descending-into-subdirs phase since we do not yet know if we need to
23# update vmlinux.
24# Therefore this step is delayed until just before final link of vmlinux.
25#
26# System.map is generated to document addresses of all kernel symbols
27
28# Error out on error
29set -e
30
31# Nice output in kbuild format
32# Will be supressed by "make -s"
33info()
34{
35 if [ "${quiet}" != "silent_" ]; then
36 printf " %-7s %s\n" ${1} ${2}
37 fi
38}
39
40# Link of vmlinux.o used for section mismatch analysis
41# ${1} output file
42modpost_link()
43{
44 ${LD} ${LDFLAGS} -r -o ${1} ${KBUILD_VMLINUX_INIT} \
45 --start-group ${KBUILD_VMLINUX_MAIN} --end-group
46}
47
48# Link of vmlinux
49# ${1} - optional extra .o files
50# ${2} - output file
51vmlinux_link()
52{
53 local lds="${objtree}/${KBUILD_LDS}"
54
55 if [ "${SRCARCH}" != "um" ]; then
56 ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
57 -T ${lds} ${KBUILD_VMLINUX_INIT} \
58 --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
59 else
60 ${CC} ${CFLAGS_vmlinux} -o ${2} \
61 -Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \
62 -Wl,--start-group \
63 ${KBUILD_VMLINUX_MAIN} \
64 -Wl,--end-group \
65 -lutil ${1}
66 rm -f linux
67 fi
68}
69
70
71# Create ${2} .o file with all symbols from the ${1} object file
72kallsyms()
73{
74 info KSYM ${2}
75 local kallsymopt;
76
77 if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then
78 kallsymopt=--all-symbols
79 fi
80
81 local aflags="${KBUILD_AFLAGS} ${NOSTDINC_FLAGS} \
82 ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}"
83
84 ${NM} -n ${1} | \
85 scripts/kallsyms ${kallsymopt} | \
86 ${CC} ${aflags} -c -o ${2} -x assembler-with-cpp -
87}
88
89# Create map file with all symbols from ${1}
90# See mksymap for additional details
91mksysmap()
92{
93 ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
94}
95
96# Delete output files in case of error
97trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR
98cleanup()
99{
100 rm -f .old_version
101 rm -f .tmp_System.map
102 rm -f .tmp_kallsyms*
103 rm -f .tmp_version
104 rm -f .tmp_vmlinux*
105 rm -f System.map
106 rm -f vmlinux
107 rm -f vmlinux.o
108}
109
110#
111#
112# Use "make V=1" to debug this script
113case "${KBUILD_VERBOSE}" in
114*1*)
115 set -x
116 ;;
117esac
118
119if [ "$1" = "clean" ]; then
120 cleanup
121 exit 0
122fi
123
124# We need access to CONFIG_ symbols
125. ./.config
126
127#link vmlinux.o
128info LD vmlinux.o
129modpost_link vmlinux.o
130
131# modpost vmlinux.o to check for section mismatches
132${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
133
134# Update version
135info GEN .version
136if [ ! -r .version ]; then
137 rm -f .version;
138 echo 1 >.version;
139else
140 mv .version .old_version;
141 expr 0$(cat .old_version) + 1 >.version;
142fi;
143
144# final build of init/
145${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
146
147kallsymso=""
148kallsyms_vmlinux=""
149if [ -n "${CONFIG_KALLSYMS}" ]; then
150
151 # kallsyms support
152 # Generate section listing all symbols and add it into vmlinux
153 # It's a three step process:
154 # 1) Link .tmp_vmlinux1 so it has all symbols and sections,
155 # but __kallsyms is empty.
156 # Running kallsyms on that gives us .tmp_kallsyms1.o with
157 # the right size
158 # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of
159 # the right size, but due to the added section, some
160 # addresses have shifted.
161 # From here, we generate a correct .tmp_kallsyms2.o
162 # 2a) We may use an extra pass as this has been necessary to
163 # woraround some alignment related bugs.
164 # KALLSYMS_EXTRA_PASS=1 is used to trigger this.
165 # 3) The correct ${kallsymso} is linked into the final vmlinux.
166 #
167 # a) Verify that the System.map from vmlinux matches the map from
168 # ${kallsymso}.
169
170 kallsymso=.tmp_kallsyms2.o
171 kallsyms_vmlinux=.tmp_vmlinux2
172
173 # step 1
174 vmlinux_link "" .tmp_vmlinux1
175 kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o
176
177 # step 2
178 vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2
179 kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o
180
181 # step 2a
182 if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then
183 kallsymso=.tmp_kallsyms3.o
184 kallsyms_vmlinux=.tmp_vmlinux3
185
186 vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3
187
188 kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o
189 fi
190fi
191
192info LD vmlinux
193vmlinux_link "${kallsymso}" vmlinux
194
195info SYSMAP System.map
196mksysmap vmlinux System.map
197
198# step a (see comment above)
199if [ -n "${CONFIG_KALLSYMS}" ]; then
200 mksysmap ${kallsyms_vmlinux} .tmp_System.map
201
202 if ! cmp -s System.map .tmp_System.map; then
203 echo Inconsistent kallsyms data
204 echo echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround
205 cleanup
206 exit 1
207 fi
208fi
209
210# We made a new kernel - delete old version file
211rm -f .old_version