Makefile: Build Linux modules

Some Linux kselftests require a kernel module to exercise the
functionality. Add build rules for building kernel modules and
installing them into a folder that will be later shared with the
QEMU VM. Changes are tracked and a stamp file is updated accordingly.

Bug: 193407077
Test: make linux_modules
Change-Id: Ia46b953c669b3f754dcb6a3cb7402b487efd0403
diff --git a/Makefile b/Makefile
index 88096b0..6a65868 100644
--- a/Makefile
+++ b/Makefile
@@ -54,9 +54,14 @@
 VERBOSE ?= 0
 ARCH = arm64
 
-DEFAULT_KERNEL_IMAGE := $(LINUX_OUT)/arch/arm64/boot/Image
-# KERNEL_IMAGE can be set to use own custom kernel image.
-KERNEL_IMAGE ?= $(DEFAULT_KERNEL_IMAGE)
+LINUX_OUT_IMAGE := $(LINUX_OUT)/arch/arm64/boot/Image
+LINUX_OUT_MODULES := $(LINUX_OUT)/modules_install
+LINUX_OUT_MODULES_DEP := $(LINUX_OUT)/modules_install.stamp
+
+# KERNEL_IMAGE/MODULES can be set to use own custom kernel image.
+KERNEL_IMAGE ?= $(LINUX_OUT_IMAGE)
+KERNEL_MODULES ?= $(LINUX_OUT_MODULES)
+KERNEL_MODULES_DEP ?= $(LINUX_OUT_MODULES_DEP)
 
 ##
 ## Toolchain options and variables
@@ -232,10 +237,20 @@
 	$(call copy_to_dist, $(LINUX_DIST_FILES), $(LINUX_DIST))
 
 .PHONY: linux_image
-linux_image $(DEFAULT_KERNEL_IMAGE): $(LINUX_CONFIG)
+linux_image $(LINUX_OUT_IMAGE): $(LINUX_CONFIG)
 	+ $(LINUX_MAKE) Image.gz
 	$(call copy_to_dist, $(LINUX_DIST_FILES), $(LINUX_DIST))
 
+.PHONY: linux_modules
+linux_modules $(LINUX_OUT_MODULES_DEP): $(LINUX_OUT_IMAGE)
+	@ rm -rf $(LINUX_OUT_MODULES)
+	+ $(LINUX_MAKE) modules
+	+ $(LINUX_MAKE) INSTALL_MOD_PATH=$(LINUX_OUT_MODULES) modules_install
+	@ find $(LINUX_OUT_MODULES) -type f | sort | \
+		xargs sha1sum > $(LINUX_OUT_MODULES_DEP).tmp
+	@ cmp $(LINUX_OUT_MODULES_DEP).tmp $(LINUX_OUT_MODULES_DEP) || \
+		mv $(LINUX_OUT_MODULES_DEP).tmp $(LINUX_OUT_MODULES_DEP)
+
 .PHONY: linux_clean
 linux_clean:
 	+ $(LINUX_MAKE) mrproper
@@ -316,7 +331,9 @@
 		-M $(call hyphensuffix,$@) \
 		-k "$(KERNEL_IMAGE)" \
 		$(RUN_TEST_ARGS) "$(RUN_TEST_HOST_SH)" \
-		$(if $(RUN_TEST_QEMU_ARGS),-- ,)$(RUN_TEST_QEMU_ARGS)
+		-- \
+		-D modules:${KERNEL_MODULES}/lib/modules \
+		$(RUN_TEST_QEMU_ARGS)
 
 ifeq ($(VERBOSE),1)
 RUN_TEST_ARGS += -v
@@ -411,7 +428,7 @@
 $(CROSVM_HELLOWORLD_TESTS): RUN_TEST_TIMEOUT := 300s
 
 .PHONY test: $(TESTS)
-$(TESTS): $(KERNEL_IMAGE)
+$(TESTS): $(KERNEL_IMAGE) $(KERNEL_MODULES_DEP)
 	@ $(RUN_TEST)
 .PHONY test-list: $(TEST_LISTS)
 $(TEST_LISTS):