So the truth is Linux fan control sucks especially on laptops. So lets try to control the CPU fan with our own little bash script why dont we
Now I need to preface this with the fact that I will make continual refinements to this script.
This is mainly for people with laptops or people with no EFI Fan Control Curve overrides
This is a crude working version based on my asus controller in my laptop. It will absolutely vary from PC to PC. Now this was my approach
So what you have to realize is that the temp controller despite rounding has the ability to display up to three decimal places most engineers will just round to the nearest whole number which the ASUS people did. So temperature is in the thousands when you read the file on my PC and that is why you need this weird temperature value. Now keep in mind you can no longer monitor the RPM of the fan because setting a PWM value puts the controller in manual mode and disables all the nice stuff. I really hate controllers that do this with linux systems. Anways I made my curve as you can see. Scroll to the middle to see my values. They start at 45 and max the fan at 65
before we start get lm-sensors so we can at least view what controllers we have
sudo apt install lm-sensors && sensors
sensors output:
iwlwifi-virtual-0
Adapter: Virtual device
temp1: +42.0°C
pch_skylake-virtual-0
Adapter: Virtual device
temp1: +61.5°C
acpitz-virtual-0
Adapter: Virtual device
temp1: +49.0°C (crit = +103.0°C)
asus-isa-0000
Adapter: ISA adapter
cpu_fan: -1 RPM
temp1: +49.0°C
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +50.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +46.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +48.0°C (high = +100.0°C, crit = +100.0°C)
Core 2: +45.0°C (high = +100.0°C, crit = +100.0°C)
Core 3: +47.0°C (high = +100.0°C, crit = +100.0°C)
heimdallr@WiFightWhenWeCanMakeLove:~$
Assigning PWM levels: CSV
TEXT :: "Eric K Ayers Reverse Engineering Fan Control (ASUS GL502VT-DS74",,,,"Notes:"
FORMAT :: "TEMP Celsius","PWM MAX","SCALE","PWM VAL",
0000,255,0,0,"DONT operate below freezing"
1000,255,0,0,
2000,255,0,0,
3000,255,0,0,
4000,255,0,0,
5000,255,0,0,
6000,255,0.35,89,"Fan min operating speed 35 %"
7000,255,0.35,89,
8000,255,0.35,89,
9000,255,0.35,89,
10000,255,0.35,89,
11000,255,0.35,89,
12000,255,0.35,89,
13000,255,0.35,89,
14000,255,0.35,89,
15000,255,0.35,89,
16000,255,0.35,89,
17000,255,0.35,89,
18000,255,0.35,89,
19000,255,0.35,89,
20000,255,0.35,89,
21000,255,0.35,89,
22000,255,0.35,89,
23000,255,0.35,89,
24000,255,0.35,89,
25000,255,0.35,89,
26000,255,0.35,89,
27000,255,0.35,89,
28000,255,0.35,89,
29000,255,0.35,89,
30000,255,0.35,89,
31000,255,0.35,89,
32000,255,0.35,89,
33000,255,0.35,89,
34000,255,0.35,89,
35000,255,0.35,89,
36000,255,0.35,89,
37000,255,0.35,89,
38000,255,0.35,89,
39000,255,0.35,89,
40000,255,0.35,89,
41000,255,0.35,89,
42000,255,0.35,89,
43000,255,0.35,89,
44000,255,0.35,89,
45000,255,35.00%,89,"Start Fan Curve Here"
46000,255,38.25%,97,
47000,255,41.50%,105,
48000,255,44.75%,114,
49000,255,48.00%,122,
50000,255,51.25%,130,
51000,255,54.50%,138,
52000,255,57.75%,147,
53000,255,61.00%,155,
54000,255,64.25%,163,
55000,255,67.50%,172,
56000,255,70.75%,180,
57000,255,74.00%,188,
58000,255,77.25%,196,
59000,255,80.50%,205,
60000,255,83.75%,213,
61000,255,87.00%,221,
62000,255,90.25%,230,
63000,255,93.50%,238,
64000,255,96.75%,246,
65000,255,100.00%000,255,"Max speed should occur at TJ Max"
66000,255,100.00%000,255,"CPU’s do not like temps above this"
67000,255,100.00%000,255,"Keep Maxed"
68000,255,100.00%000,255,
69000,255,100.00%000,255,
70000,255,100.00%000,255,
71000,255,100.00%000,255,
72000,255,100.00%000,255,
73000,255,100.00%000,255,
74000,255,100.00%000,255,
75000,255,100.00%000,255,
76000,255,100.00%000,255,
77000,255,100.00%000,255,
78000,255,100.00%000,255,
79000,255,100.00%000,255,
80000,255,100.00%000,255,
81000,255,100.00%000,255,
82000,255,100.00%000,255,
83000,255,100.00%000,255,
84000,255,100.00%000,255,
85000,255,100.00%000,255,
86000,255,100.00%000,255,
87000,255,100.00%000,255,
88000,255,100.00%000,255,
89000,255,100.00%000,255,
90000,255,100.00%000,255,
91000,255,100.00%000,255,
92000,255,100.00%000,255,
93000,255,100.00%000,255,
94000,255,100.00%000,255,
95000,255,100.00%000,255,
96000,255,100.00%000,255,
97000,255,100.00%000,255,
98000,255,100.00%000,255,
99000,255,100.00%000,255,
100000,255,100.00%000,255,"TRIG HALT"
Code: (Bash Script ran as sudo)
Pay close attention to my methodology in setting the paths as they constantly vary boot to boot
#!/bin/bash
# PURPOSE: Script runs fan control as per Eric's reverse engineering of the GL502VT Controllers
# EXPLOIT TYPE: SHIM (Drivers remain proprietary so we must override the system and poll ourselves)
# AUTHOR: Eric Ayers
# Assumes asus temperature from sensors command is as follows matches cat file with approprive DIV:
#
# coretemp-isa-0000
# Adapter: ISA adapter
# Package id 0: +47.0°C (high = +100.0°C, crit = +100.0°C) << Temp of concern
# Core 0: +47.0°C (high = +100.0°C, crit = +100.0°C)
# Core 1: +46.0°C (high = +100.0°C, crit = +100.0°C)
# Core 2: +43.0°C (high = +100.0°C, crit = +100.0°C)
# Core 3: +45.0°C (high = +100.0°C, crit = +100.0°C)
#
#
if [ $EUID -ne 0 ]; then
echo "Eric mandates this script be run as root"
exit 1
fi
echo "SCRIPT STARTED AT $(date)"
echo "=========================================================="
sensors
pathPWM1=$(sudo find /sys/devices/platform/asus-nb-wmi/ -name pwm1)
pathT1=$(sudo find /sys/devices/platform/asus-nb-wmi/ -name temp1_input)
echo "Information for user above :: For monitoring purposes only"
echo "=========================================================="
echo ''
echo ''
stop=0
while true;
do
sleep 0.1
currTemp="$(cat $pathT1)"
tempThresFreeze=5000
tempThres45=45000
tempThres46=46000
tempThres47=47000
tempThres48=48000
tempThres49=49000
tempThres50=50000
tempThres51=51000
tempThres52=52000
tempThres53=53000
tempThres54=54000
tempThres55=55000
tempThres56=56000
tempThres57=57000
tempThres58=58000
tempThres59=59000
tempThres60=60000
tempThres61=61000
tempThres62=62000
tempThres63=63000
tempThres64=64000
tempThres65=65000
tempThresHalt=105000
if [ $currTemp -lt $tempThresFreeze ]
then
sudo echo "0" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres45 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres46 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres47 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres48 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres49 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres50 ]
then
sudo echo "130" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres51 ]
then
sudo echo "138" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres52 ]
then
sudo echo "147" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres53 ]
then
sudo echo "155" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres54 ]
then
sudo echo "163" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres55 ]
then
sudo echo "172" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres56 ]
then
sudo echo "180" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres57 ]
then
sudo echo "188" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres58 ]
then
sudo echo "196" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres59 ]
then
sudo echo "205" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres60 ]
then
sudo echo "213" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres61 ]
then
sudo echo "221" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres62 ]
then
sudo echo "230" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres63 ]
then
sudo echo "238" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres64 ]
then
sudo echo "246" >> $pathPWM1
fi
if [ $currTemp -eq $tempThres65 ]
then
sudo echo "255" >> $pathPWM1
fi
if [ $currTemp -gt $tempThres65 ]
then
sudo echo "255" >> $pathPWM1
fi
echo "Information for user below :: States temp and fan speed"
echo "CORE TEMP"
echo "$(cat $pathT1)"
echo "FAN PWM"
echo "$(cat $pathPWM1)"
done
This was my methodology. it could obviously be cleaned up but feel free to build on the idea. Its in my GIT but I think just posting it here should suffice.
This should work for most devices but you will have to do a bit of digging in your own systems
dependencies:
lm-sensors
Lets us all share ideas below and ways we can improve linux fan control! I know it can be done and we need to focus on making something robust that isnt based on the old fancontrol script wrapper. Its really not that great. It used to be but now things have changed!
Next Steps
Output in screen
Log Screen output
Automate – Create System D Service
Create interface for DC and PWM
Create GUI
Allow for hysterisis
Reverse Engineer NVIDIA SMI to expose laptop GPU fan control. (Its usually stuffed away in dev/null and unexposed)