blob: c6761d8d973a6c67c91068799e747cde9ccc1648 [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:
der_akinatorbeaa41e2023-11-23 05:45:16 +000076#ifdef TW_LOAD_VENDOR_BOOT_MODULES
77 for (auto&& module_dir:module_dirs) {
78 modules_loaded += Try_And_Load_Modules(module_dir, false);
79 if (modules_loaded >= expected_module_count) goto exit;
80 }
81#endif
Mohd Farazfe8bcd42023-08-26 20:50:26 +053082 /* In both mode vendor_boot or vendor modules are used
83 * Because Ramdisk is flashed in both.
84 */
85 break;
bigbiff850fa282021-10-09 12:37:29 -040086 }
bigbiff22851b92021-09-01 16:46:57 -040087
bigbiff850fa282021-10-09 12:37:29 -040088 if (ven) {
89 LOGINFO("Checking mounted /vendor\n");
90 ven->Mount(true);
91 }
bigbiff8c52c872022-04-10 17:34:46 -040092 if (ven_dlkm) {
93 LOGINFO("Checking mounted /vendor_dlkm\n");
94 ven_dlkm->Mount(true);
95 }
bigbiff22851b92021-09-01 16:46:57 -040096
bigbiff850fa282021-10-09 12:37:29 -040097 for (auto&& module_dir:vendor_module_dirs) {
98 modules_loaded += Try_And_Load_Modules(module_dir, true);
99 if (modules_loaded >= expected_module_count) goto exit;
100 }
bigbiff22851b92021-09-01 16:46:57 -0400101
bigbiff8c52c872022-04-10 17:34:46 -0400102 modules_loaded += Try_And_Load_Modules(vendor_dlkm_base_dir, true);
103 if (modules_loaded >= expected_module_count) goto exit;
104
bigbiffe3aa02e2021-10-01 13:07:38 -0400105exit:
bigbiff850fa282021-10-09 12:37:29 -0400106 if (ven)
107 ven->UnMount(false);
bigbiff8c52c872022-04-10 17:34:46 -0400108 if (ven_dlkm)
Captain Throwback8d665fa2024-01-28 23:41:14 -0500109 ven_dlkm->UnMount(false, MNT_DETACH);
bigbiff22851b92021-09-01 16:46:57 -0400110
Mohd Farazfe8bcd42023-08-26 20:50:26 +0530111 android::base::SetProperty(TW_MODULES_MOUNTED_PROP, "true");
Adithya Ra327aa72021-12-19 00:49:54 +0530112
bigbiff22851b92021-09-01 16:46:57 -0400113 return true;
114}
115
bigbiff850fa282021-10-09 12:37:29 -0400116int KernelModuleLoader::Try_And_Load_Modules(std::string module_dir, bool vendor_is_mounted) {
117 LOGINFO("Checking directory: %s\n", module_dir.c_str());
118 int modules_loaded = 0;
119 std::string dest_module_dir;
120 dest_module_dir = "/tmp" + module_dir;
121 TWFunc::Recursive_Mkdir(dest_module_dir);
122 Copy_Modules_To_Tmpfs(module_dir);
123 if (!Write_Module_List(dest_module_dir))
124 return kernel_modules_requested.size();
125 if (!vendor_is_mounted && module_dir == "/vendor/lib/modules") {
126 module_dir = "/lib/modules";
127 }
128 LOGINFO("mounting %s on %s\n", dest_module_dir.c_str(), module_dir.c_str());
129 if (mount(dest_module_dir.c_str(), module_dir.c_str(), "", MS_BIND, NULL) == 0) {
nijel84b185322022-01-03 14:28:39 -0500130 Modprobe m({module_dir}, "modules.load.twrp", false);
bigbiff850fa282021-10-09 12:37:29 -0400131 m.LoadListedModules(false);
132 modules_loaded = m.GetModuleCount();
Captain Throwback8d665fa2024-01-28 23:41:14 -0500133 PartitionManager.UnMount_By_Path(module_dir.c_str(), false, MNT_DETACH);
bigbiff850fa282021-10-09 12:37:29 -0400134 LOGINFO("Modules Loaded: %d\n", modules_loaded);
135 }
136 return modules_loaded;
137}
138
139std::vector<string> KernelModuleLoader::Skip_Loaded_Kernel_Modules() {
140 std::vector<string> kernel_modules = kernel_modules_requested;
141 std::vector<string> loaded_modules;
142 std::string kernel_module_file = "/proc/modules";
143 if (TWFunc::read_file(kernel_module_file, loaded_modules) < 0)
144 LOGINFO("failed to get loaded kernel modules\n");
Magendanz84164b92021-12-12 14:53:41 -0800145 LOGINFO("number of modules loaded by init: %zu\n", loaded_modules.size());
bigbiff850fa282021-10-09 12:37:29 -0400146 if (loaded_modules.size() == 0)
147 return kernel_modules;
148 for (auto&& module_line:loaded_modules) {
149 auto module = TWFunc::Split_String(module_line, " ")[0];
150 std::string full_module_name = module + ".ko";
151 auto found = std::find(kernel_modules.begin(), kernel_modules.end(), full_module_name);
152 if (found != kernel_modules.end()) {
153 LOGINFO("found module to dedupe: %s\n", (*found).c_str());
154 kernel_modules.erase(found);
155 }
156 }
157 return kernel_modules;
bigbiff22851b92021-09-01 16:46:57 -0400158}
159
160bool KernelModuleLoader::Write_Module_List(std::string module_dir) {
161 DIR* d;
162 struct dirent* de;
163 std::vector<std::string> kernel_modules;
bigbiff22851b92021-09-01 16:46:57 -0400164 d = opendir(module_dir.c_str());
bigbiff850fa282021-10-09 12:37:29 -0400165 auto deduped_modules = Skip_Loaded_Kernel_Modules();
166 if (deduped_modules.size() == 0) {
167 LOGINFO("Requested modules are loaded\n");
168 return false;
169 }
bigbiff22851b92021-09-01 16:46:57 -0400170 if (d != nullptr) {
171 while ((de = readdir(d)) != nullptr) {
172 std::string kernel_module = de->d_name;
173 if (de->d_type == DT_REG) {
174 if (android::base::EndsWith(kernel_module, ".ko")) {
175 for (auto&& requested:kernel_modules_requested) {
176 if (kernel_module == requested) {
177 kernel_modules.push_back(kernel_module);
bigbiff850fa282021-10-09 12:37:29 -0400178 continue;
179 }
bigbiff22851b92021-09-01 16:46:57 -0400180 }
181 continue;
182 }
183 }
184 }
bigbiff850fa282021-10-09 12:37:29 -0400185 std::string module_file = module_dir + "/modules.load.twrp";
bigbiff22851b92021-09-01 16:46:57 -0400186 TWFunc::write_to_file(module_file, kernel_modules);
bigbiff850fa282021-10-09 12:37:29 -0400187 closedir(d);
bigbiff22851b92021-09-01 16:46:57 -0400188 }
189 return true;
190}
191
192bool KernelModuleLoader::Copy_Modules_To_Tmpfs(std::string module_dir) {
bigbiff850fa282021-10-09 12:37:29 -0400193 std::string ramdisk_dir = "/tmp" + module_dir;
194 DIR* d;
bigbiff22851b92021-09-01 16:46:57 -0400195 struct dirent* de;
bigbiff850fa282021-10-09 12:37:29 -0400196 d = opendir(module_dir.c_str());
197 if (d != nullptr) {
198 while ((de = readdir(d)) != nullptr) {
199 std::string kernel_module = de->d_name;
200 if (de->d_type == DT_REG) {
201 std::string src = module_dir + "/" + de->d_name;
202 std::string dest = ramdisk_dir + "/" + de->d_name;
203 if (TWFunc::copy_file(src, dest, 0700, false) != 0) {
204 return false;
205 }
206 }
207 }
208 closedir(d);
209 } else {
210 LOGINFO("Unable to open module directory: %s. Skipping\n", module_dir.c_str());
211 return false;
212 }
213 return true;
214}