blob: 292d18f6ffb8a365f773fe81de240dee34bed9e0 [file] [log] [blame]
bigbiff22851b92021-09-01 16:46:57 -04001#include "kernel_module_loader.hpp"
Adithya Ra327aa72021-12-19 00:49:54 +05302#include "common.h"
Mohd Farazfe8bcd42023-08-26 20:50:26 +05303#include "variables.h"
bigbiff22851b92021-09-01 16:46:57 -04004
bigbiffe3aa02e2021-10-01 13:07:38 -04005const std::vector<std::string> kernel_modules_requested = TWFunc::split_string(EXPAND(TW_LOAD_VENDOR_MODULES), ' ', true);
6
Mohd Farazfe8bcd42023-08-26 20:50:26 +05307BOOT_MODE KernelModuleLoader::Get_Boot_Mode() {
8 std::string cmdline;
9 std::string bootconfig;
10 android::base::ReadFileToString("/proc/bootconfig", &bootconfig);
11 android::base::ReadFileToString("/proc/cmdline", &cmdline);
12
13 if (cmdline.find("twrpfastboot=1") != std::string::npos && (bootconfig.find("androidboot.force_normal_boot = \"1\"") != std::string::npos ||
14 cmdline.find("androidboot.force_normal_boot=1") != std::string::npos))
15 return RECOVERY_FASTBOOT_MODE;
16 else if (android::base::GetProperty(TW_FASTBOOT_MODE_PROP, "0") == "1")
17 return FASTBOOTD_MODE;
18
19 return RECOVERY_IN_BOOT_MODE;
20}
21
bigbiff850fa282021-10-09 12:37:29 -040022bool KernelModuleLoader::Load_Vendor_Modules() {
23 // check /lib/modules (ramdisk vendor_boot)
24 // check /lib/modules/N.N (ramdisk vendor_boot)
25 // check /lib/modules/N.N-gki (ramdisk vendor_boot)
26 // check /vendor/lib/modules (ramdisk)
27 // check /vendor/lib/modules/1.1 (ramdisk prebuilt modules)
28 // check /vendor/lib/modules/N.N (vendor mounted)
29 // check /vendor/lib/modules/N.N-gki (vendor mounted)
bigbiff8c52c872022-04-10 17:34:46 -040030 // check /vendor_dlkm/lib/modules (vendor_dlkm mounted)
Mohd Farazfe8bcd42023-08-26 20:50:26 +053031 if (android::base::GetBoolProperty(TW_MODULES_MOUNTED_PROP, false)) return true;
bigbiff850fa282021-10-09 12:37:29 -040032 int modules_loaded = 0;
bigbiff22851b92021-09-01 16:46:57 -040033
bigbiff850fa282021-10-09 12:37:29 -040034 LOGINFO("Attempting to load modules\n");
35 std::string vendor_base_dir(VENDOR_MODULE_DIR);
36 std::string base_dir(VENDOR_BOOT_MODULE_DIR);
bigbiff8c52c872022-04-10 17:34:46 -040037 std::string vendor_dlkm_base_dir(VENDOR_DLKM_MODULE_DIR);
bigbiff850fa282021-10-09 12:37:29 -040038 std::vector<std::string> module_dirs;
39 std::vector<std::string> vendor_module_dirs;
bigbiff22851b92021-09-01 16:46:57 -040040
bigbiff850fa282021-10-09 12:37:29 -040041 TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor");
bigbiff8c52c872022-04-10 17:34:46 -040042 TWPartition* ven_dlkm = PartitionManager.Find_Partition_By_Path("/vendor_dlkm");
bigbiff850fa282021-10-09 12:37:29 -040043 vendor_module_dirs.push_back(VENDOR_MODULE_DIR);
44 vendor_module_dirs.push_back(vendor_base_dir + "/1.1");
bigbiff22851b92021-09-01 16:46:57 -040045
bigbiff850fa282021-10-09 12:37:29 -040046 module_dirs.push_back(base_dir);
bigbiff22851b92021-09-01 16:46:57 -040047
bigbiff850fa282021-10-09 12:37:29 -040048 struct utsname uts;
49 if (uname(&uts)) {
50 LOGERR("Unable to query kernel for version info\n");
51 }
bigbiff22851b92021-09-01 16:46:57 -040052
bigbiff850fa282021-10-09 12:37:29 -040053 std::string rls(uts.release);
54 std::vector<std::string> release = TWFunc::split_string(rls, '.', true);
55 int expected_module_count = kernel_modules_requested.size();
56 module_dirs.push_back(base_dir + "/" + release[0] + "." + release[1]);
Captain Throwbackfd464d52023-08-18 10:54:41 -040057#ifndef TW_LOAD_VENDOR_MODULES_EXCLUDE_GKI
sekaiacge86b9c72021-12-31 19:30:44 +080058 std::string gki = "/" + release[0] + "." + release[1] + "-gki";
59 module_dirs.push_back(base_dir + gki);
60 vendor_module_dirs.push_back(vendor_base_dir + gki);
Captain Throwbackfd464d52023-08-18 10:54:41 -040061#endif
bigbiff22851b92021-09-01 16:46:57 -040062
Mohd Farazfe8bcd42023-08-26 20:50:26 +053063 switch(Get_Boot_Mode()) {
64 case RECOVERY_FASTBOOT_MODE:
65 /* On bootmode: once, there is not always stock kernel
66 * so try only with twrp prebuilt modules.
67 */
68 for (auto&& module_dir:vendor_module_dirs) {
69 modules_loaded += Try_And_Load_Modules(module_dir, false);
70 if (modules_loaded >= expected_module_count) goto exit;
71 }
72 break;
bigbiff22851b92021-09-01 16:46:57 -040073
Mohd Farazfe8bcd42023-08-26 20:50:26 +053074 case FASTBOOTD_MODE:
75 case RECOVERY_IN_BOOT_MODE:
76 /* In both mode vendor_boot or vendor modules are used
77 * Because Ramdisk is flashed in both.
78 */
79 break;
bigbiff850fa282021-10-09 12:37:29 -040080 }
bigbiff22851b92021-09-01 16:46:57 -040081
bigbiff850fa282021-10-09 12:37:29 -040082 if (ven) {
83 LOGINFO("Checking mounted /vendor\n");
84 ven->Mount(true);
85 }
bigbiff8c52c872022-04-10 17:34:46 -040086 if (ven_dlkm) {
87 LOGINFO("Checking mounted /vendor_dlkm\n");
88 ven_dlkm->Mount(true);
89 }
bigbiff22851b92021-09-01 16:46:57 -040090
bigbiff850fa282021-10-09 12:37:29 -040091 for (auto&& module_dir:vendor_module_dirs) {
92 modules_loaded += Try_And_Load_Modules(module_dir, true);
93 if (modules_loaded >= expected_module_count) goto exit;
94 }
bigbiff22851b92021-09-01 16:46:57 -040095
bigbiff8c52c872022-04-10 17:34:46 -040096 modules_loaded += Try_And_Load_Modules(vendor_dlkm_base_dir, true);
97 if (modules_loaded >= expected_module_count) goto exit;
98
bigbiffe3aa02e2021-10-01 13:07:38 -040099exit:
bigbiff850fa282021-10-09 12:37:29 -0400100 if (ven)
101 ven->UnMount(false);
bigbiff8c52c872022-04-10 17:34:46 -0400102 if (ven_dlkm)
103 ven_dlkm->UnMount(false);
bigbiff22851b92021-09-01 16:46:57 -0400104
Mohd Farazfe8bcd42023-08-26 20:50:26 +0530105 android::base::SetProperty(TW_MODULES_MOUNTED_PROP, "true");
Adithya Ra327aa72021-12-19 00:49:54 +0530106
bigbiff22851b92021-09-01 16:46:57 -0400107 return true;
108}
109
bigbiff850fa282021-10-09 12:37:29 -0400110int KernelModuleLoader::Try_And_Load_Modules(std::string module_dir, bool vendor_is_mounted) {
111 LOGINFO("Checking directory: %s\n", module_dir.c_str());
112 int modules_loaded = 0;
113 std::string dest_module_dir;
114 dest_module_dir = "/tmp" + module_dir;
115 TWFunc::Recursive_Mkdir(dest_module_dir);
116 Copy_Modules_To_Tmpfs(module_dir);
117 if (!Write_Module_List(dest_module_dir))
118 return kernel_modules_requested.size();
119 if (!vendor_is_mounted && module_dir == "/vendor/lib/modules") {
120 module_dir = "/lib/modules";
121 }
122 LOGINFO("mounting %s on %s\n", dest_module_dir.c_str(), module_dir.c_str());
123 if (mount(dest_module_dir.c_str(), module_dir.c_str(), "", MS_BIND, NULL) == 0) {
nijel84b185322022-01-03 14:28:39 -0500124 Modprobe m({module_dir}, "modules.load.twrp", false);
bigbiff850fa282021-10-09 12:37:29 -0400125 m.LoadListedModules(false);
126 modules_loaded = m.GetModuleCount();
127 umount2(module_dir.c_str(), MNT_DETACH);
128 LOGINFO("Modules Loaded: %d\n", modules_loaded);
129 }
130 return modules_loaded;
131}
132
133std::vector<string> KernelModuleLoader::Skip_Loaded_Kernel_Modules() {
134 std::vector<string> kernel_modules = kernel_modules_requested;
135 std::vector<string> loaded_modules;
136 std::string kernel_module_file = "/proc/modules";
137 if (TWFunc::read_file(kernel_module_file, loaded_modules) < 0)
138 LOGINFO("failed to get loaded kernel modules\n");
Magendanz84164b92021-12-12 14:53:41 -0800139 LOGINFO("number of modules loaded by init: %zu\n", loaded_modules.size());
bigbiff850fa282021-10-09 12:37:29 -0400140 if (loaded_modules.size() == 0)
141 return kernel_modules;
142 for (auto&& module_line:loaded_modules) {
143 auto module = TWFunc::Split_String(module_line, " ")[0];
144 std::string full_module_name = module + ".ko";
145 auto found = std::find(kernel_modules.begin(), kernel_modules.end(), full_module_name);
146 if (found != kernel_modules.end()) {
147 LOGINFO("found module to dedupe: %s\n", (*found).c_str());
148 kernel_modules.erase(found);
149 }
150 }
151 return kernel_modules;
bigbiff22851b92021-09-01 16:46:57 -0400152}
153
154bool KernelModuleLoader::Write_Module_List(std::string module_dir) {
155 DIR* d;
156 struct dirent* de;
157 std::vector<std::string> kernel_modules;
bigbiff22851b92021-09-01 16:46:57 -0400158 d = opendir(module_dir.c_str());
bigbiff850fa282021-10-09 12:37:29 -0400159 auto deduped_modules = Skip_Loaded_Kernel_Modules();
160 if (deduped_modules.size() == 0) {
161 LOGINFO("Requested modules are loaded\n");
162 return false;
163 }
bigbiff22851b92021-09-01 16:46:57 -0400164 if (d != nullptr) {
165 while ((de = readdir(d)) != nullptr) {
166 std::string kernel_module = de->d_name;
167 if (de->d_type == DT_REG) {
168 if (android::base::EndsWith(kernel_module, ".ko")) {
169 for (auto&& requested:kernel_modules_requested) {
170 if (kernel_module == requested) {
171 kernel_modules.push_back(kernel_module);
bigbiff850fa282021-10-09 12:37:29 -0400172 continue;
173 }
bigbiff22851b92021-09-01 16:46:57 -0400174 }
175 continue;
176 }
177 }
178 }
bigbiff850fa282021-10-09 12:37:29 -0400179 std::string module_file = module_dir + "/modules.load.twrp";
bigbiff22851b92021-09-01 16:46:57 -0400180 TWFunc::write_to_file(module_file, kernel_modules);
bigbiff850fa282021-10-09 12:37:29 -0400181 closedir(d);
bigbiff22851b92021-09-01 16:46:57 -0400182 }
183 return true;
184}
185
186bool KernelModuleLoader::Copy_Modules_To_Tmpfs(std::string module_dir) {
bigbiff850fa282021-10-09 12:37:29 -0400187 std::string ramdisk_dir = "/tmp" + module_dir;
188 DIR* d;
bigbiff22851b92021-09-01 16:46:57 -0400189 struct dirent* de;
bigbiff850fa282021-10-09 12:37:29 -0400190 d = opendir(module_dir.c_str());
191 if (d != nullptr) {
192 while ((de = readdir(d)) != nullptr) {
193 std::string kernel_module = de->d_name;
194 if (de->d_type == DT_REG) {
195 std::string src = module_dir + "/" + de->d_name;
196 std::string dest = ramdisk_dir + "/" + de->d_name;
197 if (TWFunc::copy_file(src, dest, 0700, false) != 0) {
198 return false;
199 }
200 }
201 }
202 closedir(d);
203 } else {
204 LOGINFO("Unable to open module directory: %s. Skipping\n", module_dir.c_str());
205 return false;
206 }
207 return true;
208}