Debian Linux on Lenovo/IBM Thinkpad Z60m

Last update: October 14th, 2007

I will try to install Debian 3.1 (Sarge). Pre-installed WinXP will be erased. For some remorks an Etch, check my other document.

Rumors have it that installing Debian is slightly more tricky than Ubuntu or SuSE or whatever. I want to do it anyway.

Important bit of information: yes, it works and even more, almost all hardware seems to be supported, including special Thinkpad stuff (but you need some manual work). However, I am having continuing problems regarding stability and predictability of the bugs, and I cannot really recommend Debian Sarge for this laptop.

Be sure to check ThinkWiki for refrence, I will more or less list distro specific traps and solutions here.

I also installed Etch on a Thinkpad Z60m.

To install Slackware Linux, see this page.


Problems

If anyone knows how to solve any of these problems, please tell me.

In total, I felt very frustrated about these problems since they were hard to debug: no messages in /var/log/messages indicating a problem, in fact, no error message at all. The unpredictabity was the worst thing of all since I don't know how to track down the problem, since I cannot trigger it predictably.

My old Laptop used to crash during wake up, that was bad, too, but at least it was totally predictable, and thus, understandable. I could then configure it to boot and shutdown quickly, since I knew sleeping would not work. For the new laptop seemingly most hardware and features are supported and are working more or less for some time. But the laptop is unstable. This really is bad and I currently mainly blame the OS for this.


Overview

Model: 2529-FKG
Part: UH3FKGE
Working: keyboard, hard disk, display (in X), dual-head display, 2d accel, 3d accel, ethernet, wlan, touchpad, trackpoint, volume incr/decr/mute, thinklight button and software switching, button display brightness control, special buttons, software led switching, suspend to ram in X (but not in console) (does it drain?), usb (keyboard & mouse tested on console and X), vga out, sound.
Currently not working: vga/lcd switching in X (but you have dual-head), key press repetition on page left/page right buttons.
Not working out of the box: X, sleep, special buttons.
Untested: hibernate, pcmcia, dvd writer, bluetooth, irda, firewire, svideo out, modem, cpu frequency scaling, hardware encryption and random device.

What I did

XOrg Backport + ATI official fglrx driver

  • I downloaded the Xorg backport:
    wget -m -np http://www.backports.org/debian/pool/main/x/xorg-x11/
    (I put it on our local mirror. Instead, you can go to the root of that server and read how to access the packages directly by using /etc/apt/sources.list.)
  • To not automatically or accidentally install any more backports than needed, I put the downloaded directory on a local server and allowed apt full access to it. The above wget does not download all you need, however, some more backports are needed. I added www.backports.org to /etc/apt/sources.list, but gave it lower pin-priority (see backports.org for documentation). Then I added all packages that were required for smooth installation manually with full priority. FIXME: sources.list, preferences (list non-Xorg packages that require backport).
  • Then, I installed the Xorg backport (6.9.0) (using aptitude) and also selected many, many packages manually, so this meant a longer package selection session to install much of the stuff I wanted (much is still missing).
  • I downloaded fglrx from ATI (see the ThinkWiki for a link) and also a kernel 2.6.15 patch for it (it's only one line that has to be changed, see below).

    See the compilation instructions. I used the Debian/sid package from the ATI archive (Debian/sarge would not work since it required XFree, but I have XOrg now). In the new version, the resulting .dev files are called a bit differently:
    fglrx-control-qt3_8.21.7-1_i386.deb
    fglrx-driver_8.21.7-1_i386.deb
    fglrx-driver-dev_8.21.7-1_i386.deb
    fglrx-kernel-src_8.21.7-1_i386.deb
    fglrx-sources_8.21.7-1_i386.deb
    After the module-assistant prepare step, I patched the fglrx.tar.bz2 file that had appeared in /usr/src. I unpacked, edited one line (see below), and repacked the fglrx.tar.bz2 file. In modules/fglrx/firegl_public.c, I changed:
    -#if 0
    +#if LINUX_VERSION_CODE >= 0x02060f
         // WARNING WARNINIG WARNNING WARNNING WARNNING WARNNING WARNNING WARNNING
    Then I continued compilation and installation of the driver. Whenever you compile a new kernel, you have to recompile the modules:
    module-assistant prepare
    module-assistant update
    module-assistant a-i fglrx
    Without this, Xorg uses a different driver (i.e, it seems to work anyway).
  • X seems to work now and the system automatically booted into XDM. I tuned the config a bit:
  • I suggest you configure dual-head (or whatever you wish) with aticonfig now to test the VGA out. It works without an external monitor as well, so I did not change it anymore after issuing:
    aticonfig --initial=dual-head
    In fact, I like this. It's a decent setup to have a 1680x1050 laptop screen plus a 1920x1200 24" LCD. :-)
  • Switching to text consoles from X does not work. Add this to /etc/X11/xorg.conf:
    Section "ServerFlags"
            Option          "XkbDisable"    "true"
    EndSection
  • The dpi setting is wrong: xdm invokes the X server to set the resolution to 100dpi. This is wrong. I edited /etc/X11/xdm/Xservers:
    -:0 local /usr/X11R6/bin/X vt7 -dpi 100 -nolisten tcp
    +:0 local /usr/X11R6/bin/X vt7 -nolisten tcp
    After this, the display resolution was still wrong : the external monitor has 94dpi, not 75 as set (although the monitor told the driver via DDC. Thus the driver is broken). So I did:
    Section "Monitor"
            Identifier   "aticonfig Monitor 1"
            DisplaySize  518 324
    EndSection
    I believed the driver to set the internal LCDs resolution to 129x126. I had expected 128x128, but it's close, so I hope it's correct. If you think 128x128 is correct, then use:
    Section "Monitor"
            Identifier   "aticonfig Monitor 0"
            DisplaySize  333 208
    EndSection
  • xdm crashed after a session was reset. The computer was alive and could be used and thus also rebooted remotely, but the display was frozen in black (and X took 100% cpu). In contrast to logging out, I found that killing xdm did not hurt the display, though. So I simply told it to restart after session reset and it worked, then. Edit /etc/X11/xdm/xdm-config and add:
    DisplayManager*terminateServer: true
    I saw similar solutions posted for gdm and other display managers.
  • Finally, my advice is to not use the radeon driver: I tried it for a whole day and it just could not properly talk to the external LCD panel: although the panel exactly told it the desired modeline (protocol in xorg.0.log), the driver just did not obey and programmed the card to produce signals outside the panel's tolerance (e.g. 43 Hz vert. refresh).

Encrypting swap, /tmp and /home

  • Trying to make cryptsetup work, I am missing a kernel option: the device mapper. The CONFIG_* variables to adjust are:
    CONFIG_BLK_DEV_DM=m
    CONFIG_DM_CRYPT=m
    Alternatively in menu config, it is under Device drivers/Multiple-device support. Enable Device mapper support and Crypt target support.
  • I installed and encrypted the swap partition and /home. (See the documentation in /usr/share/doc/cryptosetup). This was very easy.
  • I also wanted to encrypt /tmp. So I made a small partition of 3GB for it and made similar steps as for swap (substituting 'swap' with 'tmp' in /etc/crypttab). Unfortunately, the init scripts have a, well, bug: they do not make /tmp's root directory writable for everybody. After I installed the encrypted /tmp, no-one else but root could log in (in X)... And since it's reformatted at each boot, it does not help to adjust this once: it will be the same after each boot.
  • I did not want to modify the start scripts, though. So my cheap patch was to create a new file /sbin/mount.ext2, which is called every time an ext2 partition is mounted (which is only /tmp in my system anyway -- the others use ext3), and to enter the following lines:
    #! /bin/sh
    if test "x$2" = "x/tmp"; then
        chmod 1777 /tmp
    fi
    With this, it works.
  • Oh, no, it didn't: at boot, there was not enough random to initialise two disks. So I used /dev/urandom instead of /dev/random in /etc/crypttab. I'll change this to /dev/hwrng as soon as I check out the crypto hardware.
  • Note that version 6.9.0 of Xorg has a 'bug' wrt. acpi event handling: if acpid cannot be contacted, it directly accesses the ACPI event socket. If this happens, acpid cannot start afterwards since X has taken the device. This happened for me a few times and I don't exactly know why, since it would mean that acpid was not running, which it should. One thing that happens then is that the sleep button does not work. The only fix currently seems to be to ensure that acpid starts before X. (As I said: it should, but I still had problems). I have read that the X code is to be modified so that X only tries acpid, not the event socket directly, since that's the correct way of handling acpi events.

Sleep (Suspend to RAM)

  • Despite what I read in some (maybe older) docu, suspend to RAM worked out of the box for me without unloading any module and under X in the set-up described above. To test it, I typed:
    echo mem > /sys/power/state

    The machine quickly goes to sleep then (within ~3 seconds). To wake it up, press FN. To immediately shut it down, press POWER.

  • To automate the procedure, I added a new file /etc/acpi/events/sleepbtn:
    event=button[ /]sleep
    action=/etc/acpi/sleepbtn.sh
    My new small script also locks the screen for the current X user.
    #! /bin/sh
    XUSER=`who | grep ' :0' | cut -d ' ' -f 1`
    if test -n "$XUSER"; then
        # Either xlock:
        # su $XUSER -c "DISPLAY=:0 xlock -mode galaxy&"
    
        # Or XScreenSaver:
        su $XUSER -c "DISPLAY=:0 xscreensaver-command -lock"
        sleep 2
    fi
    
    echo mem > /sys/power/state
    Please see here for my current, slightly more complicated configuration.
  • I tested the power dissipation: it's 500mW, so a full battery will take ~4 days to unload. I think 500mW is too much, maybe I'm leaking power (e.g. in the graphics chip). This will need more investigation. I suspect parts of the video hardware are still on, so I will manually set the hardware to VESA off before sleeping.
  • When suspending from X, the text console is dead after wakeup. To reboot it correctly after resume, I now use vbetool. The sequence needed in the sleep script is interesting, but seems to work well. My current sleep script is here. (Thanks to Peter Weijmarshausen for suggesting vbetool!)

Wireless

Without having had a wireless access, I did the following:

  • In the kernel, use ipw2200 drivers and enable kernel fireware loader.
  • Go to the ipw2200 project homepage, download the fireware (I downloaded 2.0, 2.1 and 2.2 (you never know...)) and install in /usr/local/lib/firmware.

When I then ran into an area with wlan, it just worked.

ThinkPad Buttons TPB

apt-get install tpb
  • /dev/nvram was missing until I added nvram to /etc/modules
  • I had to add myself to the nvram group:
    adduser ht nvram
  • I used xmodmap to map some keys to X11 key symbols:
    keycode  144 = XF86AudioPrev
    keycode  153 = XF86AudioNext
    keycode  162 = XF86AudioPlay
    keycode  164 = XF86AudioStop
    
    ! keycode  234 = XF86ApplicationLeft
    keycode  234 = Prior
    ! keycode  233 = XF86ApplicationRight
    keycode  233 = Next
    As you can use, I simply use the page left/page right keys (or whatever their purpose is) to page up/page down.
  • One problem: the page left/page right buttons do not repeat. To enable autorepeat of the two keys under X, use:
    xset r 233
    xset r 234
  • I then told fvwm1 (yes!) to invoke xmms accordingly, namely:
    Key Action
    XF86AudioStop xmms -s
    XF86AudioPlay xmms -t
    XF86AudioPrev xmms -r
    XF86AudioNext xmms -f

DHCP

Frankly, I do not understand the concept of Debian's DHCP config on laptops. It's really a pain in the bottom to tell it to ask for Mother everytime it wakes up. Automatically switching the configuration, HTTP proxy inclusive, was, therefore, programmed manually by me. I will list the modifications in brief now.

  • Use dhcpcd instead of dhcp-client. We want a daemon, not a boot-once, ask never solution.
  • The sleep script is slightly more complex now since I want to restart DHCP after wake-up. The computer is most likely in a different network environment.
    #! /bin/sh
    dhcpcd-bin -k
    
    XUSER=`who | grep ' :0' | cut -d ' ' -f 1`
    if test -n "$XUSER"; then
        su $XUSER -c "DISPLAY=:0 xscreensaver-command -lock"
    fi
    
    sleep 1
    killall dhcpcd-bin  # just to be sure
    
    # Shut down video hardware:
    chvt 1
    vbetool dpms off
    
    # Measure energy dissipation:
    (echo -n "BEGIN SLEEP: "; date ; cat /proc/acpi/battery/BAT0/state ) >> /var/log/sleep-dissipation.log
    
    # Sleep!
    echo mem > /sys/power/state
    
    # Measure energy dissipation:
    (echo -n "WAKEUP: "; date ; cat /proc/acpi/battery/BAT0/state ; echo "END") >> /var/log/sleep-dissipation.log
    
    # Reboot video hardware:
    vbetool post
    chvt 1
    vbetool dpms on
    chvt 7
    
    # To restart dhcpcd is quite disgusting since it keeps exiting for no
    # obvious reasons.  Who would possibly want a DHCP client daemon to
    # exit??  If so, I kill it.
    dhcpcd-bin -n
    
    # Further, for more unknown reasons, dhcpcd does not seem to be able
    # to constantly watch in background whether a device gets access to
    # a DHCP server.  Therefore, we try to brink the devices up now.
    ifup -a
    
    # Since this still does not work, keep on trying for a while:
    sleep 10
    dhcpcd-bin -n
    sleep 10
    dhcpcd-bin -n
    sleep 10
    dhcpcd-bin -n
    sleep 10
    dhcpcd-bin -n
    sleep 10
    dhcpcd-bin -n
    sleep 10
    dhcpcd-bin -n
    And since dhcpd-bin is absolutely not allowed to ever give up trying, I have a crontab entry:
    0/2 * * * *   /sbin/dhcpcd-bin -n &
    Any proposal for a cleaner (and working) solution would be appreciated.
  • I made a new directory for location switching: /etc/location. It contains scripts and also subdirs for each config. Further, there's a symbolic link 'current' that points to the directory that's active. This link is updated when the IP address changes. Some system files are links into the current directory, e.g. /etc/tinyproxy/tinyproxy.conf and /etc/apt/sources.list.
    /etc/location:
    drwxr-xr-x ... default
    drwxr-xr-x ... absint
    drwxr-xr-x ... home
    lrwxrwxrwx ... current -> absint
    -rwxr-xr-x ... get-ip-address.sh
    -rw-r--r-- ... interface.map
    -rwxr-xr-x ... interface-name.sh
    ...
    
    lrwxrwxrwx ... /etc/apt/sources.list -> ../location/current/sources.list
    
    /etc/tinyproxy:
    lrwxrwxrwx ... tinyproxy.conf -> /etc/location/current/tinyproxy.conf
  • My /etc/network/interfaces looks like this:
    auto lo
    iface lo inet loopback
    
    auto eth0
    auto eth1
    auto eth2
    
    mapping eth0
        script /etc/location/interface-name.sh
    
    mapping eth1
        script /etc/location/interface-name.sh
    
    mapping eth2
        script /etc/location/interface-name.sh
    
    iface rj45 inet dhcp
    
    iface wlan inet dhcp
    
    #iface firewire inet dhcp
    The mentioned script that finds the card name looks like this:
    #! /bin/sh
    cat /etc/location/interface.map | /etc/network/get-mac-address.sh "$@"
    And this is the interface.map file. You need to adjust the MAC addresses for the devices of your machine:
    XY:XY:XY:XY:XY:XY  rj45
    XY:XY:XY:XY:XY:XY  wlan
    And the get-mac-address.sh is the unmodified version from the docu (see man page of ifup and interface) copied from /usr/share/doc/ifupdown/examples/get-mac-address.sh. Finally, I edited /etc/dhcpc/dhcpcd.exe to change some global settings, maintain the link /etc/location/current and restart some daemons when the address changes.
  • For HTTP access, I use tinyproxy (for a direct web proxy) and privoxy (for a filtered web proxy) and I restart them with different config files when the IP addresse changes. My web browser always uses a local port as a proxy, so I can change the access proxy without changing the browser config by simply restarting tinyproxy.

Drivers

Network: Broadcom 10/100/1000 tg3 out of the box (but no auto-detection)
Hard Disk: 2.6.x Kernel SCSI SATA driver (libsata) download
Display: 1680x1050 ATI Radeon X600 Xorg + proprietary ATI driver (fglrx) backport + download
Optical Drive: DVD-Recordable 8x, EIDE in distro
Audio: Analog Devices AD1981HD Intel HD Audio (snd_hda_intel) in kernel
Wireless: Intel 2915 a/b/g ipw2200 needs fireware download from sourceforge project
USB: out of the box
Irda:
Firewire: Thinkwiki: Ricoh R5C841 out of the box? (not checked, but drivers report success)
Cardbus: Thinkwiki: Ricoh R5C841
Flash Card Reader: Thinkwiki: Ricoh R5C841
Touchpad/Trackpoint: Synaptics ps2/psaux out of the box
synaptics download
Bluetooth: kernel Thinkpad driver in kernel (but not yet checked)

Content

Index

October 14th, 2007
Comments? Suggestions? Corrections? You can drop me a line.
zpentrabvagiktu@theiling.de
Schwerpunktpraxis