Linux hwmon子系统分析1(基于Linux6.6)---系统框架介绍
一、Linux hwmon
子系统概述
hwmon
(硬件监控)是 Linux 内核中的一个子系统,用于提供对硬件设备(如温度传感器、电压监测、风扇速度等)的监控支持。该子系统允许用户通过标准的接口读取和控制硬件的状态,尤其是在温度、电压、风扇转速等方面。hwmon
子系统提供了一个统一的方式来访问这些硬件监测信息,常用于系统健康监测、节能、超频等场景。
主要功能
- 温度监控:监测 CPU、GPU、内存和其他组件的温度。
- 电压监控:监控系统中不同部件的电压。
- 风扇监控:读取风扇的转速信息。
- 功率消耗:监测系统或组件的功率使用情况。
- 其他传感器数据:如电池状态、负载等。
工作原理
hwmon
子系统通过内核驱动暴露硬件监控设备的信息。这些硬件设备通常是传感器或监控芯片,它们通过总线(如 I2C、SMBus、SPI 等)与主板或其他硬件连接。
硬件监控设备的结构
每个硬件监控设备都有一组属性,这些属性通常包括以下几类:
- 温度传感器:温度的读数,单位通常为摄氏度(°C)。
- 电压传感器:系统或组件的电压读数,单位通常为伏特(V)。
- 风扇传感器:风扇的转速,单位通常为转每分钟(RPM)。
- 功率传感器:组件的功率使用情况,单位通常为瓦特(W)。
这些传感器通过 hwmon
接口对外暴露数据,通常以 sysfs
接口的形式供用户空间程序访问。
配置和启用 hwmon
hwmon
的驱动程序通常会自动加载,但有时你需要手动启用它,或者加载某些特定硬件的驱动模块。加载某个硬件监控驱动后,相关设备的信息会被暴露到 /sys/class/hwmon/
目录下。
常见的硬件监控驱动
- Intel CPU 温度:
coretemp
驱动用于 Intel 处理器。 - AMD CPU 温度:
k10temp
驱动用于 AMD 处理器。 - NVIDIA GPU 温度:通过
nvidia-smi
工具或专用驱动获取。 - 主板传感器:例如通过
lm_sensors
获取传感器信息。
在大多数 Linux 发行版中,lm_sensors
软件包被用于检测并配置硬件传感器。通过 sensors
命令,用户可以查看从硬件传感器读取到的各种数据。
二、sysfs相关简要说明
在之前的文章中,已经介绍了sysfs相关的框架,此处主要说明sysfs文件系统下文件访问的框架,如下图所示:
- 应用程序通过系统调用接口调用vfs接口,而vfs则调用sysfs文件系统注册的文件操作接口,如下图所示,主要为sysfs_open_file、sysfs_read_file、sysfs_write_file、sysfs_poll、generic_file_llseek、sysfs_release接口。
- 针对调用device_register接口注册的struct device类型的变量,其struct kobj_type类型变量为device_ktype,其操作接口指针为dev_sysfs_ops,主要用于读取和写入操作(dev_attr_show对应为读取、dev_attr_store为写操作),而在dev_attr_show、dev_attr_store中,则会通过文件的属性变量,获取到具体的store和show接口。而关于sysfs相关的数据结构间的关联,可参考我之前写的sysfs专栏和设备驱动模型专栏相关的文档。
- 另外sysfs是支持poll接口的,即sysfs_poll接口。若属性文件需要支持poll接口,则调用函数sysfs_notify即可。
而hwmon子系统则主要借助sysfs、设备驱动模块中设备创建和注册以及属性创建,完成属性的创建,从而完成在sysfs中创建文件,供应用程序对硬件监视器芯片的访问(如在sysfs中完成对温度传感器当前温度的读取等)
三、Linux hwmon子系统架构
在hwmon子系统中,主要即借助设备驱动模型中设备的注册以及设备属性的创建,即可针对一个硬件监视器芯片创建多个属性文件,从而应用程序即可在/sys目录下实现对文件的访问。
如下图所示,通过访问/sys/class/hwmon/hwmon0目录下的属性文件,即可对相关属性进行访问,此处主要查看当前温度内容。
hwmon子系统主要提供了接口hwmon_attr_show、hwmon_attr_store,同时抽象了针对温度芯片、风扇芯片、电源芯片等硬件监控芯片相关参数的支持,即温度芯片、风扇芯片、电源芯片等硬件监控芯片相关参数的访问接口,均会在接口hwmon_attr_show、hwmon_attr_store中被统一调用,而温度芯片、风扇芯片、电源芯片等硬件监控芯片只需要实现hwmon_ops类型函数指针即可。调用关系如下所示,其中,HWMON子系统层则为hwmon子层抽象的部分,而最下层则由具体的hwmon 设备驱动实现即可。
Linux hwmon
(硬件监控)子系统的实现流程涉及硬件驱动程序的编写、内核与硬件传感器之间的数据交互、以及通过 sysfs
文件系统向用户空间暴露硬件监控数据。具体的实现流程可以分为以下几个步骤:
1. 硬件检测与驱动加载
硬件监控传感器通常由专门的硬件芯片(如 CPU 温度传感器、主板传感器等)提供。每种硬件监控芯片通常都有相应的内核驱动来支持它。在 Linux 内核中,硬件监控通常通过特定的驱动模块(如 coretemp
、w83627ehf
等)来加载。
驱动加载的步骤:
- 硬件检测:内核通过硬件信息(如 PCI、ISA 总线设备)或通过自动检测工具(如
sensors-detect
)来发现硬件监控设备。 - 驱动注册:相应的硬件监控驱动被加载到内核中。该驱动通常会注册到
hwmon
子系统,使用hwmon_device_register()
函数进行注册。
int hwmon_device_register(struct device *dev);
驱动程序会通过 hwmon_device_register
向 hwmon
子系统注册硬件传感器设备。
2. 硬件传感器数据读取
硬件监控设备通常暴露多个传感器数据,例如温度、电压、风扇转速等。驱动程序会通过硬件接口(例如读取 I/O 寄存器或使用 SMBus)来获取这些传感器的数据。
- 设备的
read
操作:驱动程序实现特定的读取函数来读取硬件监控传感器的数据。这些数据会被定期更新,并通过sysfs
接口提供给用户空间程序。
例如,温度传感器的读取函数可能类似于下面的代码:
static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
int temp = read_temperature_from_sensor();
return snprintf(buf, PAGE_SIZE, "%d\n", temp);
}
3. sysfs 接口暴露数据
在 hwmon
子系统中,数据通过 sysfs
文件系统暴露给用户空间。每个硬件监控设备通常会在 /sys/class/hwmon/
目录下创建一个子目录。这个子目录包含与传感器相关的文件,如温度、电压、风扇转速等。
- sysfs 文件:每个传感器的数据通常会有一个对应的文件(如
temp1_input
、in1_input
)。用户可以通过读取这些文件来获取硬件监控数据。
例如,温度传感器的数据可能通过 /sys/class/hwmon/hwmon0/temp1_input
文件暴露,风扇转速通过 /sys/class/hwmon/hwmon0/fan1_input
文件暴露。
4. 硬件监控数据更新
硬件监控驱动程序会定期从硬件传感器读取数据,并通过 hwmon
子系统更新这些数据。对于动态变化的传感器(如温度、风扇转速等),驱动程序可能会周期性地更新这些数值。
-
定时器/中断:驱动程序可能会使用定时器或硬件中断来定期更新传感器数据。例如,CPU 温度监控可能每 1 秒钟更新一次。
-
读取函数:每次用户空间请求数据时(例如通过读取
sysfs
文件),驱动会再次从硬件传感器读取当前值并返回。
5. 数据暴露与访问
当数据被成功地注册到 hwmon
子系统后,用户空间程序可以通过访问 sysfs
文件系统来获取硬件监控数据。常用的硬件监控工具(如 lm_sensors
)会自动扫描 /sys/class/hwmon/
下的硬件监控设备,并提供易于用户使用的接口。
用户可以使用 cat
命令直接读取硬件监控数据:
cat /sys/class/hwmon/hwmon0/temp1_input # 获取温度
cat /sys/class/hwmon/hwmon0/fan1_input # 获取风扇转速
6. 错误处理与边界条件
驱动程序还需要处理一些边界条件和错误。例如,在读取硬件传感器时,可能会出现以下情况:
- 传感器故障:如果硬件传感器无法正常读取,驱动程序应该返回错误代码或提供合理的默认值。
- 数据溢出:如果传感器数据超出其定义的范围(如温度超过最大允许值),驱动程序应当适当处理并报告错误。
7. 卸载驱动与清理
当硬件设备不再需要时,内核需要卸载相应的驱动程序并清理相关资源。这包括注销 hwmon
设备、释放内存、移除 sysfs
文件等。
void hwmon_device_unregister(struct device *dev);
8.总结:hwmon
子系统的实现流程
- 硬件检测:通过总线设备检测硬件监控设备,加载相关驱动。
- 驱动注册:驱动使用
hwmon_device_register()
注册硬件监控设备,并暴露传感器数据。 - 数据读取:驱动通过硬件接口读取传感器数据,并将数据暴露到
sysfs
文件系统中。 - 用户空间访问:用户空间通过读取
/sys/class/hwmon/
下的文件来获取传感器数据。 - 更新与维护:硬件驱动程序周期性地更新传感器数据,并通过定时器或中断触发。
- 清理资源:驱动卸载时,清理资源并注销设备。