core & tools: system_dlkm: add dynamic partition

Converts existing static partition support to a
dynamic partition.

Bug: 200082547
Test: TH
Signed-off-by: Ramji Jiyani <ramjiyani@google.com>
Change-Id: Ifd6d0c2a04e947b16f8b241e99cca594a1d315ae
diff --git a/core/Makefile b/core/Makefile
index 758e9c5..530e32d 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1181,48 +1181,6 @@
 endif # BUILDING_INIT_BOOT_IMAGE is not true
 
 # -----------------------------------------------------------------
-#  system dlkm image
-ifeq ($(BUILDING_SYSTEM_DLKM_IMAGE),true)
-
-INSTALLED_SYSTEM_DLKM_IMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
-
-ifeq ($(BOARD_AVB_ENABLE),true)
-$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(TARGET_SYSTEM_DLKM_SRC) $(MKEROFS) $(AVBTOOL)
-	$(call pretty,"Target system_dlkm image: $@")
-	rsync -rupE $(TARGET_SYSTEM_DLKM_SRC)/ $(TARGET_SYSTEM_DLKM_OUT)
-	$(MKEROFS) "-zlz4hc" $@ $(TARGET_SYSTEM_DLKM_OUT)
-	$(call assert-max-image-size,$@,$(BOARD_SYSTEM_DLKM_PARTITION_SIZE))
-	$(AVBTOOL) add_hash_footer \
-	    --partition_name system_dlkm \
-	    --partition_size $(BOARD_SYSTEM_DLKM_PARTITION_SIZE) \
-	    --image $@
-else
-$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(TARGET_SYSTEM_DLKM_SRC) $(MKEROFS)
-	$(call pretty,"Target system_dlkm image: $@")
-	rsync -rupE $(TARGET_SYSTEM_DLKM_SRC)/ $(TARGET_SYSTEM_DLKM_OUT)
-	$(MKEROFS) "-zlz4hc" $@ $(TARGET_SYSTEM_DLKM_OUT)
-	$(call assert-max-image-size,$@,$(BOARD_SYSTEM_DLKM_PARTITION_SIZE))
-endif # BOARD_AVB_ENABLE
-
-else # BUILDING_SYSTEM_DLKM_IMAGE is not true
-
-ifdef BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
-
-INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE := $(BOARD_PREBUILT_SYSTEM_DLKM_IMAGE)
-INSTALLED_SYSTEM_DLKM_IMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
-$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET): $(INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE)
-	$(call pretty,"Using prebuilt from: $(INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE)")
-	cp $(INTERNAL_PREBUILT_SYSTEM_DLKM_IMAGE) $@
-
-else # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE not defined
-
-INSTALLED_SYSTEM_DLKM_IMAGE_TARGET :=
-
-endif # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
-
-endif # BUILDING_SYSTEM_DLKM_IMAGE is not true
-
-# -----------------------------------------------------------------
 # vendor boot image
 ifeq ($(BUILDING_VENDOR_BOOT_IMAGE),true)
 
@@ -1475,6 +1433,11 @@
 target_odm_dlkm_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_ODM_DLKM.xml.gz
 installed_odm_dlkm_notice_xml_gz := $(TARGET_OUT_ODM_DLKM)/etc/NOTICE.xml.gz
 
+target_system_dlkm_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE_SYSTEM_DLKM.txt
+target_system_dlkm_notice_file_xml := $(TARGET_OUT_INTERMEDIATES)/NOTICE_SYSTEM_DLKM.xml
+target_system_dlkm_notice_file_xml_gz := $(TARGET_OUT_INTERMEDIATES)/NOTICE_SYSTEM_DLKM.xml.gz
+installed_system_dlkm_notice_xml_gz := $(TARGET_OUT_SYSTEM_DLKM)/etc/NOTICE.xml.gz
+
 # Notice files are copied to TARGET_OUT_NOTICE_FILES as a side-effect of their module
 # being built. A notice xml file must depend on all modules that could potentially
 # install a license file relevant to it.
@@ -1495,13 +1458,15 @@
 license_modules_odm := $(filter $(TARGET_OUT_ODM)/%,$(license_modules))
 license_modules_vendor_dlkm := $(filter $(TARGET_OUT_VENDOR_DLKM)/%,$(license_modules))
 license_modules_odm_dlkm := $(filter $(TARGET_OUT_ODM_DLKM)/%,$(license_modules))
+license_modules_odm_dlkm := $(filter $(TARGET_OUT_SYSTEM_DLKM)/%,$(license_modules))
 license_modules_agg := $(license_modules_system) \
                        $(license_modules_vendor) \
                        $(license_modules_product) \
                        $(license_modules_system_ext) \
                        $(license_modules_odm) \
                        $(license_modules_vendor_dlkm) \
-                       $(license_modules_odm_dlkm)
+                       $(license_modules_odm_dlkm) \
+                       $(license_modules_system_dlkm)
 # targets used for debug symbols only and do not get copied to the device
 license_modules_symbols_only := $(filter $(PRODUCT_OUT)/apex/%,$(license_modules))
 
@@ -1593,6 +1558,13 @@
 	        $(TARGET_OUT_NOTICE_FILES), \
 	        $(license_modules_odm_dlkm), \
 	        $(exclude_target_dirs)))
+$(eval $(call combine-notice-files, xml_system_dlkm, \
+	        $(target_system_dlkm_notice_file_txt), \
+	        $(target_system_dlkm_notice_file_xml), \
+	        "Notices for files contained in the system_dlkm filesystem image in this directory:", \
+	        $(TARGET_OUT_NOTICE_FILES), \
+	        $(license_modules_system_dlkm), \
+	        $(exclude_target_dirs)))
 
 $(target_notice_file_xml_gz): $(target_notice_file_xml) | $(MINIGZIP)
 	$(hide) $(MINIGZIP) -9 < $< > $@
@@ -1608,6 +1580,8 @@
 	$(hide) $(MINIGZIP) -9 < $< > $@
 $(target_odm_dlkm_notice_file_xml_gz): $(target_odm_dlkm_notice_file_xml) | $(MINIGZIP)
 	$(hide) $(MINIGZIP) -9 < $< > $@
+$(target_system_dlkm_notice_file_xml_gz): $(target_system_dlkm_notice_file_xml) | $(MINIGZIP)
+	$(hide) $(MINIGZIP) -9 < $< > $@
 $(installed_notice_html_or_xml_gz): $(target_notice_file_xml_gz)
 	$(copy-file-to-target)
 $(installed_vendor_notice_xml_gz): $(target_vendor_notice_file_xml_gz)
@@ -1622,6 +1596,8 @@
 	$(copy-file-to-target)
 $(installed_odm_dlkm_notice_xml_gz): $(target_odm_dlkm_notice_file_xml_gz)
 	$(copy-file-to-target)
+$(installed_system_dlkm_notice_xml_gz): $(target_system_dlkm_notice_file_xml_gz)
+	$(copy-file-to-target)
 
 $(call declare-0p-target,$(target_notice_file_xml))
 $(call declare-0p-target,$(target_notice_file_xml_gz))
@@ -1637,6 +1613,8 @@
 $(call declare-0p-target,$(target_vendor_dlkm_notice_file_xml_gz))
 $(call declare-0p-target,$(target_odm_dlkm_notice_file_xml))
 $(call declare-0p-target,$(target_odm_dlkm_notice_file_xml_gz))
+$(call declare-0p-target,$(target_system_dlkm_notice_file_xml))
+$(call declare-0p-target,$(target_system_dlkm_notice_file_xml_gz))
 $(call declare-0p-target,$(installed_notice_html_or_xml_gz))
 $(call declare-0p-target,$(installed_vendor_notice_xml_gz))
 $(call declare-0p-target,$(installed_product_notice_xml_gz))
@@ -1644,6 +1622,7 @@
 $(call declare-0p-target,$(installed_odm_notice_xml_gz))
 $(call declare-0p-target,$(installed_vendor_dlkm_notice_xml_gz))
 $(call declare-0p-target,$(installed_odm_dlkm_notice_xml_gz))
+$(call declare-0p-target,$(installed_sysetm_dlkm_notice_xml_gz))
 
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_vendor_notice_xml_gz)
@@ -1652,6 +1631,7 @@
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_odm_notice_xml_gz)
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_vendor_dlkm_notice_xml_gz)
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_odm_dlkm_notice_xml_gz)
+ALL_DEFAULT_INSTALLED_MODULES += $(installed_system_dlkm_notice_xml_gz)
 endif # PRODUCT_NOTICE_SPLIT
 
 ALL_DEFAULT_INSTALLED_MODULES += $(installed_notice_html_or_xml_gz)
@@ -1729,6 +1709,7 @@
     $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE) \
     $(BOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE) \
     $(BOARD_ODM_DLKMIMAGE_FILE_SYSTEM_TYPE) \
+    $(BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE) \
   ,erofs),)
 INTERNAL_USERIMAGES_DEPS += $(MKEROFSUSERIMG)
 BOARD_EROFS_COMPRESSOR ?= "lz4hc,9"
@@ -1742,6 +1723,7 @@
     $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE) \
     $(BOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE) \
     $(BOARD_ODM_DLKMIMAGE_FILE_SYSTEM_TYPE) \
+    $(BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE) \
   ,squashfs),)
 INTERNAL_USERIMAGES_DEPS += $(MKSQUASHFSUSERIMG)
 endif
@@ -1813,7 +1795,7 @@
 endef
 
 # $(1): the path of the output dictionary file
-# $(2): a subset of "system vendor cache userdata product system_ext oem odm vendor_dlkm odm_dlkm"
+# $(2): a subset of "system vendor cache userdata product system_ext oem odm vendor_dlkm odm_dlkm system_dlkm"
 # $(3): additional "key=value" pairs to append to the dictionary file.
 define generate-image-prop-dictionary
 $(if $(filter $(2),system),\
@@ -1857,6 +1839,9 @@
 $(if $(filter $(2),odm_dlkm),\
     $(call add-common-ro-flags-to-image-props,odm_dlkm,$(1))
 )
+$(if $(filter $(2),system_dlkm),\
+    $(call add-common-ro-flags-to-image-props,system_dlkm,$(1))
+)
 $(if $(filter $(2),oem),\
     $(if $(BOARD_OEMIMAGE_PARTITION_SIZE),$(hide) echo "oem_size=$(BOARD_OEMIMAGE_PARTITION_SIZE)" >> $(1))
     $(if $(BOARD_OEMIMAGE_JOURNAL_SIZE),$(hide) echo "oem_journal_size=$(BOARD_OEMIMAGE_JOURNAL_SIZE)" >> $(1))
@@ -1889,6 +1874,7 @@
 $(if $(PRODUCT_SYSTEM_EXT_VERITY_PARTITION),$(hide) echo "system_ext_verity_block_device=$(PRODUCT_SYSTEM_EXT_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCT_VENDOR_DLKM_VERITY_PARTITION),$(hide) echo "vendor_dlkm_verity_block_device=$(PRODUCT_VENDOR_DLKM_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCT_ODM_DLKM_VERITY_PARTITION),$(hide) echo "odm_dlkm_verity_block_device=$(PRODUCT_ODM_DLKM_VERITY_PARTITION)" >> $(1))
+$(if $(PRODUCT_SYSTEM_DLKM_VERITY_PARTITION),$(hide) echo "system_dlkm_verity_block_device=$(PRODUCT_SYSTEM_DLKM_VERITY_PARTITION)" >> $(1))
 $(if $(PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot=$(PRODUCT_SUPPORTS_VBOOT)" >> $(1))
 $(if $(PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_key=$(PRODUCT_VBOOT_SIGNING_KEY)" >> $(1))
 $(if $(PRODUCT_SUPPORTS_VBOOT),$(hide) echo "vboot_subkey=$(PRODUCT_VBOOT_SIGNING_SUBKEY)" >> $(1))
@@ -1953,6 +1939,14 @@
         $(hide) echo "avb_odm_dlkm_key_path=$(BOARD_AVB_ODM_DLKM_KEY_PATH)" >> $(1)
         $(hide) echo "avb_odm_dlkm_algorithm=$(BOARD_AVB_ODM_DLKM_ALGORITHM)" >> $(1)
         $(hide) echo "avb_odm_dlkm_rollback_index_location=$(BOARD_AVB_ODM_DLKM_ROLLBACK_INDEX_LOCATION)" >> $(1)))
+$(if $(BOARD_AVB_ENABLE),$(hide) echo "avb_system_dlkm_hashtree_enable=$(BOARD_AVB_ENABLE)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+    $(hide) echo "avb_system_dlkm_add_hashtree_footer_args=$(BOARD_AVB_SYSTEM_DLKM_ADD_HASHTREE_FOOTER_ARGS)" >> $(1))
+$(if $(BOARD_AVB_ENABLE),\
+    $(if $(BOARD_AVB_SYSTEM_DLKM_KEY_PATH),\
+        $(hide) echo "avb_system_dlkm_key_path=$(BOARD_AVB_SYSTEM_DLKM_KEY_PATH)" >> $(1)
+        $(hide) echo "avb_system_dlkm_algorithm=$(BOARD_AVB_SYSTEM_DLKM_ALGORITHM)" >> $(1)
+        $(hide) echo "avb_system_dlkm_rollback_index_location=$(BOARD_SYSTEM_SYSTEM_DLKM_ROLLBACK_INDEX_LOCATION)" >> $(1)))
 $(if $(filter true,$(BOARD_USES_RECOVERY_AS_BOOT)),\
     $(hide) echo "recovery_as_boot=true" >> $(1))
 $(if $(filter true,$(BOARD_BUILD_SYSTEM_ROOT_IMAGE)),\
@@ -1996,6 +1990,9 @@
 ifdef BUILDING_ODM_DLKM_IMAGE
   PROP_DICTIONARY_IMAGES += odm_dlkm
 endif
+ifdef BUILDING_SYSTEM_DLKM_IMAGE
+  PROP_DICTIONARY_IMAGES += system_dlkm
+endif
 define generate-userimage-prop-dictionary
   $(call generate-image-prop-dictionary,$(1),$(PROP_DICTIONARY_IMAGES),$(2))
 endef
@@ -2923,7 +2920,7 @@
 # On devices with a system_dlkm partition,
 # - /system/lib/modules is a symlink to a directory that stores system DLKMs.
 # - The system_dlkm partition is mounted at /system_dlkm at runtime.
-ifdef BOARD_USES_SYSTEM_DLKM_PARTITION
+ifdef BOARD_USES_SYSTEM_DLKMIMAGE
   INTERNAL_SYSTEMIMAGE_FILES += $(call create-partition-compat-symlink,$(TARGET_OUT)/lib/modules,/system_dlkm/lib/modules,system_dlkm.img)
 endif
 
@@ -3618,6 +3615,60 @@
 $(eval $(call copy-one-file,$(BOARD_PREBUILT_ODM_DLKMIMAGE),$(INSTALLED_ODM_DLKMIMAGE_TARGET)))
 endif
 
+# -----------------------------------------------------------------
+# system_dlkm partition image
+
+ifdef BUILDING_SYSTEM_DLKM_IMAGE
+
+INTERNAL_SYSTEM_DLKMIMAGE_FILES := \
+    $(filter $(TARGET_OUT_SYSTEM_DLKM)/%,\
+      $(ALL_DEFAULT_INSTALLED_MODULES))
+
+INSTALLED_FILES_FILE_SYSTEM_DLKM := $(PRODUCT_OUT)/installed-files-system_dlkm.txt
+INSTALLED_FILES_JSON_SYSTEM_DLKM := $(INSTALLED_FILES_FILE_SYSTEM_DLKM:.txt=.json)
+$(INSTALLED_FILES_FILE_SYSTEM_DLKM): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_SYSTEM_DLKM)
+$(INSTALLED_FILES_FILE_SYSTEM_DLKM): $(INTERNAL_SYSTEM_DLKMIMAGE_FILES) $(FILESLIST) $(FILESLIST_UTIL)
+	@echo Installed file list: $@
+	mkdir -p $(dir $@)
+	if [ -d "$(BOARD_SYSTEM_DLKM_SRC)" ]; then rsync -rupE $(BOARD_SYSTEM_DLKM_SRC)/ $(TARGET_OUT_SYSTEM_DLKM); fi
+	rm -f $@
+	$(FILESLIST) $(TARGET_OUT_SYSTEM_DLKM) > $(@:.txt=.json)
+	$(FILESLIST_UTIL) -c $(@:.txt=.json) > $@
+
+system_dlkmimage_intermediates := \
+    $(call intermediates-dir-for,PACKAGING,system_dlkm)
+BUILT_SYSTEM_DLKMIMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
+define build-system_dlkmimage-target
+  $(call pretty,"Target system_dlkm fs image: $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)")
+  @mkdir -p $(TARGET_OUT_SYSTEM_DLKM)
+  @mkdir -p $(system_dlkmimage_intermediates) && rm -rf $(system_dlkmimage_intermediates)/system_dlkm_image_info.txt
+  $(call generate-image-prop-dictionary, $(system_dlkmimage_intermediates)/system_dlkm_image_info.txt, \
+	  system_dlkm, skip_fsck=true)
+  PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \
+      $(BUILD_IMAGE) \
+          $(TARGET_OUT_SYSTEM_DLKM) $(system_dlkmimage_intermediates)/system_dlkm_image_info.txt \
+          $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) $(TARGET_OUT)
+  $(call assert-max-image-size,$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET),$(BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE))
+endef
+
+# We just build this directly to the install location.
+INSTALLED_SYSTEM_DLKMIMAGE_TARGET := $(BUILT_SYSTEM_DLKMIMAGE_TARGET)
+$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET): \
+    $(INTERNAL_USERIMAGES_DEPS) \
+    $(INTERNAL_SYSTEM_DLKMIMAGE_FILES) \
+    $(INSTALLED_FILES_FILE_SYSTEM_DLKM)
+	$(build-system_dlkmimage-target)
+
+.PHONY: system_dlkmimage-nodeps sdnod
+system_dlkmimage-nodeps sdnod: | $(INTERNAL_USERIMAGES_DEPS)
+	$(build-system_dlkmimage-target)
+
+sync: $(INTERNAL_SYSTEM_DLKMIMAGE_FILES)
+
+else ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+INSTALLED_SYSTEM_DLKMIMAGE_TARGET := $(PRODUCT_OUT)/system_dlkm.img
+$(eval $(call copy-one-file,$(BOARD_PREBUILT_SYSTEM_DLKMIMAGE),$(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)))
+endif
 
 # -----------------------------------------------------------------
 # dtbo image
@@ -3673,8 +3724,7 @@
 $(strip $(foreach item,$(1),\
   $(if $(filter $(item),system_other),$(INSTALLED_SYSTEMOTHERIMAGE_TARGET),\
     $(if $(filter $(item),init_boot),$(INSTALLED_INIT_BOOT_IMAGE_TARGET),\
-      $(if $(filter $(item),system_dlkm),$(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET),\
-        $(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET))))))
+      $(INSTALLED_$(call to-upper,$(item))IMAGE_TARGET)))))
 endef
 
 # -----------------------------------------------------------------
@@ -3817,6 +3867,10 @@
     --prop com.android.build.odm_dlkm.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
     --prop com.android.build.odm_dlkm.os_version:$(PLATFORM_VERSION_LAST_STABLE)
 
+BOARD_AVB_SYSTEM_DLKM_ADD_HASHTREE_FOOTER_ARGS += \
+    --prop com.android.build.system_dlkm.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE) \
+    --prop com.android.build.system_dlkm.os_version:$(PLATFORM_VERSION_LAST_STABLE)
+
 BOARD_AVB_DTBO_ADD_HASH_FOOTER_ARGS += \
     --prop com.android.build.dtbo.fingerprint:$(BUILD_FINGERPRINT_FROM_FILE)
 
@@ -3859,6 +3913,11 @@
     --prop com.android.build.odm_dlkm.security_patch:$(ODM_DLKM_SECURITY_PATCH)
 endif
 
+ifdef SYSTEM_DLKM_SECURITY_PATCH
+BOARD_AVB_SYSTEM_DLKM_ADD_HASHTREE_FOOTER_ARGS += \
+    --prop com.android.build.system_dlkm.security_patch:$(SYSTEM_DLKM_SECURITY_PATCH)
+endif
+
 ifdef PVMFW_SECURITY_PATCH
 BOARD_AVB_PVMFW_ADD_HASH_FOOTER_ARGS += \
     --prop com.android.build.pvmfw.security_patch:$(PVMFW_SECURITY_PATCH)
@@ -3884,6 +3943,7 @@
 ODM_FOOTER_ARGS := BOARD_AVB_ODM_ADD_HASHTREE_FOOTER_ARGS
 VENDOR_DLKM_FOOTER_ARGS := BOARD_AVB_VENDOR_DLKM_ADD_HASHTREE_FOOTER_ARGS
 ODM_DLKM_FOOTER_ARGS := BOARD_AVB_ODM_DLKM_ADD_HASHTREE_FOOTER_ARGS
+SYSTEM_DLKM_FOOTER_ARGS := BOARD_AVB_SYSTEM_DLKM_ADD_HASHTREE_FOOTER_ARGS
 
 # Helper function that checks and sets required build variables for an AVB chained partition.
 # $(1): the partition to enable AVB chain, e.g., boot or system or vbmeta_system.
@@ -3992,6 +4052,10 @@
 $(eval $(call check-and-set-avb-args,odm_dlkm))
 endif
 
+ifdef INSTALLED_SYSTEM_DLKMIMAGE_TARGET
+$(eval $(call check-and-set-avb-args,system_dlkm))
+endif
+
 ifdef INSTALLED_DTBOIMAGE_TARGET
 $(eval $(call check-and-set-avb-args,dtbo))
 endif
@@ -4085,6 +4149,9 @@
   $(if $(BOARD_AVB_ODM_DLKM_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_ODM_DLKM_KEY_PATH) \
       --output $(1)/odm_dlkm.avbpubkey)
+  $(if $(BOARD_AVB_SYSTEM_DLKM_KEY_PATH),\
+    $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_SYSTEM_DLKM_KEY_PATH) \
+      --output $(1)/system_dlkm.avbpubkey)
   $(if $(BOARD_AVB_DTBO_KEY_PATH),\
     $(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_DTBO_KEY_PATH) \
       --output $(1)/dtbo.avbpubkey)
@@ -4173,6 +4240,7 @@
 	    $(INSTALLED_ODMIMAGE_TARGET) \
 	    $(INSTALLED_VENDOR_DLKMIMAGE_TARGET) \
 	    $(INSTALLED_ODM_DLKMIMAGE_TARGET) \
+	    $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) \
 	    $(INSTALLED_DTBOIMAGE_TARGET) \
 	    $(INSTALLED_PVMFWIMAGE_TARGET) \
 	    $(INSTALLED_CUSTOMIMAGES_TARGET) \
@@ -4204,11 +4272,12 @@
     $(INTERNAL_ODMIMAGE_FILES) \
     $(INTERNAL_VENDOR_DLKMIMAGE_FILES) \
     $(INTERNAL_ODM_DLKMIMAGE_FILES) \
+    $(INTERNAL_SYSTEM_DLKMIMAGE_FILES) \
 
 # -----------------------------------------------------------------
 # Check VINTF of build
 
-# Note: vendor_dlkm and odm_dlkm does not have VINTF files.
+# Note: vendor_dlkm, odm_dlkm, and system_dlkm does not have VINTF files.
 ifeq (,$(TARGET_BUILD_UNBUNDLED))
 
 intermediates := $(call intermediates-dir-for,PACKAGING,check_vintf_all)
@@ -4741,10 +4810,6 @@
 	$(hide) echo "init_boot=true" >> $@
 	$(hide) echo "init_boot_size=$(BOARD_INIT_BOOT_IMAGE_PARTITION_SIZE)" >> $@
 endif
-ifneq ($(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET),)
-	$(hide) echo "system_dlkm=true" >> $@
-	$(hide) echo "system_dlkm_size=$(BOARD_SYSTEM_DLKM_PARTITION_SIZE)" >> $@
-endif
 ifeq ($(BOARD_RAMDISK_USE_LZ4),true)
 	echo "lz4_ramdisks=true" >> $@
 endif
@@ -5045,13 +5110,17 @@
 define filter-out-missing-odm_dlkm
 $(if $(INSTALLED_ODM_DLKMIMAGE_TARGET),$(1),$(filter-out odm_dlkm,$(1)))
 endef
-# Filter out vendor,vendor_dlkm,odm,odm_dlkm from the list for AOSP targets.
+define filter-out-missing-system_dlkm
+$(if $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET),$(1),$(filter-out system_dlkm,$(1)))
+endef
+# Filter out vendor,vendor_dlkm,odm,odm_dlkm,system_dlkm from the list for AOSP targets.
 # $(1): list
 define filter-out-missing-partitions
 $(call filter-out-missing-vendor,\
   $(call filter-out-missing-vendor_dlkm,\
     $(call filter-out-missing-odm,\
-      $(call filter-out-missing-odm_dlkm,$(1)))))
+      $(call filter-out-missing-odm_dlkm,\
+        $(call filter-out-missing-system_dlkm,$(1))))))
 endef
 
 # Information related to dynamic partitions and virtual A/B. This information
@@ -5195,6 +5264,12 @@
   $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_ODM_DLKMIMAGE_TARGET)
 endif
 
+ifdef BUILDING_SYSTEM_DLKM_IMAGE
+  $(BUILT_TARGET_FILES_PACKAGE): $(INTERNAL_SYSTEM_DLKMIMAGE_FILES)
+else ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+  $(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)
+endif
+
 ifeq ($(BUILD_QEMU_IMAGES),true)
   MK_VBMETA_BOOT_KERNEL_CMDLINE_SH := device/generic/goldfish/tools/mk_vbmeta_boot_params.sh
   $(BUILT_TARGET_FILES_PACKAGE): $(MK_VBMETA_BOOT_KERNEL_CMDLINE_SH)
@@ -5229,6 +5304,7 @@
 	    $(PRODUCT_ODM_BASE_FS_PATH) \
 	    $(PRODUCT_VENDOR_DLKM_BASE_FS_PATH) \
 	    $(PRODUCT_ODM_DLKM_BASE_FS_PATH) \
+	    $(PRODUCT_SYSTEM_DLKM_BASE_FS_PATH) \
 	    $(LPMAKE) \
 	    $(SELINUX_FC) \
 	    $(INSTALLED_MISC_INFO_TARGET) \
@@ -5402,6 +5478,11 @@
 	$(hide) $(call package_files-copy-root, \
 	    $(TARGET_OUT_ODM_DLKM),$(zip_root)/ODM_DLKM)
 endif
+ifdef BUILDING_SYSTEM_DLKM_IMAGE
+	@# Contents of the system_dlkm image
+	$(hide) $(call package_files-copy-root, \
+	    $(TARGET_OUT_SYSTEM_DLKM),$(zip_root)/SYSTEM_DLKM)
+endif
 ifdef BUILDING_SYSTEM_OTHER_IMAGE
 	@# Contents of the system_other image
 	$(hide) $(call package_files-copy-root, \
@@ -5462,6 +5543,10 @@
 	$(hide) cp $(PRODUCT_ODM_DLKM_BASE_FS_PATH) \
 	  $(zip_root)/META/$(notdir $(PRODUCT_ODM_DLKM_BASE_FS_PATH))
 endif
+ifneq ($(PRODUCT_SYSTEM_DLKM_BASE_FS_PATH),)
+	$(hide) cp $(PRODUCT_SYSTEM_DLKM_BASE_FS_PATH) \
+	  $(zip_root)/META/$(notdir $(PRODUCT_SYSTEM_DLKM_BASE_FS_PATH))
+endif
 ifeq ($(TARGET_OTA_ALLOW_NON_AB),true)
 ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
 	$(hide) PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH MKBOOTIMG=$(MKBOOTIMG) \
@@ -5505,15 +5590,6 @@
 	$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
 	$(hide) cp $(INSTALLED_INIT_BOOT_IMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
 endif
-ifdef BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
-	$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
-	$(hide) cp $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES
-else # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE is not define
-ifdef INSTALLED_SYSTEM_DLKM_IMAGE_TARGET
-	$(hide) mkdir -p $(zip_root)/IMAGES
-	$(hide) cp $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET) $(zip_root)/IMAGES/
-endif # INSTALLED_SYSTEM_DLKM_IMAGE_TARGET
-endif # BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
 
 ifndef BOARD_PREBUILT_BOOTIMAGE
 ifneq (,$(strip $(INTERNAL_PREBUILT_BOOTIMAGE) $(filter true,$(BOARD_COPY_BOOT_IMAGE_TO_TARGET_FILES))))
@@ -5538,6 +5614,10 @@
 	$(hide) mkdir -p $(zip_root)/IMAGES
 	$(hide) cp $(INSTALLED_ODM_DLKMIMAGE_TARGET) $(zip_root)/IMAGES/
 endif
+ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+	$(hide) mkdir -p $(zip_root)/IMAGES
+	$(hide) cp $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) $(zip_root)/IMAGES/
+endif
 ifdef BOARD_PREBUILT_DTBOIMAGE
 	$(hide) mkdir -p $(zip_root)/PREBUILT_IMAGES
 	$(hide) cp $(INSTALLED_DTBOIMAGE_TARGET) $(zip_root)/PREBUILT_IMAGES/
@@ -5586,6 +5666,9 @@
 ifdef BUILDING_ODM_DLKM_IMAGE
 	$(hide) $(call fs_config,$(zip_root)/ODM_DLKM,odm_dlkm/) > $(zip_root)/META/odm_dlkm_filesystem_config.txt
 endif
+ifdef BUILDING_SYSTEM_DLKM_IMAGE
+	$(hide) $(call fs_config,$(zip_root)/SYSTEM_DLKM,system_dlkm/) > $(zip_root)/META/system_dlkm_filesystem_config.txt
+endif
 	@# ROOT always contains the files for the root under normal boot.
 	$(hide) $(call fs_config,$(zip_root)/ROOT,) > $(zip_root)/META/root_filesystem_config.txt
 ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
@@ -5599,9 +5682,6 @@
 	$(hide) echo "$(BOARD_KERNEL_PAGESIZE)" > $(zip_root)/INIT_BOOT/pagesize
 endif # BOARD_KERNEL_PAGESIZE
 endif # BUILDING_INIT_BOOT_IMAGE
-ifdef BUILDING_SYSTEM_DLKM_IMAGE
-	$(hide) $(call package_files-copy-root, $(TARGET_SYSTEM_DLKM_OUT),$(zip_root)/SYSTEM_DLKM)
-endif
 ifneq ($(INSTALLED_VENDOR_BOOTIMAGE_TARGET),)
 	$(call fs_config,$(zip_root)/VENDOR_BOOT/RAMDISK,) > $(zip_root)/META/vendor_boot_filesystem_config.txt
 endif
@@ -5916,7 +5996,6 @@
     $(INSTALLED_RAMDISK_TARGET) \
     $(INSTALLED_BOOTIMAGE_TARGET) \
     $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
-    $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET) \
     $(INSTALLED_USERDATAIMAGE_TARGET) \
     $(INSTALLED_VENDORIMAGE_TARGET) \
     $(INSTALLED_PRODUCTIMAGE_TARGET) \
@@ -5924,6 +6003,7 @@
     $(INSTALLED_ODMIMAGE_TARGET) \
     $(INSTALLED_VENDOR_DLKMIMAGE_TARGET) \
     $(INSTALLED_ODM_DLKMIMAGE_TARGET) \
+    $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) \
     $(updater_dep)
 endif
 $(PROGUARD_USAGE_ZIP): PRIVATE_LIST_FILE := $(call intermediates-dir-for,PACKAGING,proguard_usage.zip)/filelist
@@ -6178,6 +6258,16 @@
 droidcore-unbundled: $(INSTALLED_QEMU_ODM_DLKMIMAGE)
 endif
 
+ifdef INSTALLED_SYSTEM_DLKMIMAGE_TARGET
+INSTALLED_QEMU_SYSTEM_DLKMIMAGE := $(PRODUCT_OUT)/system_dlkm-qemu.img
+$(INSTALLED_QEMU_SYSTEM_DLKMIMAGE): $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) $(MK_QEMU_IMAGE_SH) $(SGDISK_HOST)
+	@echo Create system_dlkm-qemu.img
+	(export SGDISK=$(SGDISK_HOST); $(MK_QEMU_IMAGE_SH) $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET))
+
+system_dlkmimage: $(INSTALLED_QEMU_SYSTEM_DLKMIMAGE)
+droidcore-unbundled: $(INSTALLED_QEMU_SYSTEM_DLKMIMAGE)
+endif
+
 QEMU_VERIFIED_BOOT_PARAMS := $(PRODUCT_OUT)/VerifiedBootParams.textproto
 $(QEMU_VERIFIED_BOOT_PARAMS): $(INSTALLED_VBMETAIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE_TARGET) \
     $(MK_VBMETA_BOOT_KERNEL_CMDLINE_SH) $(AVBTOOL)
diff --git a/core/board_config.mk b/core/board_config.mk
index ad71951..5fb007e 100644
--- a/core/board_config.mk
+++ b/core/board_config.mk
@@ -77,8 +77,6 @@
 _board_strip_readonly_list += BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE
 _board_strip_readonly_list += BOARD_PRODUCTIMAGE_PARTITION_SIZE
 _board_strip_readonly_list += BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE
-_board_strip_readonly_list += BOARD_SYSTEM_DLKM_PARTITION_SIZE
-_board_strip_readonly_list += BOARD_SYSTEM_DLKM_FILE_SYSTEM_TYPE
 _board_strip_readonly_list += BOARD_SYSTEM_EXTIMAGE_PARTITION_SIZE
 _board_strip_readonly_list += BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE
 _board_strip_readonly_list += BOARD_ODMIMAGE_PARTITION_SIZE
@@ -87,6 +85,8 @@
 _board_strip_readonly_list += BOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE
 _board_strip_readonly_list += BOARD_ODM_DLKMIMAGE_PARTITION_SIZE
 _board_strip_readonly_list += BOARD_ODM_DLKMIMAGE_FILE_SYSTEM_TYPE
+_board_strip_readonly_list += BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE
+_board_strip_readonly_list += BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE
 _board_strip_readonly_list += BOARD_PVMFWIMAGE_PARTITION_SIZE
 
 # Logical partitions related variables.
@@ -95,6 +95,7 @@
 _board_strip_readonly_list += BOARD_ODMIMAGE_PARTITION_RESERVED_SIZE
 _board_strip_readonly_list += BOARD_VENDOR_DLKMIMAGE_PARTITION_RESERVED_SIZE
 _board_strip_readonly_list += BOARD_ODM_DLKMIMAGE_PARTITION_RESERVED_SIZE
+_board_strip_readonly_list += BOARD_SYSTEM_DLKMIMAGE_PARTITION_RESERVED_SIZE
 _board_strip_readonly_list += BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE
 _board_strip_readonly_list += BOARD_SYSTEM_EXTIMAGE_PARTITION_RESERVED_SIZE
 _board_strip_readonly_list += BOARD_SUPER_PARTITION_SIZE
@@ -127,7 +128,6 @@
 
 # Prebuilt image variables
 _board_strip_readonly_list += BOARD_PREBUILT_INIT_BOOT_IMAGE
-_board_strip_readonly_list += BOARD_PREBUILT_SYSTEM_DLKM_IMAGE
 
 # Defines the list of logical vendor ramdisk names to build or include in vendor_boot.
 _board_strip_readonly_list += BOARD_VENDOR_RAMDISK_FRAGMENTS
@@ -505,35 +505,6 @@
 endif
 .KATI_READONLY := BUILDING_RECOVERY_IMAGE
 
-# Are we building a system_dlkm image for system_dlkm partition ?
-#
-# Two choices:
-# 1. Use kernel prebuilt system_dlkm.img BOARD_PREBUILT_SYSTEM_DLKM_IMAGE to point image
-# 2. Build from kernel prebuilt system_dlkm_staging set PRODUCT_BUILD_SYSTEM_DLKM_IMAGE
-#
-# Both requires: BOARD_SYSTEM_DLKM_PARTITION_SIZE and must be 64MB or higher (vts).
-#
-BUILDING_SYSTEM_DLKM_IMAGE :=
-ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),)
-  ifdef BOARD_USES_SYSTEM_DLKM_PARTITION
-    BUILDING_SYSTEM_DLKM_IMAGE := true
-  endif
-endif
-ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),true)
-  BUILDING_SYSTEM_DLKM_IMAGE := true
-endif
-.KATI_READONLY := BUILDING_SYSTEM_DLKM_IMAGE
-TARGET_SYSTEM_DLKM_SRC :=
-ifeq ($(BUILDING_SYSTEM_DLKM_IMAGE),true)
-  # Make sure we know the partition size; or warn for default to 64MB
-  ifndef BOARD_SYSTEM_DLKM_PARTITION_SIZE
-    $(error BOARD_SYSTEM_DLKM_PARTITION_SIZE is not defined; must be defined as 64MB or higher.)
-  endif
-  # Point to the source for signed module by kernel; if we are building system_dlkm
-  TARGET_SYSTEM_DLKM_SRC := kernel/prebuilts/$(TARGET_KERNEL_USE)/$(TARGET_ARCH)/system_dlkm_staging
-endif
-.KATI_READONLY := TARGET_SYSTEM_DLKM_SRC
-
 # Are we building a vendor boot image
 BUILDING_VENDOR_BOOT_IMAGE :=
 ifdef BOARD_BOOT_HEADER_VERSION
@@ -899,6 +870,40 @@
 endif
 .KATI_READONLY := BUILDING_ODM_DLKM_IMAGE
 
+###########################################
+# Now we can substitute with the real value of TARGET_COPY_OUT_SYSTEM_DLKM
+ifeq ($(TARGET_COPY_OUT_SYSTEM_DLKM),$(_system_dlkm_path_placeholder))
+  TARGET_COPY_OUT_SYSTEM_DLKM := $(TARGET_COPY_OUT_SYSTEM)/system_dlkm
+else ifeq ($(filter system_dlkm system/system_dlkm,$(TARGET_COPY_OUT_SYSTEM_DLKM)),)
+  $(error TARGET_COPY_OUT_SYSTEM_DLKM must be either 'system_dlkm' or 'system/system_dlkm', seeing '$(TARGET_COPY_OUT_ODM_DLKM)'.)
+endif
+PRODUCT_COPY_FILES := $(subst $(_system_dlkm_path_placeholder),$(TARGET_COPY_OUT_SYSTEM_DLKM),$(PRODUCT_COPY_FILES))
+
+BOARD_USES_SYSTEM_DLKMIMAGE :=
+ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+  BOARD_USES_SYSTEM_DLKMIMAGE := true
+endif
+ifdef BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE
+  BOARD_USES_SYSTEM_DLKMIMAGE := true
+endif
+$(call check_image_config,system_dlkm)
+
+BUILDING_SYSTEM_DLKM_IMAGE :=
+ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),)
+  ifdef BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE
+    BUILDING_SYSTEM_DLKM_IMAGE := true
+  endif
+else ifeq ($(PRODUCT_BUILD_SYSTEM_DLKM_IMAGE),true)
+  BUILDING_SYSTEM_DLKM_IMAGE := true
+  ifndef BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE
+    $(error PRODUCT_BUILD_SYSTEM_DLKM_IMAGE set to true, but BOARD_SYSTEM_DLKMIMAGE_FILE_SYSTEM_TYPE not defined)
+  endif
+endif
+ifdef BOARD_PREBUILT_SYSTEM_DLKMIMAGE
+  BUILDING_SYSTEM_DLKM_IMAGE :=
+endif
+.KATI_READONLY := BUILDING_SYSTEM_DLKM_IMAGE
+
 BOARD_USES_PVMFWIMAGE :=
 ifdef BOARD_PREBUILT_PVMFWIMAGE
   BOARD_USES_PVMFWIMAGE := true
diff --git a/core/config.mk b/core/config.mk
index 6f22b7c..21ab707 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -929,6 +929,13 @@
 endif
 endif
 
+ifneq ($(BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE),)
+ifneq ($(BOARD_SYSTEM_DLKMIMAGE_PARTITION_RESERVED_SIZE),)
+$(error Should not define BOARD_SYSTEM_DLKMIMAGE_PARTITION_SIZE and \
+    BOARD_SYSTEM_DLKMIMAGE_PARTITION_RESERVED_SIZE together)
+endif
+endif
+
 ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_SIZE),)
 ifneq ($(BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE),)
 $(error Should not define BOARD_PRODUCTIMAGE_PARTITION_SIZE and \
@@ -964,7 +971,7 @@
 )
 
 # BOARD_*_PARTITION_LIST: a list of the following tokens
-valid_super_partition_list := system vendor product system_ext odm vendor_dlkm odm_dlkm
+valid_super_partition_list := system vendor product system_ext odm vendor_dlkm odm_dlkm system_dlkm
 $(foreach group,$(call to-upper,$(BOARD_SUPER_PARTITION_GROUPS)), \
     $(if $(filter-out $(valid_super_partition_list),$(BOARD_$(group)_PARTITION_LIST)), \
         $(error BOARD_$(group)_PARTITION_LIST contains invalid partition name \
diff --git a/core/envsetup.mk b/core/envsetup.mk
index 5cf640b..5c5b565 100644
--- a/core/envsetup.mk
+++ b/core/envsetup.mk
@@ -279,6 +279,7 @@
 _odm_path_placeholder := ||ODM-PATH-PH||
 _vendor_dlkm_path_placeholder := ||VENDOR_DLKM-PATH-PH||
 _odm_dlkm_path_placeholder := ||ODM_DLKM-PATH-PH||
+_system_dlkm_path_placeholder := ||SYSTEM_DLKM-PATH-PH||
 TARGET_COPY_OUT_VENDOR := $(_vendor_path_placeholder)
 TARGET_COPY_OUT_VENDOR_RAMDISK := vendor_ramdisk
 TARGET_COPY_OUT_PRODUCT := $(_product_path_placeholder)
@@ -289,6 +290,7 @@
 TARGET_COPY_OUT_ODM := $(_odm_path_placeholder)
 TARGET_COPY_OUT_VENDOR_DLKM := $(_vendor_dlkm_path_placeholder)
 TARGET_COPY_OUT_ODM_DLKM := $(_odm_dlkm_path_placeholder)
+TARGET_COPY_OUT_SYSTEM_DLKM := $(_system_dlkm_path_placeholder)
 
 # Returns the non-sanitized version of the path provided in $1.
 define get_non_asan_path
@@ -840,6 +842,36 @@
     $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_ODM_DLKM_APPS_PRIVILEGED \
     , odm_dlkm should not contain any executables, libraries, or apps)
 
+TARGET_OUT_SYSTEM_DLKM := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_SYSTEM_DLKM)
+
+# Unlike other partitions, system_dlkm should only contain kernel modules.
+TARGET_OUT_SYSTEM_DLKM_EXECUTABLES :=
+TARGET_OUT_SYSTEM_DLKM_OPTIONAL_EXECUTABLES :=
+TARGET_OUT_SYSTEM_DLKM_SHARED_LIBRARIES :=
+TARGET_OUT_SYSTEM_DLKM_RENDERSCRIPT_BITCODE :=
+TARGET_OUT_SYSTEM_DLKM_JAVA_LIBRARIES :=
+TARGET_OUT_SYSTEM_DLKM_APPS :=
+TARGET_OUT_SYSTEM_DLKM_APPS_PRIVILEGED :=
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_EXECUTABLES :=
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_SHARED_LIBRARIES :=
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_RENDERSCRIPT_BITCODE :=
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_APPS :=
+$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_APPS_PRIVILEGED :=
+$(KATI_obsolete_var \
+    TARGET_OUT_SYSTEM_DLKM_EXECUTABLES \
+    TARGET_OUT_SYSTEM_DLKM_OPTIONAL_EXECUTABLES \
+    TARGET_OUT_SYSTEM_DLKM_SHARED_LIBRARIES \
+    TARGET_OUT_SYSTEM_DLKM_RENDERSCRIPT_BITCODE \
+    TARGET_OUT_SYSTEM_DLKM_JAVA_LIBRARIES \
+    TARGET_OUT_SYSTEM_DLKM_APPS \
+    TARGET_OUT_SYSTEM_DLKM_APPS_PRIVILEGED \
+    $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_EXECUTABLES \
+    $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_SHARED_LIBRARIES \
+    $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_RENDERSCRIPT_BITCODE \
+    $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_APPS \
+    $(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_SYSTEM_DLKM_APPS_PRIVILEGED \
+    , system_dlkm should not contain any executables, libraries, or apps)
+
 TARGET_OUT_PRODUCT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_PRODUCT)
 TARGET_OUT_PRODUCT_EXECUTABLES := $(TARGET_OUT_PRODUCT)/bin
 .KATI_READONLY := TARGET_OUT_PRODUCT
diff --git a/core/main.mk b/core/main.mk
index 7e7575f..e9cbc60 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1209,7 +1209,8 @@
         $(subst $(_odm_path_placeholder),$(TARGET_COPY_OUT_ODM),\
           $(subst $(_vendor_dlkm_path_placeholder),$(TARGET_COPY_OUT_VENDOR_DLKM),\
             $(subst $(_odm_dlkm_path_placeholder),$(TARGET_COPY_OUT_ODM_DLKM),\
-              $(foreach p,$(1),$(call append-path,$(PRODUCT_OUT),$(p)$(2)))))))))
+              $(subst $(_system_dlkm_path_placeholder),$(TARGET_COPY_OUT_SYSTEM_DLKM),\
+                $(foreach p,$(1),$(call append-path,$(PRODUCT_OUT),$(p)$(2))))))))))
 endef
 
 # Returns modules included automatically as a result of certain BoardConfig
@@ -1594,6 +1595,9 @@
 .PHONY: odm_dlkmimage
 odm_dlkmimage: $(INSTALLED_ODM_DLKMIMAGE_TARGET)
 
+.PHONY: system_dlkmimage
+system_dlkmimage: $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET)
+
 .PHONY: systemotherimage
 systemotherimage: $(INSTALLED_SYSTEMOTHERIMAGE_TARGET)
 
@@ -1606,9 +1610,6 @@
 .PHONY: initbootimage
 initbootimage: $(INSTALLED_INIT_BOOT_IMAGE_TARGET)
 
-.PHONY: system_dlkm_image
-system_dlkm_image: $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET)
-
 ifeq (true,$(PRODUCT_EXPORT_BOOT_IMAGE_TO_DIST))
 $(call dist-for-goals, bootimage, $(INSTALLED_BOOTIMAGE_TARGET))
 endif
@@ -1633,7 +1634,6 @@
 .PHONY: droidcore-unbundled
 droidcore-unbundled: $(filter $(HOST_OUT_ROOT)/%,$(modules_to_install)) \
     $(INSTALLED_SYSTEMIMAGE_TARGET) \
-    $(INSTALLED_SYSTEM_DLKM_IMAGE_TARGET) \
     $(INSTALLED_RAMDISK_TARGET) \
     $(INSTALLED_BOOTIMAGE_TARGET) \
     $(INSTALLED_INIT_BOOT_IMAGE_TARGET) \
@@ -1657,6 +1657,7 @@
     $(INSTALLED_ODMIMAGE_TARGET) \
     $(INSTALLED_VENDOR_DLKMIMAGE_TARGET) \
     $(INSTALLED_ODM_DLKMIMAGE_TARGET) \
+    $(INSTALLED_SYSTEM_DLKMIMAGE_TARGET) \
     $(INSTALLED_SUPERIMAGE_EMPTY_TARGET) \
     $(INSTALLED_PRODUCTIMAGE_TARGET) \
     $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
@@ -1672,6 +1673,8 @@
     $(INSTALLED_FILES_JSON_VENDOR_DLKM) \
     $(INSTALLED_FILES_FILE_ODM_DLKM) \
     $(INSTALLED_FILES_JSON_ODM_DLKM) \
+    $(INSTALLED_FILES_FILE_SYSTEM_DLKM) \
+    $(INSTALLED_FILES_JSON_SYSTEM_DLKM) \
     $(INSTALLED_FILES_FILE_PRODUCT) \
     $(INSTALLED_FILES_JSON_PRODUCT) \
     $(INSTALLED_FILES_FILE_SYSTEM_EXT) \
@@ -1822,6 +1825,8 @@
     $(INSTALLED_FILES_JSON_VENDOR_DLKM) \
     $(INSTALLED_FILES_FILE_ODM_DLKM) \
     $(INSTALLED_FILES_JSON_ODM_DLKM) \
+    $(INSTALLED_FILES_FILE_SYSTEM_DLKM) \
+    $(INSTALLED_FILES_JSON_SYSTEM_DLKM) \
     $(INSTALLED_FILES_FILE_PRODUCT) \
     $(INSTALLED_FILES_JSON_PRODUCT) \
     $(INSTALLED_FILES_FILE_SYSTEM_EXT) \
diff --git a/core/product.mk b/core/product.mk
index 21db81e..43724a8 100644
--- a/core/product.mk
+++ b/core/product.mk
@@ -268,6 +268,7 @@
 _product_single_value_vars += PRODUCT_ODM_VERITY_PARTITION
 _product_single_value_vars += PRODUCT_VENDOR_DLKM_VERITY_PARTITION
 _product_single_value_vars += PRODUCT_ODM_DLKM_VERITY_PARTITION
+_product_single_value_vars += PRODUCT_SYSTEM_DLKM_VERITY_PARTITION
 _product_single_value_vars += PRODUCT_SYSTEM_SERVER_DEBUG_INFO
 _product_single_value_vars += PRODUCT_OTHER_JAVA_DEBUG_INFO
 
@@ -298,6 +299,7 @@
 _product_single_value_vars += PRODUCT_ODM_BASE_FS_PATH
 _product_single_value_vars += PRODUCT_VENDOR_DLKM_BASE_FS_PATH
 _product_single_value_vars += PRODUCT_ODM_DLKM_BASE_FS_PATH
+_product_single_value_vars += PRODUCT_SYSTEM_DLKM_BASE_FS_PATH
 
 # The first API level this product shipped with
 _product_single_value_vars += PRODUCT_SHIPPING_API_LEVEL
@@ -384,7 +386,6 @@
 
 # Controls for whether different partitions are built for the current product.
 _product_single_value_vars += PRODUCT_BUILD_SYSTEM_IMAGE
-_product_single_value_vars += PRODUCT_BUILD_SYSTEM_DLKM_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_SYSTEM_OTHER_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_VENDOR_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_PRODUCT_IMAGE
@@ -392,6 +393,7 @@
 _product_single_value_vars += PRODUCT_BUILD_ODM_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_VENDOR_DLKM_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_ODM_DLKM_IMAGE
+_product_single_value_vars += PRODUCT_BUILD_SYSTEM_DLKM_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_CACHE_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_RAMDISK_IMAGE
 _product_single_value_vars += PRODUCT_BUILD_USERDATA_IMAGE
diff --git a/core/product_config.mk b/core/product_config.mk
index 6fae73e..15935ea 100644
--- a/core/product_config.mk
+++ b/core/product_config.mk
@@ -566,6 +566,7 @@
     ODM \
     VENDOR_DLKM \
     ODM_DLKM \
+    SYSTEM_DLKM \
     CACHE \
     RAMDISK \
     USERDATA \
diff --git a/core/soong_config.mk b/core/soong_config.mk
index a8071a3..7f9dbe5 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -174,6 +174,7 @@
 $(call add_json_str,  OdmPath,                           $(TARGET_COPY_OUT_ODM))
 $(call add_json_str,  VendorDlkmPath,                    $(TARGET_COPY_OUT_VENDOR_DLKM))
 $(call add_json_str,  OdmDlkmPath,                       $(TARGET_COPY_OUT_ODM_DLKM))
+$(call add_json_str,  SystemDlkmPath,                    $(TARGET_COPY_OUT_SYSTEM_DLKM))
 $(call add_json_str,  ProductPath,                       $(TARGET_COPY_OUT_PRODUCT))
 $(call add_json_str,  SystemExtPath,                     $(TARGET_COPY_OUT_SYSTEM_EXT))
 $(call add_json_bool, MinimizeJavaDebugInfo,             $(filter true,$(PRODUCT_MINIMIZE_JAVA_DEBUG_INFO)))
@@ -199,6 +200,7 @@
 $(call add_json_list, BoardOdmSepolicyDirs,              $(BOARD_ODM_SEPOLICY_DIRS))
 $(call add_json_list, BoardVendorDlkmSepolicyDirs,       $(BOARD_VENDOR_DLKM_SEPOLICY_DIRS))
 $(call add_json_list, BoardOdmDlkmSepolicyDirs,          $(BOARD_ODM_DLKM_SEPOLICY_DIRS))
+$(call add_json_list, BoardSystemDlkmSepolicyDirs,       $(BOARD_SYSTEM_DLKM_SEPOLICY_DIRS))
 # TODO: BOARD_PLAT_* dirs only kept for compatibility reasons. Will be a hard error on API level 31
 $(call add_json_list, SystemExtPublicSepolicyDirs,       $(SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS) $(BOARD_PLAT_PUBLIC_SEPOLICY_DIR))
 $(call add_json_list, SystemExtPrivateSepolicyDirs,      $(SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS) $(BOARD_PLAT_PRIVATE_SEPOLICY_DIR))
diff --git a/core/sysprop.mk b/core/sysprop.mk
index 1d38f8c..12ead6e 100644
--- a/core/sysprop.mk
+++ b/core/sysprop.mk
@@ -464,6 +464,20 @@
     $(empty),\
     $(empty)))
 
+# ----------------------------------------------------------------
+# system_dlkm/build.prop
+#
+
+INSTALLED_SYSTEM_DLKM_BUILD_PROP_TARGET := $(TARGET_OUT_SYSTEM_DLKM)/etc/build.prop
+$(eval $(call build-properties,\
+    system_dlkm,\
+    $(INSTALLED_SYSTEM_DLKM_BUILD_PROP_TARGET),\
+    $(empty),\
+    $(empty),\
+    $(empty),\
+    $(empty),\
+    $(empty)))
+
 # -----------------------------------------------------------------
 # system_ext/etc/build.prop
 #