blob: fd24a91974de8bdb0df9e83840fc09087a7c3141 [file] [log] [blame]
bigbiff22851b92021-09-01 16:46:57 -04001#include "kernel_module_loader.hpp"
2
3bool KernelModuleLoader::Load_Vendor_Modules(BOOT_MODE mode) {
4 // check /lib/modules (ramdisk vendor_boot)
5 // check /lib/modules/N.N (ramdisk vendor_boot)
6 // check /lib/modules/N.N-gki (ramdisk vendor_boot)
7 // check /vendor/lib/modules (ramdisk)
8 // check /vendor/lib/modules/1.1 (ramdisk prebuilt modules)
9 // check /vendor/lib/modules/N.N (vendor mounted)
10 // check /vendor/lib/modules/N.N-gki (vendor mounted)
11
12 LOGINFO("Attempting to load modules\n");
13 std::string vendor_base_dir(VENDOR_MODULE_DIR);
14 std::string base_dir(VENDOR_BOOT_MODULE_DIR);
15 std::vector<std::string> module_dirs;
16 std::vector<std::string> vendor_module_dirs;
17
18 TWPartition* ven = PartitionManager.Find_Partition_By_Path("/vendor");
19 vendor_module_dirs.push_back(VENDOR_MODULE_DIR);
20 vendor_module_dirs.push_back(vendor_base_dir + "/1.1");
21
22 module_dirs.push_back(base_dir);
23
24 struct utsname uts;
25 if (uname(&uts)) {
26 LOGERR("Unable to query kernel for version info\n");
27 }
28
29 std::string rls(uts.release);
30 std::vector<std::string> release = TWFunc::split_string(rls, '.', true);
31 module_dirs.push_back(base_dir + "/" + release[0] + "." + release[1]);
32
33 for (auto&& module_dir:module_dirs) {
34 Try_And_Load_Modules(module_dir);
35 }
36
37 for (auto&& module_dir:vendor_module_dirs) {
38 Try_And_Load_Modules(module_dir);
39 }
40
41 if (ven) {
42 LOGINFO("Checking mounted /vendor\n");
43 ven->Mount(true);
44 }
45
46 for (auto&& module_dir:vendor_module_dirs) {
47 Try_And_Load_Modules(module_dir);
48 }
49
50 if (ven)
51 ven->UnMount(false);
52
53 return true;
54}
55
56bool KernelModuleLoader::Try_And_Load_Modules(std::string module_dir) {
57 LOGINFO("Checking directory: %s\n", module_dir.c_str());
58 std::string dest_module_dir;
59 dest_module_dir = "/tmp" + module_dir;
60 TWFunc::Recursive_Mkdir(dest_module_dir);
61 Copy_Modules_To_Tmpfs(module_dir);
62 Write_Module_List(dest_module_dir);
63 Modprobe m({dest_module_dir}, "modules.load.twrp");
64 m.EnableVerbose(true);
65 m.LoadListedModules(false);
66 int modules_loaded = m.GetModuleCount();
67 LOGINFO("Modules Loaded: %d\n", modules_loaded);
68 return modules_loaded > 0 ? true : false;
69}
70
71bool KernelModuleLoader::Write_Module_List(std::string module_dir) {
72 DIR* d;
73 struct dirent* de;
74 std::vector<std::string> kernel_modules;
75 std::vector<std::string> kernel_modules_requested = TWFunc::split_string(EXPAND(TW_LOAD_VENDOR_MODULES), ' ', true);
76 d = opendir(module_dir.c_str());
77 if (d != nullptr) {
78 while ((de = readdir(d)) != nullptr) {
79 std::string kernel_module = de->d_name;
80 if (de->d_type == DT_REG) {
81 if (android::base::EndsWith(kernel_module, ".ko")) {
82 for (auto&& requested:kernel_modules_requested) {
83 if (kernel_module == requested) {
84 kernel_modules.push_back(kernel_module);
85 continue;
86 }
87 }
88 continue;
89 }
90 }
91 }
92 std::string module_file = module_dir + "/modules.load.twrp";
93 TWFunc::write_to_file(module_file, kernel_modules);
94 closedir(d);
95 }
96 return true;
97}
98
99bool KernelModuleLoader::Copy_Modules_To_Tmpfs(std::string module_dir) {
100 std::string ramdisk_dir = "/tmp" + module_dir;
101 DIR* d;
102 struct dirent* de;
103 d = opendir(module_dir.c_str());
104 if (d != nullptr) {
105 while ((de = readdir(d)) != nullptr) {
106 std::string kernel_module = de->d_name;
107 if (de->d_type == DT_REG) {
108 std::string src = module_dir + "/" + de->d_name;
109 std::string dest = ramdisk_dir + "/" + de->d_name;
110 if (TWFunc::copy_file(src, dest, 0700, false) != 0) {
111 return false;
112 }
113 }
114 }
115 closedir(d);
116 } else {
117 LOGINFO("Unable to open module directory: %s. Skipping\n", module_dir.c_str());
118 return false;
119 }
120 return true;
121}