CPU 温度读取
  最近搞cpu 内核温度,总算是有点成就了。需要参考的文献有:
PCI Local Bus Specification
AMD相关:
BIOS and Kernel Developer's Guide for AMD Athlon 64 and AMD Opteron Processors
BIOS and Kernel Dveloper's Guide (BKDG) For AMD Family 10h Processor
BIOS and Kernel Dveloper's Guide ( For AMD NPT Family 0Fh Processor
AMD CPUID Specification
...
Intel相关:
Intel A3
...
 
Core Temp软件相关说明:
 
Intel and AMD recently published detailed, public information about the "DTS" (Digital Thermal Sensor), which provides much higher accuracy and more relevant temperature reading than the standard thermal diode sensors do
Core Temp lets you monitor Intel "Core Duo", "Core Solo" (Yonah), "Core 2 Duo", "Core 2 Extreme", "Core 2 Quad", " Pentium E2000" series, "Celeron 400/500" series (Allendale, Conroe, Merom, Kentsfield, Conroe-L respectively), "Xeon 3000/3200/5100/5300" series (Woodcrest, Clovertown respectively) and all AMD K8 (AMD64) and K10 (Phenom, Opteron) series die temperature.
The temperature readings are very accurate as the data is collected from a Digital Thermal Sensor (or DTS) which is located in each individual processing core, near the ho
ttest part. This sensor is digital, which means it doesn't rely on an external circuit located on the motherboard to report temperature, its value is stored in a special register in the processor so any software can access and read it. This eliminates any inaccuracy that can be caused by external motherboard circuits and sensors and then different types of programs trying to read those sensors.
 
This is how the program works:
Intel defines a certain Tjunction temperature for the processor. In the case of Yonah it is 85C° or 100C°. First of all the program reads from a Model Specific Register (or MSR), and detects the Tjunction temperature. A different MSR contains the temperature data, this data is represented as Delta in C° between current temperature and Tjunction.
So the actual temperature is calculated like this 'Core Temp = Tjunction - Delta'
The size of the data field is 7 bits. This means a Delta of 0 - 127C° can be reported in the
ory. But from preliminary tests, the reported temperature doesn't go below 0C°, no matter what kind of cooling was used.
AMD chips report the temperature by a special register in the CPU's NB. Core Temp reads that register and uses a formula provided by AMD to calculate the current temperature.
The formula for the K8 is: 'Core Temp = Value - 49'.
The formula for the K10* is: 'CPU Temp** = Value / 8'.
The sensor in AMD CPUs can report temperatures between -49C and 206C.
*K10 = Phenom (Agena), Opteron (Barcelona). The K10 reports a temperature value that is relative to a certain predefined value, it doesn't report the actual processor temperature! So take that into consideration.
**CPU Temp is because the Phenom/Opteron (K10) have only one sensor per package, meaning there is only one reading per processor.
 
      刚接手这个的时候,可以说是一头雾水,完全不知道该怎么搞。首先接触到的就是hwmonitorcore temp 大学生就业难的原因这两款软件,同时看到上面core temp 的说明,可以说知道一点东西了。可以它其中说的amd是在nb的特殊寄存器中,这个到底是什么寄存器了。当时没有去看amd的一些文档,就直接看是逆向hwmonitorcore temp软件,通过动态和静态分析了这两个软件的驱动和应用程序,只能说知道其中他们是在不断的进行端口读写分别是0XCF80xCFC这两个端口。你可以上网查这两个端口是干什么的,之前由于我左右龙之宇内至尊pci 配置空间读取问题,所以对这个两个端口不是很陌生。pci 配置空间相关说明就要看pci 规范了,说的很详细。
要是.......就造句一年级  之后,看是学习cpu 手册了,因为我的机器是amd的,所以就先或许amd的温度吧。看了很多,刚开始还不知道什么事,慢慢的,就知道其中有一个thermal status register,这个寄存器中保存了当前核心温度。这个寄存器就是core temp所说的nb中的特殊寄存器。那么这个寄存器是如何读取的呢,看来了amd bios and kernel ‘guid 。。。中我们知道这个基础器是Fn3 E4.其中会说的pci配置空间。Fn3 是指读取pci配置空间时要用的到fun 3,而E4就是对应于这个fun 3的偏移为E4。读取这个32bit数据。然后我们就可以解析获取原始的当前温度了。
    由于amd对这个寄存器有过修改,因而在解析的时候我们需要知道这是那种型号的。我们看到core temp是能获取k8k10 amd内核温度计算公式。那么是什么是k8什么是k10呢。
      使用cpuid eax = 0x1)得到的eax中的familymodel,和stepping进行判断。
      The Family is an 8-bit value and is defined as: Family[7:0] = ({0000b,BaseFamily[3:0]} + ExtendedFamily[7:0]). For example, if BaseFamily[3:0] = 0Fh and ExtendedFamily[7:0] = 01h, then Family[7:0] = 10h. If BaseFamily[3:0] is less than 0Fh then ExtendedFamily[7:0] is reserved and Family is equal to BaseFamily[3:0].
      Model is an 8-bit value and is defined as: Model[7:0] = {ExtendedModel[3:0],BaseModel[3:0]}. For example,
if ExtendedModel[3:0] = 0Eh and BaseModel[3:0] = 08h, then Model[7:0] = E8h. If BaseFamily[3:0] is less
than 0Fh then ExtendedModel[3:0] is reserved and Model is equal to BaseModel[3:0].
 
      如果family > 0xF,那么就是k10.
      而对于k8的是怎么判断的呢,北京疫情什么时候解除family 0xF,而除了
        /* feature available since SH-C0, exclude older revisions */
               (((model == 4) && (stepping == 0)) ||
                    ((model == 5) && (stepping <= 1)))
 
    这些类型的cpu都可以算是k8的。
    如何读pci,应该也清楚了,就是通过0xcf80xcfc进行读取,但是需要busno,devno,funnoreg,这样才能读取到指定的数据。但是我们并不知道busnodevno缉魂电影解析啊。而funno就是0x3,而reg就是E4A4.
    首先我们根据cpu类型获取到时k8还是k10.这两种类型的cpu对应的deviceid是不同。k8 0x1103k101203.通过这两个数据以及baseclass,就可以在遍历过程中得到busno
devno了。后面就是对数据进行解析了。哦。。。还有一点就是在看了bios and kernel书之后,按照它的方式我们发现需要有个diodeoffset来进行校正。而temp23-14bit)/(23-16bit),diodeOffset的值也是不同的。不管哪种,得到的数据总是有点问题。郁闷了。你想core temp算法确实是按照上面的方式进行的。currtemp =rawtemp/4 - 49 + basetemp;后来,偶然机会发现在linux的内核中有一个k8temp.c这个东西,这个就是获取k8的温度。认真的学习了代码。发现可以正确的获取内核温度。他的方法并不是上面先除4在减49的。而是用上面coretemp说明中的value -49进行的。这个value就是读取的(23-16bit)数据,这个让我有点奇怪,amd温度中说了,天府currenttemp添加为(23-14bit)。真是搞不清楚。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。