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