module load: attempt to load modules from /vendor

Use TW_LOAD_VENDOR_MODULES := "module1.ko module2.ko modulen.ko"
in BoardConfig to have TWRP attempt to load kernel modules during
startup. For fastboot ramdisks, TWRP will attempt to load from
the ramdisk from /vendor/lib/modules. You can have the build
system copy the modules to
$(TARGET_RECOVERY_ROOT_OUT)/vendor/lib/modules/1.1
Otherwise in recovery in boot mode, TWRP will attempt the following:
check /lib/modules (ramdisk vendor_boot)
check /lib/modules/N.N (ramdisk vendor_boot)
check /lib/modules/N.N-gki (ramdisk vendor_boot)
check /vendor/lib/modules (ramdisk)
check /vendor/lib/modules/1.1 (ramdisk prebuilt modules)
check /vendor/lib/modules/N.N (vendor mounted)
check /vendor/lib/modules/N.N-gki (vendor mounted)

Change-Id: I2dccf199e37d47cb7a7e79b0e11026d67b4e3186
diff --git a/twrp.cpp b/twrp.cpp
index 6de0e62..1b0e337 100644
--- a/twrp.cpp
+++ b/twrp.cpp
@@ -44,6 +44,7 @@
 #include "twcommon.h"
 #include "twrp-functions.hpp"
 #include "data.hpp"
+#include "kernel_module_loader.hpp"
 #include "partitions.hpp"
 #ifdef __ANDROID_API_N__
 #include <android-base/strings.h>
@@ -101,9 +102,39 @@
 	}
 }
 
+static void process_fastbootd_mode() {
+		LOGINFO("starting fastboot\n");
+		printf("=> Linking mtab\n");
+		symlink("/proc/mounts", "/etc/mtab");
+		std::string fstab_filename = "/etc/twrp.fstab";
+		if (!TWFunc::Path_Exists(fstab_filename)) {
+			fstab_filename = "/etc/recovery.fstab";
+		}
+		printf("=> Processing %s\n", fstab_filename.c_str());
+		if (!PartitionManager.Process_Fstab(fstab_filename, 1, false)) {
+			LOGERR("Failing out of recovery due to problem with fstab.\n");
+			return;
+		}
+		TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor");
+		PartitionManager.Setup_Super_Devices();
+		PartitionManager.Prepare_Super_Volume(ven);
+#ifdef TW_LOAD_VENDOR_MODULES
+		KernelModuleLoader::Load_Vendor_Modules(FASTBOOTD_MODE);
+#endif
+		gui_msg(Msg("fastboot_console_msg=Entered Fastboot mode..."));
+		if (gui_startPage("fastboot", 1, 1) != 0) {
+			LOGERR("Failed to start fastbootd page.\n");
+		}
+}
+
 static void process_recovery_mode(twrpAdbBuFifo* adb_bu_fifo, bool skip_decryption) {
 	char crash_prop_val[PROPERTY_VALUE_MAX];
 	int crash_counter;
+	std::string cmdline;
+	if (TWFunc::read_file("/proc/cmdline", cmdline) != 0) {
+		LOGINFO("Unable to read cmdline for fastboot mode\n");
+	}
+
 	property_get("twrp.crash_counter", crash_prop_val, "-1");
 	crash_counter = atoi(crash_prop_val) + 1;
 	snprintf(crash_prop_val, sizeof(crash_prop_val), "%d", crash_counter);
@@ -123,11 +154,19 @@
 		fstab_filename = "/etc/recovery.fstab";
 	}
 	printf("=> Processing %s\n", fstab_filename.c_str());
-	if (!PartitionManager.Process_Fstab(fstab_filename, 1)) {
+	if (!PartitionManager.Process_Fstab(fstab_filename, 1, true)) {
 		LOGERR("Failing out of recovery due to problem with fstab.\n");
 		return;
 	}
 
+#ifdef TW_LOAD_VENDOR_MODULES
+	bool fastboot_mode = cmdline.find("twrpfastboot=1") != std::string::npos;
+	if (fastboot_mode)
+		KernelModuleLoader::Load_Vendor_Modules(RECOVERY_FASTBOOT_MODE);
+	else
+		KernelModuleLoader::Load_Vendor_Modules(RECOVERY_IN_BOOT_MODE);
+#endif
+
 // We are doing this here to allow super partition to be set up prior to overriding properties
 #if defined(TW_INCLUDE_LIBRESETPROP) && defined(TW_OVERRIDE_SYSTEM_PROPS)
 	if (!PartitionManager.Mount_By_Path(PartitionManager.Get_Android_Root_Path(), true)) {
@@ -340,14 +379,9 @@
 	TWFunc::Clear_Bootloader_Message();
 
 	if (startup.Get_Fastboot_Mode()) {
-		LOGINFO("starting fastboot\n");
-		gui_msg(Msg("fastboot_console_msg=Entered Fastboot mode..."));
-		if (gui_startPage("fastboot", 1, 1) != 0) {
-			LOGERR("Failed to start fastbootd page.\n");
-		}
+		process_fastbootd_mode();
 		delete adb_bu_fifo;
 		TWFunc::Update_Intent_File(startup.Get_Intent());
-
 		reboot();
 		return 0;
 	} else {
@@ -363,7 +397,6 @@
 	gui_start();
 	delete adb_bu_fifo;
 	TWFunc::Update_Intent_File(startup.Get_Intent());
-
 	reboot();
 
 	return 0;