system/core
修訂 | 60d83effb0b17b7a25ea440d2e2c21ae64cffed8 (tree) |
---|---|
時間 | 2017-12-26 19:43:34 |
作者 | Chih-Wei Huang <cwhuang@linu...> |
Commiter | Chih-Wei Huang |
init: add modprobe
We added the modprobe function to init before but it was dropped in
oreo-x86. Originally I planned to replace it by toybox's modprobe.
However, it doesn't work as expected. For example, the audio driver
is not loaded correctly in some Skylake devices.
To fix that, add back the modprobe function to init.
@@ -94,6 +94,7 @@ LOCAL_REQUIRED_MODULES := \ | ||
94 | 94 | |
95 | 95 | # Create symlinks. |
96 | 96 | LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \ |
97 | + ln -sf ../init $(TARGET_ROOT_OUT)/sbin/modprobe; \ | |
97 | 98 | ln -sf ../init $(TARGET_ROOT_OUT)/sbin/ueventd; \ |
98 | 99 | ln -sf ../init $(TARGET_ROOT_OUT)/sbin/watchdogd |
99 | 100 |
@@ -31,6 +31,7 @@ | ||
31 | 31 | #include <private/android_filesystem_config.h> |
32 | 32 | #include <selinux/android.h> |
33 | 33 | #include <selinux/selinux.h> |
34 | +#include <cutils/klog.h> | |
34 | 35 | #include <cutils/probe_module.h> |
35 | 36 | |
36 | 37 | #include "ueventd.h" |
@@ -521,5 +522,40 @@ DeviceHandler::DeviceHandler() | ||
521 | 522 | : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, |
522 | 523 | std::vector<Subsystem>{}, false) {} |
523 | 524 | |
525 | +int modprobe_main(int argc, char **argv) | |
526 | +{ | |
527 | + // We only accept requests from root user (kernel) | |
528 | + if (getuid()) return -EPERM; | |
529 | + | |
530 | + // Kernel will launch a user space program specified by | |
531 | + // /proc/sys/kernel/modprobe to load modules. | |
532 | + // No deferred loading in this case. | |
533 | + while (argc > 1 && (!strcmp(argv[1], "-q") || !strcmp(argv[1], "--"))) { | |
534 | + klog_set_level(KLOG_NOTICE_LEVEL); | |
535 | + argc--, argv++; | |
536 | + } | |
537 | + | |
538 | + if (argc < 2) { | |
539 | + // it is called without enough arguments | |
540 | + return -EINVAL; | |
541 | + } | |
542 | + | |
543 | + std::string options; | |
544 | + if (argc > 2) { | |
545 | + options = argv[2]; | |
546 | + for (int i = 3; i < argc; ++i) { | |
547 | + options += ' '; | |
548 | + options += argv[i]; | |
549 | + } | |
550 | + } | |
551 | + KLOG_NOTICE("modprobe", "%s %s", argv[1], options.c_str()); | |
552 | + | |
553 | + Uevent uevent = { .modalias = argv[1] }; | |
554 | + DeviceHandler dh; | |
555 | + dh.ReadModulesDescFiles(); | |
556 | + dh.OnColdBootDone(); | |
557 | + return dh.LoadModule(uevent) || dh.LoadModule(uevent.modalias) ? 0 : -1; | |
558 | +} | |
559 | + | |
524 | 560 | } // namespace init |
525 | 561 | } // namespace android |
@@ -995,6 +995,10 @@ static void InstallRebootSignalHandlers() { | ||
995 | 995 | } |
996 | 996 | |
997 | 997 | int main(int argc, char** argv) { |
998 | + if (!strcmp(basename(argv[0]), "modprobe")) { | |
999 | + return modprobe_main(argc, argv); | |
1000 | + } | |
1001 | + | |
998 | 1002 | if (!strcmp(basename(argv[0]), "ueventd")) { |
999 | 1003 | return ueventd_main(argc, argv); |
1000 | 1004 | } |
@@ -21,6 +21,7 @@ namespace android { | ||
21 | 21 | namespace init { |
22 | 22 | |
23 | 23 | int ueventd_main(int argc, char** argv); |
24 | +int modprobe_main(int argc, char **argv); | |
24 | 25 | |
25 | 26 | } // namespace init |
26 | 27 | } // namespace android |