Memoirs In Free Fall

January 8, 2006

Debian sid on an IBM ThinkPad A21e

Filed under: Uncategorized — amit @ 12:59 pm

I recently acquired a ThinkPad A21e laptop. This is an account of how I set up Debian GNU/Linux unstable (as of November 2005 through January 2006) on it.

Specifications

  • Intel Celeron 600 MHz (SL3W8?)
  • Intel 440MX chipset with 256 MB PC66 SDRAM
  • ATI Rage Mobility P/M graphics chipset with 4MB RAM driving a 15″ XGA (1024×768) TFT display
  • IBM TravelStar 20GN hard disk, 10GB capacity, 4200 rpm hard disk on hda
  • Built in 3.5″ floppy drive
  • LG CRN-8241U 24x CD-ROM drive on hdb in the UltraBay
  • TI PCI1410 PC Card controller with one PC Card slot
  • Intel 82559 (PRO/100) Ethernet controller
  • Xircom Mini-PCI V.90 modem (PCI ID 115D:000C)

In addition, I use a D-Link DWL-G650 PC Card 802.11g Wi-Fi adapter for wireless connectivity, as well as a generic USB IntelliMouse Optical knockoff for a mouse.

Setup

Processor – Intel Celeron 600 MHz

Being a Celeron, this processor lacks SpeedStep altogether. However, it does support ACPI throttling T states, which are a more coarse way to control power consumption by essentially causing the processor to forcibly stop a certain proportion of the time.

I built and installed scaler to try to keep the CPU load around 50% when on battery power. I needed to change the TARGET_FILE macro in the scaler.c source file to

#define TARGET_FILE "/proc/acpi/processor/CPU/throttling"

since it seems the scheme has changed since the code was last updated.

I installed the Debian laptop-mode-tools package and (since I’m using ACPI) modified the ACPI event handling scripts to start and stop the scaler daemon when disconnected from or reconnected to the AC adapter. Sadly, this model appears too old to report ACPI AC adapter events, generating ACPI battery events instead, so I had to resort to hacking up the corresponding action script.

According to /etc/acpi/events/lm_battery, this was /etc/acpi/actions/lm_battery.sh, so I added some stuff to it.

Near the beginning:

#! /bin/bash

# The A21e generates battery events for AC adapter plugin/remove. Handle that
# first.

if [ "$2" = "BAT0" -a "$3" = "00000080" -a "$4" = "00000001" ]; then
	STATE=$(awk '{print $2}' /proc/acpi/ac_adapter/AC/state)
	case $STATE in
		on-line)	logger -p daemon.info On mains power.
				pkill scaler
				for i in up up up up up up up
				do
					echo $i > /proc/acpi/ibm/brightness
					sleep 0.2
				done
				laptop_mode stop
				;;
		off-line)	logger -p daemon.info On battery power.
				/usr/sbin/scaler 50
				for i in down down down down down down down
				do
					echo $i > /proc/acpi/ibm/brightness
					sleep 0.2
				done
				laptop_mode start
				;;
		*)		logger -p daemon.info AC unknown: "$STATE"
				;;
	esac
fi

test -f /usr/sbin/laptop_mode || exit 0

.
.
.

As you can see, apart from starting and killing scaler, I also had the script adjust the LCD brightness on power adapter unplug and replug. (The latter support depends on controls that involve the ibm_acpi kernel module; more on that later.)

If I’d had a SpeedStep-capable processor, I could’ve used cpudyn or similar with the speedstep-smi kernel module, but since I don’t have one, I haven’t investigated how to set up SpeedStep.

I’ll cover power management separately.

ATI Rage Mobility P/M and LCD display

Setting up X for 2D acceleration with this chipset is straightforward — use the “ati” driver, and it’ll be treated as a Mach64 accelerator. I couldn’t get 3D to work, though — it’s equipped with just 4MB of RAM, and that space is insufficient to accelerate 3D at XGA resolutions. It is my understanding that the Mach64 support in X.org 6.8.2 at least (no idea about 6.9.0) does not incorporate 3D acceleration support since it is insecure. I built the Mach64 driver from the Mesa3D CVS tree with non-secure drivers enabled, but to no avail — even at 800×600 — and I could not get direct rendering to work.

With the ibm_acpi kernel module loaded, some control over the LCD is possible. Under the /proc/acpi/ibm tree there are control files for brightness (“brightness”) and display switching (“video”). In my experience the latter doesn’t work particularly well at least under ACPI, but the former works very well. In addition, the tool vbetool can be used to turn on and off the the display. I’ll have more on that later.

IBM TravelStar 20GN

This is a rather slow 10GB unit spinning at 4200 rpm, with a high-pitched whine, but it suits my purposes fine. I initially set up the laptop to use APM, and for suspend-to-disk purposes created a hibernate volume at the end of the disk. This is nothing more than a hidden FAT16 LBA partition (type ID 0x1e) that carries one file called save2dsk.bin. This file can be created using Andrew Tridgell’s tphdisk tool. It needs to be slightly (a few megabytes) larger than the size of physical memory and video memory together. I created a 300 MB partition and file.

Once I switched to ACPI, suspend to disk would no longer work, so I set up software suspend instead, which writes to a swap volume instead. I’ll have more on that later.

Another thing I did was to set up smartd to monitor the SMART characteristics of the hard disk. On Debian this consisted merely of installing the smartmontools package and modifying /etc/default/smartmontools to monitor the hard disk:

# Defaults for smartmontools initscript (/etc/init.d/smartmontools)
# This is a POSIX shell fragment

# list of devices you want to explicitly enable S.M.A.R.T. for
# not needed if the device is monitored by smartd
enable_smart="/dev/hda"

# uncomment to start smartd on system startup
start_smartd=yes

Then I started smartd with invoke-rc.d smartmontools start.

I also set up a few /etc/hdparm.conf settings:

# -A disable/enable the IDE drive's read-lookahead feature      
lookahead = on
# -c enable (E)IDE 32-bit I/O support - can be any of 0,1,3        
io32_support = 1
# -m sector count for multiple sector I/O
mult_sect_io = 16
# -u interrupt-unmask flag for the drive
interrupt_unmask = on

/dev/hda {
        write_cache = on
        transfer_mode = 66
        spindown_time = 120
}

The spindown_time setting sets up the hard disk to spin down in ten minutes in the absence of activity. With laptop mode, when off AC power, the ext3 journal commit time increases from once every five seconds to something configurable via /etc/laptop-mode/laptop-mode.conf, so this setting has a chance to take effect and spin the hard disk down for enhanced battery savings. (The laptop mode tools also modify the spin-down time.)

###############################################################################
# Hard drive behaviour settings
###############################################################################

# Maximum time, in seconds, of work that you are prepared to lose when your
# system crashes or power runs out. This is the maximum time that Laptop Mode
# will keep unsaved data waiting in memory before spinning up your hard drive.
LM_BATT_MAX_LOST_WORK_SECONDS=1800
LM_AC_MAX_LOST_WORK_SECONDS=360

# Should laptop mode tools control readahead?
CONTROL_READAHEAD=1

# Read-ahead, in kilobytes. You can spin down the disk while playing MP3/OGG
# by setting the disk readahead to a reasonable size, e.g. 3072 (3 MB).
# Effectively, the disk will read a complete MP3 at once, and will then spin 
# down while the MP3/OGG is playing. Don't set this too high, because the 
# readahead is applied to _all_ files that are read from disk.
LM_READAHEAD=3072
NOLM_READAHEAD=128

# Should laptop mode tools add the "noatime" option to the mount options when 
# laptop mode is enabled?
CONTROL_NOATIME=1

# Should laptop mode tools control the hard drive idle timeout settings?
CONTROL_HD_IDLE_TIMEOUT=1

# Idle timeout values. (hdparm -S)
# Default is 2 hours on AC (NOLM_HD_IDLE_TIMEOUT_SECONDS=7200) and 5 seconds
# for battery and for AC with laptop mode on.
LM_AC_HD_IDLE_TIMEOUT_SECONDS=3600
LM_BATT_HD_IDLE_TIMEOUT_SECONDS=120
NOLM_HD_IDLE_TIMEOUT_SECONDS=7200

# Shoudl laptop mode tools control the hard drive power management settings?
CONTROL_HD_POWERMGMT=1

# Power management for HD (hdparm -B values)
BATT_HD_POWERMGMT=1
LM_AC_HD_POWERMGMT=255
NOLM_AC_HD_POWERMGMT=255

# Should laptop mode tools control the hard drive write cache settings?
CONTROL_HD_WRITECACHE=0

# Write cache settings for HD (hdparm -W values)
NOLM_AC_HD_WRITECACHE=1
NOLM_BATT_HD_WRITECACHE=0
LM_HD_WRITECACHE=0

CD-ROM drive, CardBus controller and Ethernet adapter

These are picked up and configured by the hotplug subsystem; for the Ethernet adapter I just placed one line in /etc/network/interfaces:

iface eth0 inet dhcp

Most of the time I use the laptop unwired, so I don’t have it brought up automatically.

Xircom Mini-PCI V.90 modem

As expected, this is a winmodem. It works pretty well with the ltmodem driver. I downloaded the source and after installing the linux-headers package corresponding to the Debian kernel installed, I ran the build_deb script inside to detect the modem and build the kernel module for the modem. After installing the generated package and loading the module with a modprobe ltmodem and modprobe ltserial, the simulated serial dialout device showed up under udev as /dev/ttyLTM0 (character special file, major 62, minor 64), ready to be used.

D-Link DWL-G650 wireless adapter

This carries an Atheros 5212 chipset paired with a 2.4 GHz radio capable of 11b and 11g operation (no 11a though). I use the madwifi driver with it. Under Debian, this involves installing the module-assistant package and running module-assistant auto-install madwifi to build a package of the modules, then installing the generated package with dpkg -i. The next time I plugged in the card the hotplug subsystem loaded the driver, leaving it ready for use.

I use wpa_supplicant for WPA and roaming support in conjunction with guessnet and ifplugd to manage connectivity. All of them are available in Debian’s apt repository. Essentially, in conjunction with Debian’s ifupdown, this allows hotplug to manage interfaces and allow for automatic configuration of known networks. The hole, roaming on unprotected hotspots, is something that doesn’t work perfectly yet, unfortunately. I’m still working on that one.

Here’s what ties them together — /etc/network/interfaces:

auto ath0

mapping ath0
	script /usr/sbin/guessnet-ifupdown
	map default: home

iface home inet static
      wireless-essid "my-essid"
      wireless-mode Managed
      wireless-power on
      address 192.168.2.5
      netmask 255.255.255.0
      gateway 192.168.2.1
      test wireless mac RO:UT:RM:AC:AD:DR essid my-essid
      pre-up /etc/init.d/wpasupplicant restart
      post-down /etc/init.d/wpasupplicant restart

iface work inet dhcp
      test wireless essid work-essid
      wireless-essid work-essid
      wireless-mode Managed
      wireless-power on
      pre-up /etc/init.d/wpasupplicant restart
      post-down /etc/init.d/wpasupplicant restart

iface other inet dhcp
      wireless-essid any
      wireless-mode Managed
      wireless-power on
      pre-up /etc/init.d/wpasupplicant restart
      post-down /etc/init.d/wpasupplicant restart

iface adhoc inet dhcp
      wireless-essid any
      wireless-mode Ad-Hoc
      wirelss-power on
      pre-up /etc/init.d/wpasupplicant restart
      post-down /etc/init.d/wpasupplicant restart

allow-hotplug ath0

mapping hotplug
	script /usr/sbin/guessnet-ifupdown
	map default: home

Essentially it passes hotplug events regarding interfaces to guessnet, which uses the test directives in each stanza to decide which one fits best, then uses it to set up the appropriate interface.

I use WPA-PSK at home and the workplaces uses LEAP, so I’ve set up wpa_supplicant to scan for the known APs in /etc/wpa_supplicant.conf:

ap_scan=1
.
.
.
network={
	ssid="my-essid"
	psk="my-psk"
	proto=WPA
	group=TKIP
	key_mgmt=WPA-PSK
	scan_ssid=1
	pairwise=TKIP
}

# LEAP with dynamic WEP keys
network={
	ssid="work-essid"
	key_mgmt=IEEE8021X
	eap=LEAP
	identity="user"
	password="password"
}

network={
	ssid=""
	key_mgmt=NONE
}

That last one should cause wpa_supplicant to associate with any open AP; however, whether it’s because of ifplugd or guessnet or something wrong with my configuration, that never actually happens, and I usually end up having to stop wpa_supplicant with invoke-rc.d wpasupplicant stop and then use iwlist and iwconfig to manually associate with an open AP. Oh well. I’ll get it right sooner or later. For the moment, it does cycle through the known networks and does automatically authenticate against and associate with my home network simply when I plug in the card.

In order to get wpa_supplicant going I needed to set it up for my card in /etc/default/wpasupplicant:

ENABLED=1
.
.
.
OPTIONS="-i ath0 -D madwifi -c /etc/wpa_supplicant.conf"

and start wpa_supplicant with invoke-rc.d wpasupplicant start.

Keyboard

This is the plain ThinkPad keyboard without the Windows or menu keys. There are four convenience buttons — one ThinkPad button, up/down volume control buttons and one mute button, that act independently of the driver mixer. I use tpb to manage them. I installed the Debian package for it and edited /etc/tpbrc to change the action of the ThinkPad key (directive THINKPAD) to start /usr/bin/opera. I also changed the OSD font and color to taste:

OSDFONT     -*-arial black-*-*-*-*-*-180-*-*-*-*-*-*
OSDCOLOR    Green

By and large, the defaults work well. It also takes care of the Fn-PgUp keystroke to toggle the ThinkLight (the LED that lights up the keyboard if you feel it’s too dark to see the key labels). I have tpb start from my .xsession:

tpb -d

I also set up ACPI events for the Fn keystrokes. Specifically, this laptop generates events for Fn-F3 to control the LCD backlight (on/off), Fn-F4 for standby, Fn-F7 to switch displays and Fn-F12 to hibernate. I created a file /etc/acpi/events/ibmkey:

event=ibm[ /]hotkey
action=/etc/acpi/actions/ibmkey.sh %e

and the corresponding action script:

#!/bin/sh

if [ $2 != "HKEY" ] ; then exit ; fi

case "$3 $4" in
	"00000080 00001003")
		# Fn-F3, Blank screen
		echo 12 > /proc/acpi/ibm/beep
		STATE=$(grep '^lcd:' /proc/acpi/ibm/video | awk '{print $2}')
		if [ "${STATE}" = 'enabled' ]; then
			# It's been known to lie; check to see if we've done
			# this before.
			
			logger -p local0.warn /proc/acpi/ibm/video lied to us
			
			if [ -f /var/run/lcd-disabled ]; then
				STATE=disabled
			fi
		fi
		if [ "${STATE}" = 'enabled' ]; then
			echo lcd_disable > /proc/acpi/ibm/video
			/usr/sbin/vbetool dpms off
			touch /var/run/lcd-disabled
		else
			/usr/sbin/vbetool dpms on
			echo lcd_enable > /proc/acpi/ibm/video
			rm -f /var/run/lcd-disabled
		fi
		;;
	"00000080 00001004")
		# Fn-F4, Sleep
		echo 2 > /proc/acpi/ibm/beep
		chvt 1
		echo 7 > /proc/acpi/processor/CPU/throttling
		echo lcd_disable > /proc/acpi/ibm/video
		/usr/sbin/vbetool dpms off
		echo standby > /sys/power/state
		/usr/sbin/vbetool dpms on
		echo lcd_enable > /proc/acpi/ibm/video
		echo 0 > /proc/acpi/processor/CPU/throttling
		chvt 12
		;;
	"00000080 00001007")
		# Fn-F7, Switch
		echo video_switch > /proc/acpi/ibm/video
		;;
	"00000080 0000100c")
		# Fn-F12, Hibernate
		echo 2 > /proc/acpi/ibm/beep
		/usr/sbin/hibernate
		;;
esac

Now for what this script does — the hotplug subsystem matches ACPI events against the event files in /etc/acpi/events and invokes the commands specified therein, providing the event data as arguments. The script then uses the event data to determine what the hotkey event was and acts accordingly.

The ibm_acpi kernel module adds much functionality specific to IBM ThinkPads, including a /proc/acpi/ibm procfs tree that provides much state information and control over various aspects of the laptop. It also allows for the generation and recognition of IBM-specific ACPI events, such as the hotkey events. This depends on hotkey support being enabled either through /proc/acpi/ibm/hotkey or through the options passed to the ibm_acpi module at load time. I used the latter option, creating a file called /etc/modprobe.d/ibm-acpi:

options ibm-acpi experimental=1 hotkey=enable

One of the things ibm_acpi allows control over is the LCD backlight, including brightness and turning it on and off. Unfortunately, the latter is pretty unreliable, so I had to cook up a way to keep track of whether the LCD was on or off. I ended up with a statefile in /var/run and the use of vbetool to turn the display on and off on the Fn-F3 keystroke. It works fairly reliably.

The Fn-F4 keystroke is fairly straightforward — I bring the CPU to maximum throttling (lowest speed, just in case), disable the LCD and then ask ACPI to send the laptop into S1 standby mode. Turning the LCD off is necessary since for some reason, ACPI standby doesn’t do this. I tried to use S3 sleep (“mem”), but this was summarily ignored, and S2 suspend locked up the laptop hard.

On resume the LCD is enabled again and the throttling is disabled.

The Fn-F7 video switch is accomplished by means of the /proc/acpi/ibm/video control file, but I’m not sure if this really works; I have not had the chance to try it with a CRT. At least it seems to disable and enable the LCD.

The Fn-F12 keystroke invokes the swsusp2 hibernate script from the Debian hibernate package, which works equally well with swsusp integrated in the stock Debian kernels. More on that later.

Pointer input (mouse and TrackPoint)

ThinkPads are equipped with a TrackPoint device that serves as a mouse replacement — effectively a nubby joystick between the G, H and B keys on the keyboard and a set of three buttons beyond the spacebar. The blue-and-black “middle button” is meant to be used with the TrackPoint to generate scroll events. X recognizes it as a regular PS/2 mouse with three buttons, however, and does not, by default, provide for scrolling functionality.

There’s a tool called tp-scroll that can sit in between the /dev/input/mouse0 device file and X, and can translate middle button drags into scrolling events, and it works fairly well. However, it has one major issue — it makes it inconvenient to remap buttons and coexist peacefully with an external USB mouse — frequently the tp-scroll horizontal-axis scroll events will generate the same X button events as the USB mouse’s side buttons, and it seems not to work very well at all with the newly released X11R6.9.0, where generates “button 10” events for scroll up and button 6 and 7 events for horizontal scroll — and none at all for scroll-down.

Fortunately, X builds in its own scrollwheel emulation. For a while now, you can configure the mouse to emulate a scrollwheel using the EmulateWheel option:

Section "InputDevice"
	Identifier	"Configured Mouse"
	Driver		"mouse"
	Option		"CorePointer"		"on"
	Option		"Device"		"/dev/input/mouse0"
	Option		"Protocol"		"ExplorerPS/2"
	Option		"ZAxisMapping"		"4 5 6 7"
	Option		"EmulateWheelButton"	"2"
	Option		"EmulateWheel"		"on"
	Option		"Emulate3Buttons"	"on"
	Option		"YAxisMapping"		"4 5"
	Option		"XAxisMapping"		"6 7"
EndSection

Unfortunately, until recently, this meant foregoing Button 2 (middle-click) events, which made things rather inconvenient, even with Emulate3Buttons allowing the event to be generated with the left and right buttons clicked together. However, there’s been a patch for quite a while that allows a timeout to be set up; if the button is released during the timeout period, a regular middle-click event is generated. This is a great improvement, and the only thing one loses is the ability to do a middle-button-drag (which can be kludged on using the 3-button emulation feature, whereupon you regain the ability to do a middle-button-drag using the left and right buttons together, but lose the minor ability to do a simultaneous left-and-right click). Essentially you set the EmulateWheelTimeout option in addition to the above:

	Option		"EmulateWheelTimeout"	"300"

David Nusinow of the Debian X Strike Force uploaded some 6.9.0rc1 packages into experimental some weeks ago with this patch applied (or maybe it made it into upstream; I don’t know); I’m using the xserver-xorg package version 6.8.99.901.dfsg.1-2 that has this patch applied. Subsequent packages (6.8.99.902.dfsg.2-1; 6.9.0rc2 up to the current package in unstable, 6.9.0.dfsg.1-2) seem to have this functionality broken. Currently I’ve placed the 6.9.0rc1 xserver-xorg package on hold; I’ll upgrade when the issue is fixed. For now, the package can be had off snapshot.debian.net.

The horizontal scrolling generates button events 6 and 7, which are usually configured for side buttons, so in browsers, they usually act as back and forward button events. This can get really aggravating when you’re trying to scroll vertically up or down and end up going back or forward accidentally because you weren’t scrolling perfectly vertically. Fortunately, most browsers are easy to fix. For Gecko-based browsers such as Mozilla, Seamonkey, Firefox, etc. you can navigate to about:config and change the setting mousewheel.horizscroll.withnokey.action to the value 0. I also recommend changing mousewheel.horizscroll.withnokey.numlines to the value 5. This changes the behavior of horizontal scroll events from going back and forth in history to scrolling the page horizontally. (Thanks to the Mac community for running into this problem with the Mighty Mouse and figuring out how to fix it.)

Opera, my browser of choice, similarly generates Back and Forward events for buttons 6 and 7. This is easly fixed. In Opera 8 and higher, bring up the Preferences dialog (Tools → Preferences) and hit the Advanced tab. In the left pane, select the last item, Shortcuts. In the top right selection box, choose Opera Standard and select Edit… Then in the dialog box that appears, expand the Application item and look for Button6 and Button7 events. Change their actions to read Scroll left and Scroll right instead. Click OK to dismiss the dialog box, and choose the Opera Standard (Modified) item and dismiss the dialog box with the OK button. At this point your TrackPoint should be able to scroll in both axes without triggering page flips.

(Apparently, the use of button 6 and 7 events for horizontal scrolling is now standard, with X11R6.9.0’s default ZAxisMapping having been reverted to this effect. Now the world needs to change to comply . . .)

I also set up gpm to give me a cursor on text console; here’s my /etc/gpm.conf:

device=/dev/input/mice
responsiveness=
repeat_type=raw
type=exps2
append=''
sample_rate=

Additionally, I wanted to use my USB mouse in its full glory. This is done using a fairly standard-looking setup (except for the AlwaysCore option to allow me to use it simultaneously with the TrackPoint, and the four values to push the side buttons up to distinguish them from the horizontal scrolling events from the TrackPoint). From my /etc/X11/xorg.conf:

Section "InputDevice"
	Identifier	"USB mouse"
	Driver		"mouse"
	Option		"AlwaysCore"		"on"
	Option		"Device"		"/dev/input/mouse1"
	Option		"Protocol"		"ExplorerPS/2"
	Option		"ZAxisMapping"		"4 5 6 7"
	Option		"Buttons"		"9"
EndSection

As a result, the side buttons generate button events 8 and 9 (which is, again, standard with X.org 6.9 and 7.0), which most browsers sadly do not recognize yet. Enter IMWheel. This is an aged tool that was in vogue when the IntelliMouse Wheel first started becoming popular and applications still lacked support for the scrollwheel — it was used to translate the wheel events into keystrokes in the applications. Those days are long past at least as far as scrollwheels are concerned — practically all toolkits have some provision to support the scrollwheel, even if it means setting X resources to get Motif and Athena Widgets to comply. However, with the now-oddball side button settings, imwheel sees its worth again.

Here’s my ${HOME}/.imwheelrc:

"[Tt]erm"
None,	Thumb1,	Up
None,	Thumb2,	Down

"[Rr]xvt"
None,	Thumb1,	Up
None,	Thumb2,	Down

"konsole"
None,	Thumb1,	Up
None,	Thumb2,	Down

"AcroRead"
None,   Thumb1, Page_Down
None,	Thumb2,	Page_Up

"opera"
None,   Thumb1, Alt_L|Left
None,   Thumb2, Alt_L|Right

"konqueror"
None,   Thumb1, Alt_L|Left
None,   Thumb2, Alt_L|Right

"[Ss]eamonkey-bin"
None,   Thumb1, Alt_L|Left
None,   Thumb2, Alt_L|Right

I invoke imwheel with imwheel -b 000089, telling it not to bother with up, down, left or right scrolling events, but to capture buttons 8 and 9 and treat them as thumb buttons (which they are). The ${HOME}/.imwheelrc specifies the translations to perform. As you can see, I have it turn them into Alt-Left and Alt-Right keystrokes in Seamonkey, Konqueror and Opera, which are back/forward events as far as those browsers are concerned. (If you’re curious about the patterns, they’re matched against titles or window classes.)

Whew. Moving on . . .

Power management

Ah yes. This laptop is capable of both APM and ACPI. I initially set it up to use APM (which works essentially out of the box — however, it’s a limited interface, so things like AC adapter notification aren’t available to do nifty things like turn on laptop mode or dim the screen or throttle the CPU automatically), but decided to move on to using ACPI instead. As I’ve indicated before, there is support for ThinkPad-specific features, and laptop_mode is a handy perk. By and large, ACPI works well, except for the annoying fact that standby mode does not turn off the LCD. The hotkey setup outlined above takes care of that issue, fortunately.

Software suspend also works, but it takes a little work. Stock Debian kernels don’t build in any disk or even controller drivers, instead relying on an initrd image generated during kernel package install time to carry appropriate modules and generate device nodes on the fly using udev or similar. At the time of this writing, I had tried yaird only to find that it generated broken initital RAM disks incapable of generating /dev/hda1 on their own, so I’d switched to initramfs.

Now the way swsusp works is that you provide a resume=/dev/hdnx kernel parameter pointing out the swap device. Ordinarily, a kernel that builds in disk drivers itself will attempt to resume off the swap device indicated as its first order of business after initialization. However, given that Debian kernels cannot do this, this duty falls to the initial RAM disk, or initrd, that loads the drivers prior to switching the root device to the actual root filesystem on disk and transferring control to init. Yaird does not, as of this writing, support resuming from a swsusp page dump. initramfs-generated initrds are purported to do so by parsing the resume= parameter and sending the appropriate major and minor device numbers to /sys/power/resume, but in my case this didn’t work either.

Fortunately, the initramfstools allow the administrator to specify scripts to be run at various stages of initrd processing, so I decided I would save myself the trouble and placed scripts to attempt the resume from swap (as well as create a device file that the initrd seemed to have a hard time generating on its own).

Here’s /etc/mkinitramfs/scripts/local-top/resume:

#!/bin/sh
echo 3:2 > /sys/power/resume

This forces the kernel to attempt a manual resume from the swap device, /dev/hda2. (The numbers are the major and minor numbers of the block device.) At some point I’ll figure out why the initrd can’t manage to do this on its own. For now, though, this is a good workaround.

Here’s /etc/mkinitramfs/init-premount/rootfs:

#!/bin/sh
mknod /dev/hda1 b 3 1

Again, udev and hotplug ought to be able to manage this part on their own. Since they don’t (and it’s my understanding it’s udev’s fault), this will work for now.

The last piece is to add the resume= parameter as a kernel option in the GRUB configuration file, /boot/grub/menu.lst:

# kopt=root=/dev/hda1 ro elevator=as resume=/dev/hda2

This will just set up menu.lst to be processed by update-grub (so that any subsequent kernels installed will pick up these options); I run update-grub.

At next reboot, I can hit Fn-F12, which will invoke the hibernate script, upon which the swap device from which the initrd attempted to do a manual resume will in turn be used as a swsusp resume location. On powerup, the initrd will attempt to resume from it once drivers are loaded, and the hibernated session will be resumed.

I think that about covers everything. There are varied bits of functionality that one can gain out of a ThinkPad; this post covers the more interesting among them.

Advertisements

4 Comments »

  1. Could you post your xorg.conf file — SuSE Enterprise fails to properly probe the display and I am having one hell of a time getting it to go.

    Comment by Dan Reiland — July 11, 2006 @ 3:59 am

  2. Section "Files"
            FontPath        "unix/:7100"                    # local font server
            # if the local font server has problems, we can fall back on these
            FontPath        "/usr/share/fonts/X11/misc"
            FontPath        "/usr/share/fonts/X11/cyrillic"
            FontPath        "/usr/share/fonts/X11/75dpi/:unscaled"
            FontPath        "/usr/share/fonts/X11/100dpi/:unscaled"
            FontPath        "/usr/share/fonts/X11/Type1"
            FontPath        "/usr/share/fonts/X11/CID"
            FontPath        "/usr/share/fonts/X11/75dpi"
            FontPath        "/usr/share/fonts/X11/100dpi"
            FontPath        "/usr/share/fonts/truetype/msttcorefonts"
            FontPath        "/usr/share/fonts/truetype/ttf-bitstream-vera"
            FontPath        "/usr/share/fonts/truetype/openoffice"
            FontPath        "/usr/share/fonts/truetype"
            RgbPath         "/usr/share/X11/rgb"
            ModulePath      "/usr/lib/xorg/modules"
    EndSection

    Section "Module"
            Load    "dbe"
            Load    "ddc"
            Load    "glx"
            Load    "dri"
            Load    "fb"
            Load    "extmod"
            Load    "freetype"
            Load    "int10"
            Load    "record"
            Load    "type1"
            Load    "v4l"
            Load    "vbe"
            Load    "GLcore"
            Load    "xaa"
            Load    "ramdac"
            Load    "xf1bpp"
            Load    "xf4bpp"
            Load    "shadowfb"
            Load    "i2c"
            Load    "vgahw"
            Load    "fbdevhw"
    EndSection

    Section "InputDevice"
            Identifier      "Generic Keyboard"
            Driver          "kbd"
            Option          "CoreKeyboard"
            Option          "XkbLayout"     "us,dev,ar"
            Option          "XkbModel"      "pc101"
            Option          "XkbOptions"    "ctrl:swapcaps,grp:alt_shift_toggle"
            Option          "XkbCompat"     "default+pc+iso9995"
            Option          "XkbRules"      "xorg"
    EndSection

    Section "InputDevice"
            Identifier      "Configured Mouse"
            Driver          "mouse"
            Option          "CorePointer"           "on"
            Option          "Device"                "/dev/input/mouse0"
            Option          "Protocol"              "ExplorerPS/2"
            Option          "ZAxisMapping"          "4 5 6 7"
            Option          "EmulateWheelButton"    "2"
            Option          "EmulateWheel"          "on"
            Option          "EmulateWheelTimeout"   "300"
            Option          "YAxisMapping"          "4 5"
            Option          "XAxisMapping"          "6 7"
    EndSection

    Section "InputDevice"
            Identifier      "USB mouse"
            Driver          "mouse"
            Option          "AlwaysCore"            "on"
            Option          "Device"                "/dev/input/mouse1"
            Option          "Protocol"              "ExplorerPS/2"
            Option          "ZAxisMapping"          "4 5 6 7"
            Option          "Buttons"               "9"
    EndSection

    Section "Device"
            Identifier      "ATI Technologies, Inc. Rage Mobility P/M"
            Driver          "ati"
            Option          "DMAMode" "async"
    EndSection

    Section "Monitor"
            Identifier      "Generic Monitor"
            Option          "DPMS"
    EndSection

    Section "Screen"
            Identifier      "Default Screen"
            Device          "ATI Technologies, Inc. Rage Mobility P/M"
            Monitor         "Generic Monitor"
            DefaultDepth    24
            SubSection "Display"
                    Depth           1
                    Modes           "1024x768" "800x600" "640x480"
            EndSubSection
            SubSection "Display"
                    Depth           4
                    Modes           "1024x768" "800x600" "640x480"
            EndSubSection
            SubSection "Display"
                    Depth           8
                    Modes           "1024x768" "800x600" "640x480"
            EndSubSection
            SubSection "Display"
                    Depth           15
                    Modes           "1024x768" "800x600" "640x480"
            EndSubSection
            SubSection "Display"
                    Depth           16
                    Modes           "800x600" "640x480"
            EndSubSection
            SubSection "Display"
                    Depth           24
                    Modes           "1024x768" "800x600" "640x480"
            EndSubSection
    EndSection

    Section "ServerLayout"
            Identifier      "Default Layout"
            Screen          "Default Screen"
            InputDevice     "Generic Keyboard"
            InputDevice     "Configured Mouse"
            InputDevice     "USB Mouse"
    EndSection

    Section "DRI"
            Mode    0666
    EndSection

    Section "Extensions"
            Option          "Composite"     "enable"
    EndSection

    Comment by amit — July 11, 2006 @ 7:39 pm

  3. Hi,

    Very interesting post. I have the same hardware and I would like to optimize it too because with recent apps, the system is not really usable.

    I choosed Debian Sid to and some “light weight” applications (xfce, opera)

    I use a generic kernel provided by debian packages and I wonder if it would not be better to use a custom kernel but I’m not a kernel guru.
    Did you compile a customized kernel? If yes, could you send me your .config by email?

    Thank you.

    Comment by Vincent — May 6, 2007 @ 3:01 pm

  4. Hi Vincent,

    I used the Debian stock kernels, since they incorporate various bugfixes and patches over the kernel.org kernel. They support all the functionality of the laptop adequately.

    Comment by amit — May 6, 2007 @ 11:10 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: