blob: 055019a5a5f0d7f14a67c365123d725228757fc6 [file] [log] [blame]
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Elliot Berman <eberman@codeaurora.org>
Date: Wed, 7 Apr 2021 08:03:11 -0700
Subject: NOUPSTREAM: ANDROID: Kbuild: Add support for KBUILD_MIXED_TREE
When KBUILD_MIXED_TREE points to the output folder of another kernel's
build output, Kbuild can compile a complete kernel tree's modules
against that other kernel tree's vmlinux. This is useful when two
kernel trees exist: a "Generic Kernel Image" tree and a "device kernel"
tree. Both trees are complete kernel source trees, and the "Generic
Kernel Image" should provide the kernel Image and device kernel tree
provides device driver modules.
To accomplish this, references to vmlinux.symvers in the device kernel
should point to the generic kernel's vmlinux.symvers and the device
kernel should skip compilation of built-in files.
[CPNOTE: 03/06/21] Lee: Not suitable for Mainline
Bug: 178469391
Change-Id: I614f3e87519236c4e2c5da74937cb0ecd98a278a
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
---
Makefile | 30 +++++++++++++++++++++++++-----
arch/arm64/Makefile | 3 +++
arch/x86/Makefile | 3 +++
scripts/Makefile.modfinal | 14 ++++++++------
scripts/Makefile.modpost | 8 +++++---
scripts/depmod.sh | 9 +++++----
6 files changed, 49 insertions(+), 18 deletions(-)
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -136,6 +136,20 @@ endif
export KBUILD_EXTMOD
+# ANDROID: set up mixed-build support. mixed-build allows device kernel modules
+# to be compiled against a GKI kernel. This approach still uses the headers and
+# Kbuild from device kernel, so care must be taken to ensure that those headers match.
+ifdef KBUILD_MIXED_TREE
+# Need vmlinux.symvers for modpost and System.map for depmod, check whether they exist in KBUILD_MIXED_TREE
+required_mixed_files=vmlinux.symvers System.map
+$(if $(filter-out $(words $(required_mixed_files)), \
+ $(words $(wildcard $(add-prefix $(KBUILD_MIXED_TREE)/,$(required_mixed_files))))),,\
+ $(error KBUILD_MIXED_TREE=$(KBUILD_MIXED_TREE) doesn't contain $(required_mixed_files)))
+endif
+
+mixed-build-prefix = $(if $(KBUILD_MIXED_TREE),$(KBUILD_MIXED_TREE)/)
+export KBUILD_MIXED_TREE
+
# Kbuild will save output files in the current working directory.
# This does not need to match to the root of the kernel source tree.
#
@@ -671,11 +685,13 @@ drivers-y += virt/
libs-y := lib/
endif # KBUILD_EXTMOD
+ifndef KBUILD_MIXED_TREE
# The all: target is the default when no target is given on the
# command line.
# This allow a user to issue only 'make' to build a kernel including modules
# Defaults to vmlinux, but the arch makefile usually adds further targets
all: vmlinux
+endif
CFLAGS_GCOV := -fprofile-arcs -ftest-coverage
ifdef CONFIG_CC_IS_GCC
@@ -1198,8 +1214,10 @@ cmd_link-vmlinux = \
$(CONFIG_SHELL) $< "$(LD)" "$(KBUILD_LDFLAGS)" "$(LDFLAGS_vmlinux)"; \
$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true)
+ifndef KBUILD_MIXED_TREE
vmlinux: scripts/link-vmlinux.sh autoksyms_recursive $(vmlinux-deps) FORCE
+$(call if_changed_dep,link-vmlinux)
+endif
targets := vmlinux
@@ -1450,7 +1468,9 @@ endif
# using awk while concatenating to the final file.
PHONY += modules
-modules: $(if $(KBUILD_BUILTIN),vmlinux) modules_check modules_prepare
+# if KBUILD_BUILTIN && !KBUILD_MIXED_TREE, depend on vmlinux
+modules: $(if $(KBUILD_BUILTIN), $(if $(KBUILD_MIXED_TREE),,vmlinux))
+modules: modules_check modules_prepare
cmd_modules_order = $(AWK) '!x[$$0]++' $(real-prereqs) > $@
@@ -1495,8 +1515,8 @@ __modinst_pre:
ln -s $(CURDIR) $(MODLIB)/build ; \
fi
@sed 's:^:kernel/:' modules.order > $(MODLIB)/modules.order
- @cp -f modules.builtin $(MODLIB)/
- @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
+ @cp -f $(mixed-build-prefix)modules.builtin $(MODLIB)/
+ @cp -f $(or $(mixed-build-prefix),$(objtree)/)modules.builtin.modinfo $(MODLIB)/
endif # CONFIG_MODULES
@@ -1783,7 +1803,7 @@ modules_check: $(MODORDER)
quiet_cmd_depmod = DEPMOD $(MODLIB)
cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
- $(KERNELRELEASE)
+ $(KERNELRELEASE) $(mixed-build-prefix)
modules_install:
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
@@ -1862,7 +1882,7 @@ descend: $(build-dirs)
$(build-dirs): prepare
$(Q)$(MAKE) $(build)=$@ \
single-build=$(if $(filter-out $@/, $(filter $@/%, $(KBUILD_SINGLE_TARGETS))),1) \
- need-builtin=1 need-modorder=1
+ $(if $(KBUILD_MIXED_TREE),,need-builtin=1) need-modorder=1
clean-dirs := $(addprefix _clean_, $(clean-dirs))
PHONY += $(clean-dirs) clean
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -148,7 +148,10 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
boot := arch/arm64/boot
KBUILD_IMAGE := $(boot)/Image.gz
+# Don't compile Image in mixed build with "all" target
+ifndef KBUILD_MIXED_TREE
all: Image.gz
+endif
Image: vmlinux
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -240,8 +240,11 @@ BOOT_TARGETS = bzdisk fdimage fdimage144 fdimage288 hdimage isoimage
PHONY += bzImage $(BOOT_TARGETS)
+# Don't compile Image in mixed build with "all" target
+ifndef KBUILD_MIXED_TREE
# Default kernel to build
all: bzImage
+endif
# KBUILD_IMAGE specify target image being built
KBUILD_IMAGE := $(boot)/bzImage
diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal
--- a/scripts/Makefile.modfinal
+++ b/scripts/Makefile.modfinal
@@ -12,6 +12,8 @@ include $(srctree)/scripts/Kbuild.include
# for c_flags and mod-prelink-ext
include $(srctree)/scripts/Makefile.lib
+mixed-build-prefix = $(if $(KBUILD_MIXED_TREE),$(KBUILD_MIXED_TREE)/)
+
# find all modules listed in modules.order
modules := $(sort $(shell cat $(MODORDER)))
@@ -39,11 +41,11 @@ quiet_cmd_ld_ko_o = LD [M] $@
quiet_cmd_btf_ko = BTF [M] $@
cmd_btf_ko = \
- if [ -f vmlinux ]; then \
- LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
- $(RESOLVE_BTFIDS) -b vmlinux $@; \
+ if [ -f $(mixed-build-prefix)vmlinux ]; then \
+ LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base $(mixed-build-prefix)vmlinux $@; \
+ $(RESOLVE_BTFIDS) -b $(mixed-build-prefix)vmlinux $@; \
else \
- printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
+ printf "Skipping BTF generation for %s due to unavailability of $(mixed-build-prefix)vmlinux\n" $@ 1>&2; \
fi;
# Same as newer-prereqs, but allows to exclude specified extra dependencies
@@ -56,8 +58,8 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
# Re-generate module BTFs if either module's .ko or vmlinux changed
-$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
- +$(call if_changed_except,ld_ko_o,vmlinux)
+$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),$(mixed-build-prefix)vmlinux) FORCE
+ +$(call if_changed_except,ld_ko_o,$(mixed-build-prefix)vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
endif
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -44,6 +44,8 @@ include $(srctree)/scripts/Kbuild.include
# for mod-prelink-ext
include $(srctree)/scripts/Makefile.lib
+mixed-build-prefix = $(if $(KBUILD_MIXED_TREE),$(KBUILD_MIXED_TREE)/)
+
MODPOST = scripts/mod/modpost \
$(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
@@ -64,17 +66,17 @@ else
ifeq ($(KBUILD_EXTMOD),)
-input-symdump := vmlinux.symvers
+input-symdump := $(mixed-build-prefix)vmlinux.symvers
output-symdump := modules-only.symvers
module_srcpath := $(srctree)
quiet_cmd_cat = GEN $@
cmd_cat = cat $(real-prereqs) > $@
-ifneq ($(wildcard vmlinux.symvers),)
+ifneq ($(wildcard $(mixed-build-prefix)vmlinux.symvers),)
__modpost: Module.symvers
-Module.symvers: vmlinux.symvers modules-only.symvers FORCE
+Module.symvers: $(mixed-build-prefix)vmlinux.symvers modules-only.symvers FORCE
$(call if_changed,cat)
targets += Module.symvers
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -3,14 +3,15 @@
#
# A depmod wrapper used by the toplevel Makefile
-if test $# -ne 2; then
- echo "Usage: $0 /sbin/depmod <kernelrelease>" >&2
+if test $# -ne 2 -a $# -ne 3; then
+ echo "Usage: $0 /sbin/depmod <kernelrelease> [System.map folder]" >&2
exit 1
fi
DEPMOD=$1
KERNELRELEASE=$2
+KBUILD_MIXED_TREE=$3
-if ! test -r System.map ; then
+if ! test -r ${KBUILD_MIXED_TREE}System.map ; then
echo "Warning: modules_install: missing 'System.map' file. Skipping depmod." >&2
exit 0
fi
@@ -41,7 +42,7 @@ if $depmod_hack_needed; then
KERNELRELEASE=99.98.$KERNELRELEASE
fi
-set -- -ae -F System.map
+set -- -ae -F ${KBUILD_MIXED_TREE}System.map
if test -n "$INSTALL_MOD_PATH"; then
set -- "$@" -b "$INSTALL_MOD_PATH"
fi