From 38b4e0abdcae7e6da666e09759bbedd69e8c24bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Rasmussen?= Date: Sat, 15 Jun 2024 22:02:15 +0200 Subject: [PATCH] Add w1-therm gokrazy module --- cmd/w1-therm/README.md | 3 ++ cmd/w1-therm/main.go | 91 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 cmd/w1-therm/README.md create mode 100644 cmd/w1-therm/main.go diff --git a/cmd/w1-therm/README.md b/cmd/w1-therm/README.md new file mode 100644 index 0000000..d9084b5 --- /dev/null +++ b/cmd/w1-therm/README.md @@ -0,0 +1,3 @@ +This package provides support for using 1-wire DS18B20 with gokrazy! + +The package just loads the kernel module. diff --git a/cmd/w1-therm/main.go b/cmd/w1-therm/main.go new file mode 100644 index 0000000..295a4a7 --- /dev/null +++ b/cmd/w1-therm/main.go @@ -0,0 +1,91 @@ +// w1-therm is a gokrazy helper that loads 1-wire kernel modules on boot. +// +// Example: +// +// Include the w1-therm package in your gokr-packer command: +// % gokr-packer -update=yes \ +// github.com/gokrazy/breakglass \ +// git.joco.dk/snr/fermentord/cmd/w1-therm +package main + +import ( + "bytes" + "flag" + "fmt" + "log" + "os" + "path/filepath" + "strings" + + "golang.org/x/sys/unix" +) + +func logic() error { + flag.Parse() + + for _, mod := range []string{ + "kernel/drivers/w1/wire.ko", + "kernel/drivers/w1/masters/w1-gpio.ko", + "kernel/drivers/w1/slaves/w1-therm.ko", + } { + if err := loadModule(mod); err != nil && !os.IsNotExist(err) { + return err + } + } + + dev := "w1_bus_master1" + target, err := checkOneWireInterface(dev) + if err != nil { + log.Printf("Bluetooth interface %v not found.", target) + } else { + fmt.Printf("Bluetooth device %v: %v\n", dev, target) + } + + // gokrazy should not supervise this process even when manually started. + os.Exit(125) + return nil +} + +func checkOneWireInterface(device string) (string, error) { + name := fmt.Sprintf("/sys/bus/w1/devices/%v", device) + target, err := os.Readlink(name) + if err != nil { + return "", fmt.Errorf("OneWire bus master %v not found", device) + } + return target, nil +} + +func loadModule(mod string) error { + f, err := os.Open(filepath.Join("/lib/modules", release, mod)) + if err != nil { + return err + } + defer f.Close() + + if err := unix.FinitModule(int(f.Fd()), "", 0); err != nil { + if err != unix.EEXIST && + err != unix.EBUSY && + err != unix.ENODEV && + err != unix.ENOENT { + return fmt.Errorf("FinitModule(%v): %v", mod, err) + } + } + modname := strings.TrimSuffix(filepath.Base(mod), ".ko") + log.Printf("modprobe %v", modname) + return nil +} + +var release = func() string { + var uts unix.Utsname + if err := unix.Uname(&uts); err != nil { + fmt.Fprintf(os.Stderr, "minitrd: %v\n", err) + os.Exit(1) + } + return string(uts.Release[:bytes.IndexByte(uts.Release[:], 0)]) +}() + +func main() { + if err := logic(); err != nil { + log.Fatal(err) + } +}