Hi,
I work on a device that has usb connectors and we used them to plugged usb wifi adapter.
The problem I have is that when I reboot the device and the usb wifi adapter is plugged, the kernel module is not loaded (rtl8192cu and is dependency in my case). I must unplugged and replugged the wifi adapter to make them load.
My custom device was started from nougat-x86 but we used it has a traditionnal Android device the most possible.
In devices.cpp file, in device_init() function, the handle_deferred_module_loading() is called after the coldboot and the deferred modules should be loaded in this function by iterating through deferred_module_loading_list. When this function function is called, the modules_aliases_map is always empty, so the deferred modules are never loaded. The kernel events are correctly received and they are added in the deferred_module_loading_list. Here a copy of this function:
static void handle_deferred_module_loading()
{
/* try to read the module alias mapping if map is empty
* if succeed, loading all the modules in the queue
*/
if (!list_empty(&modules_aliases_map)) {
struct listnode *node = NULL;
struct listnode *next = NULL;
struct module_alias_node *alias = NULL;
list_for_each_safe(node, next, &deferred_module_loading_list) {
alias = node_to_item(node, struct module_alias_node, list);
if (alias && alias->pattern) {
INFO("deferred loading of module for %s\n", alias->pattern);
load_module_by_device_modalias(alias->pattern, false);
free(alias->pattern);
list_remove(node);
free(alias);
}
}
}
}
The modules_aliases_map is empty because it is filled by reading "/system/lib/modules/4.8.11-android-x86_64+/modules.alias" file, this file cannot be read because the system partition is not mounted at this time, it is mounted later in fs action.
If I modify handle_deferred_module_loading() like below to wait booting before loading deferred modules, the kernel wifi modules are loaded correctly with some others modules that was not loaded before:
static void handle_deferred_module_loading()
{
pid_t pid = fork();
if (pid != 0) {
return;
}
if (list_empty(&modules_aliases_map)) {
read_modules_aliases();
read_modules_blacklist();
}
while (is_booting()) {
usleep(100000);
if (list_empty(&modules_aliases_map)) {
read_modules_aliases();
read_modules_blacklist();
}
}
/* try to read the module alias mapping if map is empty
* if succeed, loading all the modules in the queue
*/
if (!list_empty(&modules_aliases_map)) {
struct listnode *node = NULL;
struct listnode *next = NULL;
struct module_alias_node *alias = NULL;
list_for_each_safe(node, next, &deferred_module_loading_list) {
alias = node_to_item(node, struct module_alias_node, list);
if (alias && alias->pattern) {
INFO("deferred loading of module for %s\n", alias->pattern);
load_module_by_device_modalias(alias->pattern, false);
free(alias->pattern);
list_remove(node);
free(alias);
}
}
}
exit(0);
}
I tried to mount the system partition before "start ueventd" in init.rc with this line "mount ext4 /dev/block/mmcblk0p5 /system ro", but the partition didn't seem to be mounted.
I tried too to revert commit cfa5ded4b3bbec856a14544c06f3148046e7dcca to make ueventd.cpp and devices.cpp like in nougat-release branch, but that doesn't correct the problem.
Maybe I'm missing something.
In nougat-release branch, I didn't see reference to deferred modules, so I was wondering how in traditional Android device the deferred modules are loaded (if they are loaded)?
I would like to know if there is a better solution then modifying handle_deferred_module_loading() and if the change I made could break something?