Debian on laptop

From YobiWiki
Revision as of 01:44, 26 February 2008 by <bdi>PhilippeTeuwen</bdi> (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Converted with HTML::WikiConverter::MediaWiki from my old phpwiki site


How to tune a laptop to save battery life and to handle on-the-go configuration?

ACPI

  • apt-get install acpi acpid acpitool

Adaptative CPU speed (on Pentium Mobile Centrino) with 2.6 kernels

Choose one of these methods:

With laptop_mode (preferred as it does more than CPU scaling and does not run as daemon)

By default, conservative governor when on battery and performance governor when on AC

  • add to /etc/modules:
    • cpufreq_conservative
    • cpufreq_ondemand
    • speedstep_centrino
  • apt-get install laptop-mode-tools
  • /etc/laptop-mode/laptop-mode.conf: set CONTROL_CPU_FREQUENCY=1
  • Note that the script /usr/sbin/laptop_mode contains an error line 606: (at least version 1.11-1, a bugreport exists)
    • Replace THIS_GOVERNOR by THIS_CPU_GOVERNOR
  • Another bug: when on verbose, it empties the log file /var/log/acpid!
  • Some broken ACPI don't send AC events, monitor /var/log/acpid while (un)plugging the power and see if there are calls to lm_ac_adapter.sh or only to lm_battery.sh.
    If only to lm_battery.sh, then set ACPI_WITHOUT_AC_EVENTS=1 in laptop-mode.conf

With powernowd:

By default, aggressive switch to highest freq when load > 80% and progressive switch to lowest freq when load < 20%

  • apt-get install powernowd
  • add to /etc/modules:
    • cpufreq_userspace
    • speedstep_centrino

Manually:

If you want to use always the same governor, then this is the easiest:

  • apt-get install sysfsutils
  • add to /etc/modules the desired scaling governor: cpufreq_(powersave/conservative/ondemand)
  • edit /etc/sysfs.conf
    • devices/system/cpu/cpu0/cpufreq/scaling_governor=ondemand
  • for some stats:
    • modprobe cpufreq_stats
    • cat /sys/devices/system/cpu/cpu*/cpufreq/stats/*
      and you will see how much time was spent on each freq and how many switches occured.

cf also package cpufreqd especially for kernels 2.4

Networking

  • apt-get install ifscheme ifplugd
    • when using ifplugd to monitor an interface, this interface should not be "auto" in /etc/network/interfaces

Some problems:

  • At boot time, ifscheme is called between ifupdown_clean and ifupdown, so /etc/default/ifscheme BOOT_SCHEME=my_scheme does not work, hack: put this instead in the /etc/default/ifscheme file:
    • echo my_scheme > /etc/network/run/scheme
  • interface seems up but left unconfigured at boot time -> if the cable is already plugged ifplugd does not configure the interface
  • after a suspend-to-ram, ifplugd does not configure the interface

Wireless:

  • waproamd?

Suspend-to-ram

  • first, try:
    • sync
    • echo "mem" >> /proc/power/state
  • ongoing...

Suspend-to-disk

  • first, try:
    • sync
    • echo "disk" >> /proc/power/state
  • ongoing...

HD

spin down:

  • laptop-mode-tools (preferred)
    • apt-get install laptop-mode-tools hdparm
    • seems to work even with SATA and seems more efficient than noflushd (and can handle CPU scaling and other tweaks as well)
  • noflushd
    • does not work with SATA controller
    • requires a better sata passthrough for hdparm

smartmon:

  • smartmon with SATA?
  • cf also HardDrives

Hotkeys

  • apt-get install hotkey-setup
  • Use the keys via the Gnome preferences->Keyboard shortcuts (gnome-keybinding-properties)
  • You can try setup the keys yourself with e.g. lineak, cf LaptopDell

Screen

If you have a Radeon video card, it does not turn off when you close your LID and if you have e.g. a Dell D610 with an Intel 915GM card, id does turn off but doesn't turn on anymore when opened, even worse!!
Here is a script backlight_install.sh to solve both problems:

 #!/bin/bash
 
 # Version: 0.04
 # Copyright:
 #    2006 Philippe Teuwen <phil-debian _at_ teuwen.org>
 # License:
 #    GPL
 # Usage:
 #    Install radeontool if you have an ATI Radeon  video card
 #    or install vbetool if you have an Intel 915GM video card
 #    To install this script, run it without params
 
 # For printing extra messages -> /var/log/acpid
 DEBUG=false
 
 # Supported card_handlers: radeon/vbepost/vbestate
 # You are not supposed to change this yourself but rather run this script
 # without parameters for a proper installation!!
 card_handler=undef
 
 ###########################################################################
 # read permanent states
 lid_state="unknown"
 
 function read_lid_state() {
     case $(cat /proc/acpi/button/lid/LID/state) in
         *open)
             lid_state=open
         ;;
         *closed)
             lid_state=closed
         ;;
     esac
 }
 
 function check_installed() {
     tool=$1
     if which $tool >/dev/null; then
         echo "Good! $tool found."
     else
         echo "Please install $tool and run this script again"
         exit 1
     fi
 }
 
 function install() {
     EVENT_NAME=backlight_handler
     echo "Installation of this script..."
     echo -n "Which card handler do you want to use? [radeon/vbepost/vbestate/none]: "
     #TODO: detect radeon automatically?
     read mycard
     case "$mycard" in
         radeon)
             check_installed radeontool
             ;;
         vbepost)
             check_installed vbetool
             ;;
         vbestate)
             check_installed vbetool
             echo "Saving current video hardware data..."
             mkdir -p /var/lib/vbetool
             save_vt_nr=$(fgconsole)
             chvt 1
             vbetool vbestate save > /var/lib/vbetool/vbestate
             chvt $save_vt_nr
             echo "Done."
             ;;
         none)
             echo "Then you probably don't need this script! Exiting."
             exit 0
             ;;
         *)
             echo "Error: unsupported card handler!: $mycard. Exiting."
             exit 1
             ;;
     esac
     echo "Installation of the script"
     ACTION_DEST=/etc/acpi/actions
     EVENT_DEST=/etc/acpi/events
     me="$(basename $0)"
     cd "$(dirname $0)"
     if [ ! -d $EVENT_DEST ]; then
         echo "Error! Did you install acpid?"
         exit 1
     fi
     cat > $EVENT_DEST/$EVENT_NAME << EOF
 event=button[ /]lid
 action=$ACTION_DEST/$EVENT_NAME.sh %e
 EOF
     /etc/init.d/acpid reload
     if [ "$(pwd)/$me" != "$ACTION_DEST/$EVENT_NAME.sh" ]; then
         mkdir -p "$ACTION_DEST"
         sed "s/^\(card_handler=\).*/\1$mycard/" $me > "$ACTION_DEST/$EVENT_NAME.sh"
         chmod 755 "$ACTION_DEST/$EVENT_NAME.sh"
     else
         # In-place re-configuration
         sed -i "s/^\(card_handler=\).*/\1$mycard/" $me;
     fi
     echo "Installation finished!"
     exit 0
 }
 
 ###########################################################################
 # Main()
 
 [ "$1" = "" ] && install
 read_lid_state
 $DEBUG && echo "LID: $lid_state"
 case "$lid_state" in
     open)
         $DEBUG && echo "Setting light on";
         case "$card_handler" in
             radeon)
                 radeontool light on;
             ;;
             vbepost)
                 save_vt_nr=$(fgconsole)
                 chvt 15
                 vbetool post
                 sleep 1
                 chvt $save_vt_nr
             ;;
             vbestate)
                 save_vt_nr=$(fgconsole)
                 chvt 15
                 if [ -e /var/lib/vbetool/vbestate ]; then
                     vbetool vbestate restore < /var/lib/vbetool/vbestate
                 else
                     $DEBUG && echo "Error: unconfigured vbestate, fallback to vbepost";
                     vbetool post
                 fi
                 sleep 1
                 chvt $save_vt_nr
             ;;
             *)
                 $DEBUG && echo "Error: unknown card_handler: $card_handler";
             ;;
         esac
         ;;
     closed)
         $DEBUG && echo "Setting light off";
         case "$card_handler" in
             radeon)
                 radeontool light off;
             ;;
             vbe*)
             ;;
             *)
                 $DEBUG && echo "Error: unknown card_handler: $card_handler";
             ;;
         esac
         ;;
     *)
         $DEBUG && echo "Error: LID state not recognized: $lid_state"
         ;;
 esac

If you know what you are doing, you can achieve much smaller script, cf LaptopDellD610 step-by-step


Low battery warning

As I mostly use icewn and there is no alert mechanism forseen in it, I use my own script: /etc/acpi/events/warn_battery:


event=battery.*
action=/etc/acpi/actions/warn_battery.sh %e

/etc/acpi/actions/warn_battery.sh (chmod +x):

 #! /bin/bash
 
 # Automatically warns when the battery almost runs out.
 # Version: 0.03
 # Copyright:
 #       2006 Philippe Teuwen <phil-debian _at_ teuwen.org>
 # License:
 #       GPL
 
 BATT_INFO=/proc/acpi/battery/$2
 
 MINIMUM_BATTERY_MINUTES=7
 MINIMUM_BATTERY_CHARGE_MAH=500
 MINIMUM_BATTERY_CHARGE_MWH=500
 CRITICAL_BATTERY_MINUTES=1
 CRITICAL_BATTERY_CHARGE_MAH=100
 CRITICAL_BATTERY_CHARGE_MWH=100
 #WARNING_SOUND=/usr/share/sounds/pop.wav
 WARNING_SOUND=/usr/share/kismet/wav/new_network.wav
 
 if [ -f $BATT_INFO/state ] ; then
     [[ $(cat /proc/acpi/ac_adapter/AC/state) = *on-line* ]] && exit
     if cat $BATT_INFO/state | grep -q discharging ; then
         REMAINING=`cat $BATT_INFO/state | grep "remaining capacity:.*m.h" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
         REMAINING=${REMAINING:-0}
         FULL=`cat $BATT_INFO/info | grep "last full capacity:.*m.h" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
         FULL=${FULL:-0}
         IN_MAH=0
         IN_MWH=0
         ( cat $BATT_INFO/state | grep mWh >/dev/null ) && IN_MWH=1 && UNIT=mW
         ( cat $BATT_INFO/state | grep mAh >/dev/null ) && IN_MAH=1 && UNIT=mA
         DO=0
         DO_CRIT=0
         PRESENT_RATE=`cat $BATT_INFO/state | grep "present rate:.*m" | sed  "s/.* \([0-9][0-9]* \).*/\1/" `
         PRESENT_RATE=${PRESENT_RATE:-0}
         [ "$PRESENT_RATE" -ne 0 -a "$REMAINING" -ne 0 ] && \
             REMAINING_MINUTES=$(($REMAINING * 60 / $PRESENT_RATE))
         [ "$REMAINING" -ne 0 -a "$FULL" -ne 0 ] && \
             REMAINING_PERCENT=$(($REMAINING * 100 / $FULL))
         [ "$PRESENT_RATE" -ne 0 -a "$REMAINING" -ne 0 ] && \
             (($REMAINING_MINUTES < $MINIMUM_BATTERY_MINUTES)) && DO=1
         [ "$IN_MAH" -ne 0 -a "$REMAINING" -lt "$MINIMUM_BATTERY_CHARGE_MAH" ] && DO=1
         [ "$IN_MWH" -ne 0 -a "$REMAINING" -lt "$MINIMUM_BATTERY_CHARGE_MWH" ] && DO=1
         [ "$PRESENT_RATE" -ne 0 -a "$REMAINING" -ne 0 ] && \
             (($REMAINING_MINUTES < $CRITICAL_BATTERY_MINUTES)) && DO_CRIT=1
         [ "$IN_MAH" -ne 0 -a "$REMAINING" -lt "$CRITICAL_BATTERY_CHARGE_MAH" ] && DO_CRIT=1
         [ "$IN_MWH" -ne 0 -a "$REMAINING" -lt "$CRITICAL_BATTERY_CHARGE_MWH" ] && DO_CRIT=1
         if [ $DO -ne 0 ] ; then
             text="WARNING!!!\n"
             text=$text"Remaining: $REMAINING${UNIT}h ($REMAINING_PERCENT%)\n"
             [[ $PRESENT_RATE -ne 0 ]] && text=$text"You have about $REMAINING_MINUTES mins left (discharging at $PRESENT_RATE$UNIT)\n"
         # Send to /var/log/acpid
             echo -e -n $text
         # Send to all terms
             #echo -e -n $text | wall
         # Send an X pop-up
             eval $(w -s -h|grep --max-count=1 "\(startx\|dm\?\)"|sed 's/^\([^[:space:]]\+\)[[:space:]]\+\([^[:space:]]\+\).*$/XUSER=\1;XDISP=\2;/')
             [[ "$XDISP" != :* ]] && XDISP=:0
             echo -e -n $text | su - $XUSER -c "DISPLAY=$XDISP /usr/X11R6/bin/xmessage -center -timeout 10 -file - " &
         # Play a sound
             aplay $WARNING_SOUND
         fi
         if [ $DO_CRIT -ne 0 ] ; then
         # Shutdown
             shutdown -h now
         # Sleep if you prefer and have an adequate script
             #/etc/acpi/actions/acpi_handler.sh button_sleep
         fi
     fi
 fi

/etc/init.d/acpid reload


Useful packages

Some packages I found useful, especially on laptops:

  • backuppc (to be installed on a server, requires only ssh and rsync on the laptop, cf also some notes on HardDrives)
  • OfflineImap
  • cron-apt

Miscellaneous

  • Disable devices you don't use often in the BIOS to get longer battery life.

todo

  • Stop services such as cupsys, cron, sysklogd, klogd, and inetd when on battery power to get more battery life --- create a script to stop these automatically when on battery and restart them when on AC power.
  • sleepd
  • suspend-to-ram and suspend-to-disk
  • lm-profiler