History

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>

Sam Ravnborg committed 14 years ago

Commit 1f2bfbd1 parent 95698573 files · +225 −212Browse files

Showing the changes to scripts (1 of 3 files). Show all

Unified · Split

scripts/link-vmlinux.sh+211−0
@@ -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
29+set -e
30+
31+# Nice output in kbuild format
32+# Will be supressed by "make -s"
33+info()
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
42+modpost_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
51+vmlinux_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
72+kallsyms()
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
91+mksysmap()
92+{
93+ ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
94+}
95+
96+# Delete output files in case of error
97+trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR
98+cleanup()
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
113+case "${KBUILD_VERBOSE}" in
114+*1*)
115+ set -x
116+ ;;
117+esac
118+
119+if [ "$1" = "clean" ]; then
120+ cleanup
121+ exit 0
122+fi
123+
124+# We need access to CONFIG_ symbols
125+. ./.config
126+
127+#link vmlinux.o
128+info LD vmlinux.o
129+modpost_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
135+info GEN .version
136+if [ ! -r .version ]; then
137+ rm -f .version;
138+ echo 1 >.version;
139+else
140+ mv .version .old_version;
141+ expr 0$(cat .old_version) + 1 >.version;
142+fi;
143+
144+# final build of init/
145+${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init
146+
147+kallsymso=""
148+kallsyms_vmlinux=""
149+if [ -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
190+fi
191+
192+info LD vmlinux
193+vmlinux_link "${kallsymso}" vmlinux
194+
195+info SYSMAP System.map
196+mksysmap vmlinux System.map
197+
198+# step a (see comment above)
199+if [ -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
208+fi
209+
210+# We made a new kernel - delete old version file
211+rm -f .old_version