embd/detect.go

140 lines
3.5 KiB
Go
Raw Normal View History

2014-03-23 02:51:22 +01:00
// Host detection.
2014-03-02 20:21:23 +01:00
package embd
import (
"fmt"
"io/ioutil"
"os/exec"
"strconv"
"strings"
)
2014-03-23 02:51:22 +01:00
// The Host type represents all the supported host types.
2014-03-23 22:34:58 +01:00
type Host string
const (
2014-03-23 02:51:22 +01:00
// HostNull reprents a null host.
2014-03-23 22:34:58 +01:00
HostNull Host = ""
2014-03-23 02:51:22 +01:00
// HostRPi represents the RaspberryPi.
2014-03-23 22:34:58 +01:00
HostRPi = "Raspberry Pi"
2014-03-23 02:51:22 +01:00
// HostBBB represents the BeagleBone Black.
2014-03-23 22:34:58 +01:00
HostBBB = "BeagleBone Black"
// HostGalileo represents the Intel Galileo board.
HostGalileo = "Intel Galileo"
2014-03-23 02:51:22 +01:00
// HostCubieTruck represents the Cubie Truck.
2014-03-23 22:34:58 +01:00
HostCubieTruck = "CubieTruck"
2014-03-23 02:51:22 +01:00
2014-05-21 23:26:50 +02:00
// HostRadxa represents the Radxa board.
2014-03-23 22:34:58 +01:00
HostRadxa = "Radxa"
2016-08-27 08:00:39 +02:00
// HostCHIP represents the NextThing C.H.I.P.
HostCHIP = "CHIP"
)
func execOutput(name string, arg ...string) (output string, err error) {
var out []byte
if out, err = exec.Command(name, arg...).Output(); err != nil {
return
}
2014-03-02 15:09:04 +01:00
output = strings.TrimSpace(string(out))
return
}
func parseVersion(str string) (major, minor, patch int, err error) {
versionNumber := strings.Split(str, "-")
parts := strings.Split(versionNumber[0], ".")
len := len(parts)
if major, err = strconv.Atoi(parts[0]); err != nil {
return 0, 0, 0, err
}
if minor, err = strconv.Atoi(parts[1]); err != nil {
return 0, 0, 0, err
}
if len > 2 {
part := parts[2]
part = strings.TrimSuffix(part, "+")
if patch, err = strconv.Atoi(part); err != nil {
return 0, 0, 0, err
}
}
return major, minor, patch, err
}
func kernelVersion() (major, minor, patch int, err error) {
output, err := execOutput("uname", "-r")
if err != nil {
return 0, 0, 0, err
}
return parseVersion(output)
}
2015-01-13 23:15:25 +01:00
func cpuInfo() (model, hardware string, revision int, err error) {
output, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
2015-01-13 23:15:25 +01:00
return "", "", 0, err
}
2015-01-13 23:15:25 +01:00
for _, line := range strings.Split(string(output), "\n") {
fields := strings.Split(line, ":")
if len(fields) < 1 {
continue
}
2015-01-15 02:06:01 +01:00
switch {
case strings.HasPrefix(fields[0], "Revision"):
revs := strings.TrimSpace(fields[1])
2015-02-17 12:34:09 +01:00
rev, err := strconv.ParseInt(revs, 16, 32)
2015-01-13 23:15:25 +01:00
if err != nil {
continue
}
revision = int(rev)
2015-01-15 02:06:01 +01:00
case strings.HasPrefix(fields[0], "Hardware"):
2016-08-27 08:00:39 +02:00
hardware = strings.TrimSpace(fields[1])
2015-01-15 02:06:01 +01:00
case strings.HasPrefix(fields[0], "model name"):
2015-01-13 23:15:25 +01:00
model = fields[1]
}
}
2015-01-13 23:15:25 +01:00
return model, hardware, revision, nil
}
2014-03-23 02:51:22 +01:00
// DetectHost returns the detected host and its revision number.
2015-01-13 23:15:25 +01:00
func DetectHost() (host Host, rev int, err error) {
major, minor, patch, err := kernelVersion()
if err != nil {
2014-03-02 20:21:23 +01:00
return HostNull, 0, err
}
if major < 3 || (major == 3 && minor < 8) {
2016-08-27 08:00:39 +02:00
return HostNull, 0, fmt.Errorf(
"embd: linux kernel versions lower than 3.8 are not supported, "+
"you have %v.%v.%v", major, minor, patch)
}
2015-01-13 23:15:25 +01:00
model, hardware, rev, err := cpuInfo()
if err != nil {
2014-03-02 20:21:23 +01:00
return HostNull, 0, err
}
2015-01-13 23:15:25 +01:00
switch {
case strings.Contains(model, "ARMv7") && (strings.Contains(hardware, "AM33XX") || strings.Contains(hardware, "AM335X")):
return HostBBB, rev, nil
case strings.Contains(hardware, "BCM2708") || strings.Contains(hardware, "BCM2709") || strings.Contains(hardware, "BCM2835"):
2015-01-13 23:15:25 +01:00
return HostRPi, rev, nil
2016-08-27 08:00:39 +02:00
case hardware == "Allwinner sun4i/sun5i Families":
if major < 4 || (major == 4 && minor < 4) {
return HostNull, 0, fmt.Errorf(
"embd: linux kernel version 4.4+ required, you have %v.%v",
major, minor)
}
return HostCHIP, rev, nil
default:
2015-02-17 12:34:09 +01:00
return HostNull, 0, fmt.Errorf(`embd: your host "%v:%v" is not supported at this moment. request support at https://github.com/kidoman/embd/issues`, host, model)
}
}