null

Костылинг температуры AMD K15 на FreeBSD

Довольно часто возникает потребность получить температуру центрального процессора. На FreeBSD 9.0 я однажды пришел к решению, но затем вышла FreeBSD 9.1, времени обновиться не было, а надежды на нативную поддержку датчика температуры в AMD K15 были. Как следует из названия, в данной статье будет рассматриваться исключительно кривой метод получения температуры процессора, в силу отсутствия поддержки оной как таковой в текущей стабильной FreeBSD 9.1.

Рассмотрим способ получения температуры с определенной погрешностью (почему именно с погрешностью, станет понятно уже сейчас):

Для начала, скачаем модуль amdtemp из FreeBSD-HEAD:

# cd /usr/src/sys/dev/amdtemp/
# fetch https://raw.github.com/freebsd/freebsd-head/master/sys/dev/amdtemp/amdtemp.c

Далее, так как поддержка датчика температуры даже в head до сих пор не адекватная, предложу вот такой костыль:

--- amdtemp.c.orig      2013-02-16 14:24:14.030226619 +0400
+++ amdtemp.c   2013-02-16 14:25:54.031260014 +0400
@@ -324,6 +324,13 @@
        case 0x11:
        case 0x12:
        case 0x14:
+               /*
+                * There is only one sensor per package.
+                */
+               sc->sc_ntemps = 1;
+
+               sc->sc_gettemp = amdtemp_gettemp;
+               break;
        case 0x15:
                /*
                 * There is only one sensor per package.
@@ -331,6 +338,7 @@
                sc->sc_ntemps = 1;

                sc->sc_gettemp = amdtemp_gettemp;
+               sc->sc_offset = 20;
                break;
        }

Ну, собственно выполним сборку с некоторыми предварительными действиями (которые могут потребоваться, если мир ещё не собирался):

# cd /usr/src/sys/modules/amdtemp
# ln -s /usr/src/sys @
# ln -s /usr/src/sys/amd64/include machine
# ln -s /usr/src/sys/x68/include x86
# WERROR= NO_WERROR= export WERROR NO_WERROR
# make

Warning: Object directory not changed from original /usr/src/sys/modules/amdtemp
awk -f @/tools/makeobjops.awk @/kern/bus_if.m -h
awk -f @/tools/makeobjops.awk @/kern/device_if.m -h
awk -f @/tools/makeobjops.awk @/dev/pci/pci_if.m -h
gcc -m64 -fomit-frame-pointer -Wall -O3 -s -march=native -mfpmath=sse -O2 -s -march=native -m64 -fomit-frame-pointer -fno-strict-aliasing -D_KERNEL -

DKLD_MODULE -nostdinc   -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common  -fno-

omit-frame-pointer  -mno-sse -mcmodel=kernel -mno-red-zone -mno-mmx -msoft-float  -fno-asynchronous-unwind-tables -ffreestanding -fstack-protector -

std=iso9899:1999 -fstack-protector -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual  

-Wundef -Wno-pointer-sign -fformat-extensions  -Wmissing-include-dirs -fdiagnostics-show-option -c /usr/src/sys/modules/amdtemp/../../dev/amdtemp/amdtemp.c
/usr/src/sys/modules/amdtemp/../../dev/amdtemp/amdtemp.c:1: warning: SSE instruction set disabled, using 387 arithmetics
ld  -d -warn-common -r -d -o amdtemp.ko amdtemp.o
:> export_syms
awk -f /usr/src/sys/modules/amdtemp/../../conf/kmod_syms.awk amdtemp.ko  export_syms | xargs -J% objcopy % amdtemp.ko
objcopy --strip-debug amdtemp.ko

Проверим работу свежесобранного модуля. Для этого, выгрузим его, если он был загружен и загрузим новую версию:

# kldunload amdtemp
# kldload ./amdtemp.ko
# sysctl dev.amdtemp.0.core0.sensor0
dev.amdtemp.0.core0.sensor0: 43,1C

Ну и в варианте - один датчик на ядро (что примечательно, датчик-то всего единственный):

# sysctl -a | grep tempe
dev.cpu.0.temperature: 43,1C
dev.cpu.1.temperature: 43,1C
dev.cpu.2.temperature: 43,1C
dev.cpu.3.temperature: 43,1C
dev.cpu.4.temperature: 43,1C
dev.cpu.5.temperature: 43,1C
dev.cpu.6.temperature: 43,1C
dev.cpu.7.temperature: 43,1C

Если всё работает, можно выполнить замещение текущего модуля свежесобранным:

# cp /boot/kernel/amdtemp.ko /boot/kernel/amdtemp.ko.old
# cp amdtemp.ko /boot/kernel/amdtemp.ko

Ну и для загрузки модуля при старте системы, убедимся в наличии соответствующей строки в loader.conf:

# vi /boot/loader.conf
amdtemp_load="YES"

Теперь можно смело использовать примерное значение температуры. Будем надеяться, что разработчики довольно быстро сделают из костыля прочную подпорку и уже во FreeBSD10 мы увидим адекватную работу с датчиком температуры на AMD K15.

Примечание:
Значение dev.amdtemp.0.sensor_offset я выбирал экспериментально и не долго думая (чтобы показатели в системе совпадали с показателями BIOS).

korg

 

Коротко о себе

Работаю в компании Tune-IT, администрирую инфраструктуру компании и вычислительную сеть кафедры Вычислительной ТехникиСПбНИУ ИТМО.

Интересы: администрирование UNIX и UNIX-like систем и активного сетевого оборудования, написание shell- и perl-скриптов, изучение технологий глобальных сетей.
Люблю собирать GNU/Linux и FreeBSD, использовать тайлинговые оконные менеджеры и писать системный софт.