Gentoo Linux on an IBM ThinkPad T42p

We recently purchased two of these wee beasties for our lab group, and I've been trying to configure one to work optimally with Gentoo Linux, so I can copy the working config to the other afterward. I won't go into too much detail about the machine itself, since you can find out most of that information elsewhere. However, since as of right now (July 30, 2004) very few people have had complete success getting everything working with these machines, I thought I'd document my progress as well. I'm not the only site with information on the T42p; you might want to check these other places (some of which describe the T41p, which is similar in many ways):

Rovey Holderith's page on setting up Gentoo on a T42p.
Installing Fedora Core 2 on a T42p.
Peter Leonard's page on running Gentoo on a T41p.
Debian on a T41p.
Vaibhav Sharma's page on installing Fedora Core 1 on a T41p.

Random update: I've changed the default IRQ settings in the BIOS (press F1 at the IBM screen on bootup to enter BIOS setup) from all 11 to be split between 11, 10, 9, and 5. Don't know if this makes a difference for anything, but if something I wrote here doesn't work for you, give that a try.

I also won't go into detail about the basic configuration of the system, since I assume that either (A) you already know how to do that, (B) you're new to Gentoo, in which case you should read the excellent Gentoo Handbook instead, or (C) you're not using Gentoo, in which case my description wouldn't help you anyway. Instead, I'll list a bunch of things that I've tried or am trying to get working, and describe my progress on each of them. Some have been easy, some have stumped me so far, and I haven't even started on some. For now, that list is:

Here is the kernel .config file I used with the latest (as of my build) gentoo-dev-sources package. I'll refer to various aspects of this kernel config later on. Note that I didn't use a generic kernel source package here - I've patched it with the swsusp2 patches, which I'll describe below.

Hardware-Accelerated Video Support

You need several things to work to get hardware-accelerated video in Linux on the T42p. Unfortunately, one of those things is a proprietary video driver from ATI. In Gentoo, you can get that driver by typing ACCEPT_KEYWORDS="~x86" emerge ati-drivers as root (or having ACCEPT_KEYWORDS="~x86" in your /etc/make.conf and just typing the emerge command). It also wouldn't hurt to emerge ati-drivers-extra, which gives you the fireglcontrol utility for adjusting dual-screen and gamma settings, and the fgl_glxgears program which lets you test your OpenGL settings and provides good eye candy. Be sure you get at least ati-drivers-3.9.0 (which you will if you set ACCEPT_KEYWORDS properly) in order for everything (like suspend-to-disk) to work properly. Once you have these modules built, emerge opengl-update and run opengl-update ati to switch the OpenGL drivers to use the ATI-supplied accelerated ones.

Emerging the ati-drivers package is just the first step, though. You also need to configure your kernel to include the proper modules. For my kernel, under Character Devices, I enabled /dev/agpgart (AGP Support), and beneath that menu, enabled support for the ATI and Intel chips (haven't yet tested whether any of them are used, but I enabled and loaded them to make sure). Also, under Graphics Support, I enabled Support for frame buffer devices and VESA VGA Graphics support, but built the ATI support as modules. Also, in the Console Display Driver section, I enabled Framebuffer Console Support.

Upon bootup, I load the agpgart, intel-agp, and fglrx kernel modules (I've added them to /etc/modules.autoload.d/kernel-2.6 so they load automatically). I then use this /etc/X11/XF86Config file for single-screen mode. The fireglcontrol program mentioned above seems to let you configure dual-monitor support, but I haven't played with it yet. With this kernel config, those modules, and that XF86Config, I get accelerated OpenGL 3D graphics - however, as I play with my config they come and go, so it's worth testing your system carefully to make sure they work for you. One test is to run /usr/X11R6/bin/glxinfo; if you have hardware-accelerated OpenGL working properly, you'll see a line about 15 lines down that says OpenGL vendor string: ATI Technologies Inc.. If your configuration isn't using hardware-accelerated OpenGL, the vendor string will say something about Mesa, at which point you'll have to poke around and figure out what's wrong. Another sign that you've got hardware-accelerated OpenGL working is that glxgears reports a frame rate of 1700+ fps, as opposed to 200 or so.

Update:

VMWare requires the DGA extension for full-screen mode, so I changed the line that said
     SubSection "extmod"
        Option "omit xfree86-dga"
     EndSubSection
to read
     Load "extmod"
After that, VMWare worked in fullscreen mode just fine.

There does seem to be some weird behavior with OpenGL, though. For example, if I try to run tuxracer or Neverwinter Nights in fullscreen mode, the display (and possibly the whole system; not sure) locks up. If I run them in windowed mode, it works fine, with full acceleration. If I run them in fullscreen mode after running them in windowed mode, they seem to work. I have to play with this more to figure out what's going on.

Note regarding Suspend-to-Disk: the fglrx ATI driver does NOT work with swsusp2. I've done a fair amount of testing with this, and concluded that while displaying X with the ATI driver doesn't break suspend-to-disk, resuming X after suspending breaks the driver and thus causes a kernel panic (which, of course, you can't see since X is broken). Here's my evidence: (1) with the ATI driver in XF86Config, swsusp2 suspends fine but freezes with video lockup on resume; (2) without changing any files, switching to a virtual console (Ctrl-Alt-F1) before suspending causes suspend/resume to work fine; (3) changing the "fglrx" line in /etc/X11/XF86Config to "vesa" and restarting X allows suspend/resume to work fine from within X. So, at least with my kernel config, you have to either use the VESA X driver or switch to a virtual terminal before suspending. This problem might have to do with unloading / loading the right modules during suspend / resume, as well; I'll have to play around to find out.

Update on swsusp2:

the problem seems to be with the intel-agp module; see my notes further down.

Update: X.Org X11.

Since it looks like X.Org's X11 server is going to be the standard in the future (due to licensing issues with XFree86), I decided to give it a try. So I switched to another virtual terminal (Ctrl-Alt-F1), logged in, stopped kdm (/etc/init.d/xdm stop), unmerged XFree86 (emerge -C xfree), and emerged xorg-x11. I also emerged the ATI drivers afterward. As far as I can tell, it just works! I get slightly lower speeds with glxgears (about 1630 instead of 1750), but tuxracer works fine. NeverwinterNights ran fine for about 5 minutes but then started getting super-choppy and eventually crashed. Not sure whether this is a problem with the X server or not. I'll post updates.

I've switched to using the vesa driver for now (I tried the radeon driver, but it locked up my system; I may play with it some more at some point). I've kept the accelerated config file around so I can switch to it if I want to play games or something.

More info: the problem seems to be related to the DRI interface. I can keep the fglrx and intel_agp modules in as long as I disable dri in XF86Config. Of course, without DRI you don't get nearly as much benefit from being able to use the ATI drivers, but that's another story.

Using an External Projector

I haven't played with this at all yet. However, arwagner has made some progress in this regard with a T41p, so I'm likely to start by borrowing his configuration. I don't know whether it'll work with vesa or not, though.

Sound Support

Works right out of the box. Use a 2.6 kernel and build ALSA support out of the box (or, alternately, use a 2.4 kernel and emerge alsa-drivers). You need the snd_intel8x0 module. ALSA doesn't seem to want to remember my mixer settings between reboots, so I'll have to play with that, but sound works flawlessly otherwise. Recent kernels include the snd_intel8x0m module for supporting a modem built into the same chipset; not sure if that's the modem included with this laptop - it's been a long time since I've needed to use a modem, so that's not likely to be a high priority for me. If someone else figures out how to configure the modem, though, I'll probably set it up. Note that I haven't tried the headphone or microphone jacks, though.

There is one other thing you have to do for sound support, which is to set the mixer values; you can do this using the command-line program alsamixer. I prefer setting the master and PCM volumes to about 87. You can test whether sound is working by running aplay /usr/kde/3.2/share/sounds/pop.wav. Note that if you're using KDE and you have arts running, you won't hear anything. Kill arts and try again (and configure KDE to not run its own sound server). VMWare gave me an error about not being able to find /dev/dsp, so I made the device, but then udev seems to have updated it automatically, since now /dev/dsp points to /dev/sound/dsp. Weird. I don't fully understand udev yet.

Suspend-to-RAM initially killed sound. I fixed it by stopping alsasound (I start it in the default rather than the boot runlevel) and starting it after resuming. After starting alsasound, I had to modprobe snd-intel8x0 and run /usr/sbin/alsactl -f /etc/asound.state restore to restore the mixer settings.

Wireless Networking

Wireless doesn't quite work out of the box, but it's pretty close. You need to emerge madwifi-driver after building your kernel. Then you need to add wlan and ath_pci to your /etc/modules.autoload.d/kernel-2.6 file (assuming you're using 2.6). There are two other steps. You have to create a link in /etc/init.d, so net.ath0 points to net.eth0 (run "ln -s net.eth0 net.ath0"), and you have to edit /etc/conf.d/net (using your favorite editor) to configure networking for ath0 as well as for eth0 (I've got ifconfig_eth0=( "dhcp" ) and ifconfig_ath0=( "dhcp" ) in that file). Finally, since I can't always count on having wired networking but I'm always willing to try to look for wireless, I disabled eth0 and enabled ath0 initialization during startup, by running rc-update del eth0 and rc-update add ath0 default.

I haven't played with WEP/WPA encryption yet, or being able to choose which wireless network you connect to, but I suspect that stuff is less difficult than getting the hardware working.

Wired Networking

Wired networking works out of the box. When building your own kernel, you have to make sure to enable support for the Intel(R) PRO/1000 Gigabit Ethernet driver in the Ethernet (1000 Mbit) section of Networking Support. You also have to add e1000 to /etc/modules.autoload.d/kernel-2.6 See my note in the Wireless Networking section about configuring the wired network to not start up automatically on bootup (unless you want it to do that).

USB Support

Works out of the box. The uhci_hcd module supports USB 1.0, the ehci_hcd module supports USB 2.0. With the XF86Config I provided above, USB keyboards and mice just work. Note, however, that if you need USB 2.0 support, you need to remove the ehci_hcd module before suspending or resuming, or the system won't suspend properly (although this may change in the future).

PCMCIA Support

This was supposed to just work, but I haven't had much luck with it. Under the right conditions I can get 16-bit cards to be recognized, although I have yet to get one to do anything useful. I can't get CardBus cards to even be recognized - the systems knows that I've inserted a card, but can't figure out what card it is or what to do with it. It's very strange; inserting the card causes the kernel to try to load the right module, but cardctl never reports any useful information about the card, and the card is typically useless. Often, running cardctl eject prints a kernel warning that says it couldn't deactivate the voltage supplied to the card, which is particularly disturbing (I don't want to release the magic blue smoke inside of the laptop). Normally I wouldn't care about PCMCIA support, but IBM chose not to include an IEEE1394 adapter on this laptop, and I really need one (we're building video hardware with an IEEE1394 interface), so getting PCMCIA working is important. Anybody who's had more success than me in this regard is welcome to tell me what I'm doing wrong!

Update:

found a bug report off of the pcmcia-cs home page which suggested that ThinkPads need pci hotplugging support in order for pcmcia cards to work properly. So I built pci hotplug support into the kernel, along with the various hardware driver modules, and after rebooting pcmcia seemed to work! The kernel inserted the pci_hotplug and pciehp modules automatically. I'm still getting one error that I find disturbing, though. When I run cardctl eject dmesg has this to say:
PCMCIA: socket f6a3382c: *** DANGER *** unable to remove socket power
I don't know how much of a danger this really is, but it's not something that makes me super-happy. But at least cards work now. Although it seems that if you insert and eject too many times, the card no longer gets recognized. Still gotta play with this a bit.

Suspending to RAM

More wackiness. I can type echo 3 > /proc/acpi/sleep and get the laptop to go to sleep. Getting it to wake up again, though, is another story. If I hit the power button the laptop comes back to life, but the screen never turns back on. Of course, this makes it a little harder to debug the problem, so I haven't quite gotten around to it yet.

Instead of using ACPI's S3 suspend mode, I've put in a script (borrowed from here, with minor modifications) to turn off the backlight when I close the lid. Since I've already got the CPU in a reduced-power state when the system is idle, this should save a lot of battery power in most cases, and be almost but not quite as good as S3. I've put the revised lid.sh script here; put it in /proc/acpi/actions, if you've configured ACPI as I have.

Did some more playing with suspend to RAM. Under just the right conditions, I can get suspend to RAM working properly. Those conditions are as follows:

  • Add acpi_sleep=s3_bios to your boot line in GRUB or LILO.
  • Don't use any fancy vga= setting in your boot line (if you leave this in, your console won't be legible after rebooting).
  • Remove the ehci_hcd module if you have it loaded.
  • Switch away from X to a console if you're using the ATI driver (but with the VESA driver, this works in X!).
  • Remove the fglrx and intel_agp modules.
  • Suspending and resuming seems to kill wireless networking. If you bring ath0 down and remove the ath_pci, ath_hal, and wlan modules before suspending, though, you can re-insert those modules and bring networking back up afterward and it'll work. I tried to do the same with alsasound, but for some reason it doesn't come back up properly.

    Suspending to Disk

    I've made much more progress in this regard. I had to apply the latest swsusp2 patches to the kernel to add swsusp2 support. I also had to get the hibernate script from the same site, and install it into /usr/local/sbin. I rebuilt the kernel with swsusp2 support, and added resume2=swap:/dev/hda5 to my kernel boot line in /boot/grub/grub.conf (I also made a duplicate entry without that line, in case resuming from suspend caused my system to hang; I've used this duplicate entry several times already). With this setup, swsusp2 seems to work to a large extent; for the most part, I can suspend and resume just fine.

    However, I'm having a few difficulties that I should mention. The first has to do with changing configurations while suspended. If I suspend with the AC adapter plugged in, for example, and resume with it unplugged, or otherwise change the hardware (remove PCMCIA cards or USB devices, for example) while the system is suspended, the kernel hangs (note: I haven't tested this thoroughly, so this is just an empirical observation). You might think it's unfair to expect the system to resume under circumstances that are different from those under which it suspended, but not being able to do so makes a laptop much less useful, and laptops are the systems for which software suspend was developed in the first place. So I don't think I'm being unreasonable in my expectations here.

    The second problem may be due to the tpb daemon that listens for ThinkPad buttons, rather than swsusp2, but I'll mention it anyway. I've mapped the Access IBM button to run the hibernate script. Sometimes, when I resume after suspending, the system immediately suspends again. Often trying to resume after that causes the system to crash entirely, so I have to boot from scratch. I'll have to play with running the script directly to see if it has the same problem.

    The third problem is with the ATI proprietary fglrx kernel module. If I'm using fglrx when I suspend, then when I resume the video is screwed up and I can't do anything (except use the magic SysRq keys to sync the drives and reboot). I'm not quite sure what these modules are doing wrong, but they're certainly not re-initializing themselves properly on restarting.

    Update: Console mode.

    If I switch to a virtual console before suspending (this is after replacing XFree86 with X.Org, but I doubt that's the issue) I can resume after suspending just fine. However, if I try to switch to my X console afterward, I get the same graphics corruption and have to do the 3-finger salute (with SysRq). BUT, if, with X stopped, I rmmod -f intel-agp (the -f is necessary since it thinks it's in use) and then restart X, it works. Building intel-agp into the kernel doesn't fix it. I'm not sure why intel-agp thinks it's in use when it isn't, but that may be part of the problem (if it thinks it's in use it won't remove itself properly, so it won't reinsert itself properly on restart, so things get munged up). By the way, just rmmoding and modprobing intel-agp while X is running doesn't stop it from locking up the display.

    Update

    With the VESA video driver, suspend to disk works. I haven't played with it enough to know whether it stops and restarts everything properly (I suspect it doesn't), but fixing that shouldn't be any more complicated than modifying the script I used for suspend to RAM.

    Controlling the Backlight

    There's a package called radeontool that lets you control the backlight. Running radeontool light tells you the current status of the backlight; tacking on or off to the end turns the backlight on or off, respectively. Apparently the backlight is the biggest power sink for a laptop running on batteries; if I can't get suspend-to-RAM working properly, I may use this command as part of a "turn-off-backlight-and-drop-CPU-to-slow-speed" function controlled by one of the thinkpad buttons; see my discussion of the tpb command for more info about this.

    CPU Speed Control

    I think I've got this working properly now. First, you need a 2.6 kernel that supports the Centrino speedstep feature (the 2.6.7 series and later should; not sure about earlier ones), and you need to either build it into the kernel or make it a module (I built it in). You should also build in the userspace cpufreq driver in the kernel; you don't need the powersave or performance drivers.

    One of the sites linked above referred to an /etc/cpuspeed.conf file, but I think that's largely if not entirely unnecessary with Gentoo. You have to emerge the cpufreqd package, and put this cpufreqd.conf file (borrowed from one of the links above, with minor tweaks) into the /etc dir. This file divides CPU control into two parts: Profiles specify what speeds the CPU can run at, and Rules specify the conditions under which each profile is used. For example, the ac_powered_high profile runs the CPU at full speed, and is used by the ac_on_high rule (when the AC adapter is in and the CPU load is heavy) and by the compiling_ac rule (when any of various compilation programs is running, regardless of the load). When the AC is on but the load is low, the ac_powered_low profile drops the CPU speed to 800 MHz; this keeps the laptop from getting too hot (it also differs from the minimum of 600 MHz, so you know that cpufreqd is running if you've got an 800 MHz clockspeed).

    ACPI System Interface

    With the 2.6 kernels, and with modern laptops, it's recommended to use ACPI rather than APM for power management. The reason for the change is that with APM, laptops handled power management on their own, often without telling the operating system what they were doing. With ACPI, the laptop tells the OS what's going on, so the OS can (for example) sync disks before suspending. In Linux, that means that ACPI sends messages to the kernel, which then has to handle those messages. So functions like suspending, resuming, etc. don't work automatically. Linux provides a daemon, acpid to detect these messages and figure out what to do.

    To use acpid, you need to have entries in the /etc/acpi directory. When an ACPI event comes in, acpid searches /etc/acpi/events to find a matching event, and runs the script listed for that event. I've only got one relevant file, default, in /etc/acpi/events. It just captures events and passes them to the default.sh script in /etc/acpi. This script determines what to do when various actions (button presses, power adapter (un)plugging, etc. Hitting the power button runs shutdown -h, and hitting sleep (Fn-F4?) runs the /usr/local/sbin/hibernate script (suspend-to-disk using swsusp2). The default.sh script refers to three other scripts, lid.sh, ac.sh, and battery.sh, which are all in /etc/acpi/actions. Right now I've got the lid.sh script trying to put the laptop into standby mode (which isn't fully working for me yet), and the ac.sh and battery.sh scripts control laptop_mode (which supposedly reduces drive spin up/down, and is in the standard 2.6.6+ kernels).

    As I've mentioned above, I've had a bit of trouble getting suspend-to-disk and suspend-to-ram working properly, but I'm close. Also, with ACPI support built into my kernel, I get this error in dmesg on startup:

    ACPI: Found ECDT
        ACPI-0179: *** Warning: The ACPI AML in your computer contains errors, please nag the manufacturer to correct it.
    
    I suspect that part of the ACPI problem may be due to the fact that the BIOS configures all devices to use IRQ 11 by default; I'll have to play with that to see if it makes any difference.

    Infrared Port Control

    I haven't played with this at all yet.

    Dual-Booting Linux and Windows

    This was as easy as it is on any other computer. I used Partition Magic in Windows to resize the Windows partition to about 20 GB. I also created a 5 GB FAT32 partition to make it easy to move files back and forth between Windows and Linux. I left the IBM partition intact for now; if I need more space later, I can delete both of those partitions and give myself an extra 10 GB. I set up Windows first, knowing that I wasn't likely to boot into it too often in the future. Once I had run Windows Update about 20 times and installed all the software I was likely to need, I resized the partition. Then after setting up Gentoo, I installed grub the way I normally do (essentially, the way the Gentoo Handbook says to do it), and everything just worked.

    Running VMWare Workstation

    VMWare just works. Of course, with the VESA video drivers it has problems with full-screen mode, but that's a problem I'll have to work on from the video driver standpoint rather than vmware. Maybe the non-proprietary Radeon drivers will work better.

    Running Vid

    Vid is a program we use within our lab group for giving presentations. We have several different versions. Sdlvid works fine in windowed mode, but doesn't display properly in full-screen mode. I suspect this is due to a problem with the VESA drivers (it's trying to do 1024x768 on a 1600x1200 screen). I've configured cpufreqd to run the processor at full speed when vid is running.

    Monitoring Hardware Sensors

    Haven't played with this at all yet.

    TV Output

    Haven't played with this at all. I need a TV with an S-video input.

    Disabling the Touchpad

    If you prefer the matchstick-style mouse interface, like me, you might want to disable the touchpad below the keyboard. To do this, just press F1 while the IBM boot screen is displayed during bootup (it doesn't say you can press F1, but you can) to get to the BIOS. From there you can disable the touchpad.

    Autoconfiguring Wired/Wireless Networking

    Also haven't played with this.

    Displaying Proper Time in Linux and Windows

    Unfortunately getting this to work means storing local time rather than UTC time in the hardware clock. The reason this is

    Displaying Feedback of Thinkpad Buttons

    Enabling a High-Res Console

    Enabling a Bootsplash Console

    Printing

    Setting up printing was fairly easy. I did most of the configuration through CUPS using KDE's Printer config tool (under Printers in the KDE Control Center). However, the page size seems to default to A4 rather than Letter under certain conditions - which would be fine, except I'm in the U.S. where we need Letter size. So I had to change /etc/enscript.cfg so "DefaultMedia: A4" became "DefaultMedia: Letter", and change /usr/share/texmf/dvips/config/config.ps to move the "A4size" section below the "letterSize" section (which is the only way I could see to get LaTeX to use Letter size).