Commit e9ba0414 authored by Sam Ravnborg's avatar Sam Ravnborg Committed by Tom Rini

kbuild: Simplify generating vmlinux

Generating vmlinux in top-level Makefile were getting a bit messy after kallsyms
support were added. Also the full link of all the .o files were duplicaed a number of times.
This patch does the following:
- Introduce built-in.o which is a prelink of most .o files
- Make the build process a bit more verbose telling when linking .tmpvmlinux*
- Use less magic when determing when to generate a new version
- Allow architectures to override the defineition of cmd_vmlinux__
- Add more comments to the MAkefile and clean up soem other comments
- Display more commends during V=1 builds

The resulting kernel boots and rn here.
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent ef41e994
......@@ -545,57 +545,83 @@ libs-y := $(libs-y1) $(libs-y2)
# Build vmlinux
# ---------------------------------------------------------------------------
# vmlinux is build from the objects seleted by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first.
#
# vmlinux
# ^
# |
# +-< $(vmlinux-init)
# | +--< init/version.o + more
# |
# +-< built-in.o
# | +--< $(vmlinux-main)
# | +--< driver/built-in.o mm/built-in.o + more
# |
# +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
#
# vmlinux version cannot be updated during normal descending-into-subdirs
# phase since we do not yet know if we need to update vmlinux.
# Therefore this step is delayed until just before final link of vmlinux -
# except in kallsyms case where it is done just before adding the
# symbols to the kernel.
#
# System.map is generated to document addresses of all kernel symbols
# This is a bit tricky: If we need to relink vmlinux, we want
# the version number incremented, which means recompile init/version.o
# and relink init/init.o. However, we cannot do this during the
# normal descending-into-subdirs phase, since at that time
# we cannot yet know if we will need to relink vmlinux.
# So we descend into init/ inside the rule for vmlinux again.
vmlinux-objs := $(head-y) $(init-y) $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) built-in.o
vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds
# Rule to link vmlinux - also used during CONFIG_KALLSYMS
# May be overridden by arch/$(ARCH)/Makefile
quiet_cmd_vmlinux__ = LD $@
define cmd_vmlinux__
$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) $(head-y) $(init-y) \
--start-group \
$(core-y) \
$(libs-y) \
$(drivers-y) \
$(net-y) \
--end-group \
$(filter .tmp_kallsyms%,$^) \
-o $@
endef
# set -e makes the rule exit immediately on error
cmd_vmlinux__ = $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
-T $(filter-out FORCE, $^) -o $@
define rule_vmlinux__
+set -e; \
$(if $(filter .tmp_kallsyms%,$^),, \
echo ' GEN .version'; \
# Generate new vmlinux version
quiet_cmd_vmlinux_version = GEN .version
cmd_vmlinux_version = set -e; \
. $(srctree)/scripts/mkversion > .tmp_version; \
mv -f .tmp_version .version; \
$(MAKE) $(build)=init; \
) \
$(if $($(quiet)cmd_vmlinux__), \
echo ' $($(quiet)cmd_vmlinux__)' &&) \
$(cmd_vmlinux__); \
echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef
$(MAKE) $(build)=init
# Generate System.map
quiet_cmd_sysmap = SYSMAP
cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds
# Link of vmlinux
# If CONFIG_KALLSYMS is set .version is already updated
# Generate System.map and verify that the content is consistent
define rule_vmlinux__
$(if $(CONFIG_KALLSYMS),,$(call cmd,vmlinux_version))
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
$(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) System.map' &&) \
$(cmd_sysmap) $@ System.map; \
if [ $$? -ne 0 ]; then \
rm -f $@; \
/bin/false; \
fi;
$(verify_kallsyms)
endef
# Generate section listing all symbols and add it into vmlinux
ifdef CONFIG_KALLSYMS
# Generate section listing all symbols and add it into vmlinux $(kallsyms.o)
# It's a three stage process:
# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is
# empty
# Running kallsyms on that gives us .tmp_kallsyms1.o with
# the right size
# the right size - vmlinux version updated during this step
# o .tmp_vmlinux2 now has a __kallsyms section of the right size,
# but due to the added section, some addresses have shifted
# but due to the added section, some addresses have shifted.
# From here, we generate a correct .tmp_kallsyms2.o
# o The correct .tmp_kallsyms2.o is linked into the final vmlinux.
# o Verify that the System.map from vmlinux matches the map from
......@@ -605,8 +631,6 @@ LDFLAGS_vmlinux += -T arch/$(ARCH)/kernel/vmlinux.lds
# temporary bypass to allow the kernel to be built while the
# maintainers work out what went wrong with kallsyms.
ifdef CONFIG_KALLSYMS
ifdef CONFIG_KALLSYMS_EXTRA_PASS
last_kallsyms := 3
else
......@@ -615,16 +639,28 @@ endif
kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
define rule_verify_kallsyms
define verify_kallsyms
$(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \
$(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map
$(Q)cmp -s System.map .tmp_System.map || \
(echo Inconsistent kallsyms data, try setting CONFIG_KALLSYMS_EXTRA_PASS ; rm .tmp_kallsyms* ; false)
(echo Inconsistent kallsyms data; \
echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
rm .tmp_kallsyms* ; /bin/false )
endef
# Update vmlinux version before link
cmd_ksym_ld = $(cmd_vmlinux__)
define rule_ksym_ld
$(call cmd,vmlinux_version)
$(call cmd,vmlinux__)
$(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd
endef
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
$(call if_changed_dep,as_o_S)
......@@ -632,43 +668,39 @@ cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) $(foreach x,$(CONFIG_KALLSYMS_ALL),--al
.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
$(call cmd,kallsyms)
.tmp_vmlinux1: $(vmlinux-objs) arch/$(ARCH)/kernel/vmlinux.lds FORCE
$(call if_changed_rule,vmlinux__)
# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
$(call if_changed_rule,ksym_ld)
.tmp_vmlinux2: $(vmlinux-objs) .tmp_kallsyms1.o arch/$(ARCH)/kernel/vmlinux.lds FORCE
$(call if_changed_rule,vmlinux__)
.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
$(call if_changed,vmlinux__)
.tmp_vmlinux3: $(vmlinux-objs) .tmp_kallsyms2.o arch/$(ARCH)/kernel/vmlinux.lds FORCE
$(call if_changed_rule,vmlinux__)
.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
$(call if_changed,vmlinux__)
# Needs to visit scripts/ before $(KALLSYMS) can be used.
$(KALLSYMS): scripts ;
endif
endif # ifdef CONFIG_KALLSYMS
# Finally the vmlinux rule
# This rule is also used to generate System.map
# and to verify that the content of kallsyms are consistent
# vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) built-in.o $(kallsyms.o) FORCE
$(call if_changed_rule,vmlinux__)
define rule_vmlinux
$(rule_vmlinux__);
$(Q)$(if $($(quiet)cmd_sysmap), \
echo ' $($(quiet)cmd_sysmap) System.map' &&) \
$(cmd_sysmap) $@ System.map; \
if [ $$? -ne 0 ]; then \
rm -f $@; \
/bin/false; \
fi;
$(rule_verify_kallsyms)
endef
# Link $(vmlinux-main) to speed up rest of build phase. No need to
# relink this part too many times.
# Use start/end-group to make sure to resolve all possible symbols
quiet_rule_vmlinux_partial = LD $@
cmd_vmlinux_partial = $(LD) $(LDFLAGS) $(LDFLAGS_$(*F)) -r \
--start-group $(filter-out FORCE, $^) \
--end-group -o $@
vmlinux: $(vmlinux-objs) $(kallsyms.o) arch/$(ARCH)/kernel/vmlinux.lds FORCE
$(call if_changed_rule,vmlinux)
built-in.o: $(vmlinux-main) FORCE
$(call if_changed,vmlinux_partial)
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
$(sort $(vmlinux-objs)) arch/$(ARCH)/kernel/vmlinux.lds: $(vmlinux-dirs) ;
$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
# Handle descending into subdirectories listed in $(vmlinux-dirs)
# Preset locale variables to speed up the build process. Limit locale
......@@ -1188,13 +1220,22 @@ ifneq ($(cmd_files),)
include $(cmd_files)
endif
# Execute command and generate cmd file
if_changed = $(if $(strip $? \
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(cmd_$(1)); \
echo 'cmd_$@ := $(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).cmd)
# execute the command and also postprocess generated .d dependencies
# file
if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
$(Q)set -e; \
$(if $($(quiet)cmd_$(1)),echo ' $(subst ','\'',$($(quiet)cmd_$(1)))';) \
$(cmd_$(1)); \
scripts/basic/fixdep $(depfile) $@ '$(subst $$,$$$$,$(subst ','\'',$(cmd_$(1))))' > $(@D)/.$(@F).tmp; \
......@@ -1208,7 +1249,7 @@ if_changed_dep = $(if $(strip $? $(filter-out FORCE $(wildcard $^),$^)\
if_changed_rule = $(if $(strip $? \
$(filter-out $(cmd_$(1)),$(cmd_$(@F)))\
$(filter-out $(cmd_$(@F)),$(cmd_$(1)))),\
@$(rule_$(1)))
$(Q)$(rule_$(1)))
# If quiet is set, only print short version of command
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment