aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-27 18:54:05 +0900
committerOphestra <cat@gensokyo.uk>2026-05-27 18:54:05 +0900
commita2cc28f53c132d12eec9e8ef7f78c8f1bc49169b (patch)
tree48749a02bb6d5eb4cf0a977c171d9c6e99c51016 /cmd
parent598c7aa30fa2fb8f0f21666ea7986521bd064327 (diff)
cmd/earlyinit: load device drivers
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/earlyinit/main.go1
-rw-r--r--cmd/earlyinit/modprobe.go73
2 files changed, 74 insertions, 0 deletions
diff --git a/cmd/earlyinit/main.go b/cmd/earlyinit/main.go
index b5e8bcde..00c4807a 100644
--- a/cmd/earlyinit/main.go
+++ b/cmd/earlyinit/main.go
@@ -242,5 +242,6 @@ func main() {
[]byte("/system/lib/firmware"),
0,
))
+ go dispatchModprobe(ctx, s)
}
diff --git a/cmd/earlyinit/modprobe.go b/cmd/earlyinit/modprobe.go
new file mode 100644
index 00000000..5a9868d4
--- /dev/null
+++ b/cmd/earlyinit/modprobe.go
@@ -0,0 +1,73 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "log"
+ "os/exec"
+ "strings"
+
+ "hakurei.app/internal/kobject"
+ "hakurei.app/internal/report"
+ "hakurei.app/internal/uevent"
+)
+
+// ModprobeError describes an unsuccessful modprobe invocation.
+type ModprobeError struct {
+ ModAlias string `json:"modalias"`
+ Stdout string `json:"stdout"`
+ Stderr string `json:"stderr"`
+ ExitCode int `json:"exit_code"`
+}
+
+var _ report.RepresentableError = ModprobeError{}
+
+func (ModprobeError) Representable() {}
+func (e ModprobeError) Error() string {
+ return fmt.Sprintf(
+ "modprobe exit status %d: %s",
+ e.ExitCode, strings.TrimSpace(e.Stderr),
+ )
+}
+
+// dispatchModprobe invokes modprobe for [uevent.KOBJ_ADD] events raising new
+// MODALIAS strings.
+func dispatchModprobe(
+ ctx context.Context,
+ s *kobject.State,
+) {
+ aliases := make(chan string, 1<<8)
+ go func() {
+ defer close(aliases)
+ s.Range(ctx, func(o *kobject.Object, act uevent.KobjectAction) bool {
+ if act == uevent.KOBJ_ADD && o.Driver == "" && o.ModAlias != "" {
+ aliases <- o.ModAlias
+ }
+ return true
+ })
+ }()
+
+ for alias := range aliases {
+ stdout, err := exec.Command("/system/sbin/modprobe", alias).Output()
+ if err == nil {
+ if len(stdout) > 0 {
+ log.Println(string(stdout))
+ }
+ continue
+ }
+
+ var exitError *exec.ExitError
+ if !errors.As(err, &exitError) || exitError == nil {
+ r.Dispatch(report.Degraded, "invoke modprobe", err)
+ continue
+ }
+
+ r.Dispatch(report.Trivial, "load device driver", ModprobeError{
+ ModAlias: alias,
+ Stdout: string(stdout),
+ Stderr: string(exitError.Stderr),
+ ExitCode: exitError.ExitCode(),
+ })
+ }
+}