[Linux on Laptops]

Linux on the Dell X200

Author: Lincoln Stein <lstein@cshl.edu>

Update 4 Oct 2003: See booting Knoppix on a firewire cdrom for information on how I made a bootable Knoppix distribution for the X200.

Introduction

The Dell Latitude X200 is an ultralight 933 MHz Pentium III-M that weighs in at 2.8 lbs. It is made by a Korean manufacturer (Samsung, I think) and relabeled by Dell. Gateway also sells a rebranded version of the same system. The graphics chip is the Intel i830M which provides good 2D performance and not-too-bad 3D acceleration on the 12" SVGA LCD. The machine comes with a PCTel Winmodem and a Ricoh R5C551 FireWire (IEEE 1394) controller of the "OHCI" type. It has two USB 2.0 ports, a Synaptics touchpad and a single 32 bit PC-Card slot. A mini-PCI IEEE 802.11b WI-FI card (based on the Lucent chipset) is included, as is an external firewire CD-ROM. The only hard disk option available from Dell is 30 GB. The base system does not come with a floppy drive (though any third-party USB floppy should work), and does not have legacy PS/2, serial or parallel ports. More hardware information can be found in my/proc/pci dump.

I got mine after the keyboard died on my aging Dell Inspiron 2100. I purchased a version with 384 MB of memory (expandable to 640 MB), the optional DVD-CDRW, and Windows XP professional. I did not get the docking station/media base, but Dell did send me a complementary leather carrying case that weighs about five times as much as the computer itself.

Bottom line: Everything works: X with 3D acceleration, the firewire CD drive, wireless, power management, USB, and even the WinModem. There are a couple of lingering annoyances that I haven't figured out.


First Pass: Mandrake Installation

I am a long-time fan of the Slackware distribution, because it is about as vanilla a distribution as you can get. Patrick Volkerding tends to do very little tinkering with the various packages that go into a full Linux system, and hence there are few surprises.

However, the boot kernels that Slackware distributes do not come with firewire support, which means that while the Slackware CD will boot Linux up through the login stage, it cannot find the install media. Another issue is that the system came with the entire internal hard drive formatted with a 30 GB NTFS partition, and FIPS, the partition resizing tool distributed with Slackware, can only deal with (V)FAT1. I opted instead to install the Mandrake distribution (version 9.1), which supports both firewire installation and NTFS resizing.

Booting

After downloading and burning the Mandrake installation, I booted the first install CD. By default, the Dell is set to boot from the internal hard disk first, even if there is a CD in the drive. You must hold down the F12 key at boot time in order to bring up a menu that allows you to select the CD as the boot medium (you can also change this permanently from the BIOS setup).

All went swimmingly until Mandrake tried to mount the installation medium, at which point it failed to find the CD. It then displayed a prompt asking me to select a kernel module to use to mount a SCSI device. To activate the firewire drive, I discovered that I had to select two modules, ohci1394.o and spb2.o in that precise order. This involves a lot of scrolling, as both modules are towards the bottom of a long list. After selecting ohci1394.o the attempt to mount the CD will again fail and Mandrake will display the kernel module prompt a second time. After selecting sbp2.o, the CD will mount and installation will continue.

Repartitioning

The next step was to repartition the hard disk, using a tool called "DiskDrake". This is a sweet application that lets you manipulate the partitions graphically. The first partition is a 32 GB "Dell Utility" partition that seems to contain a bootable MSDOS system. I don't know what it's for, so I left it intact. I reduced the NTFS system to 10 GB, created a 2.5 GB / partition, a 650 MB swap partition, and left the rest for /home. As explained later, the / partition was insufficient for all the goodies in a full Mandrake install.

The remainder of the installation was unremarkable. Mandrake correctly detected and configured the graphics adaptor, LCD screensize, touchpad, wireless card, sound chip, and even detected and configured the USB mouse that I had attached at the time.

Rebooting

After rebooting, everything was fine -- almost. There was something awry with the APM support. Suspend/resume did not work, causing a freeze on resume, and oddly enough the function key combination that changes screen brightness caused a crash (this has been reported elsewhere). The solution to both problems was to recompile the kernel with "APIC support on uniprocessors" turned off, APM compiled as a module, and ACPI support turned off. Note that you have to use the version of the kernel source code that Mandrake supplies as an RPM. Do not use a vanilla kernel.

The firewire CD drive works if it is plugged in at boot time, but it has problems with plugging and unplugging. See Problems.

Getting the Modem to Work

Mandrake doesn't automatically support the internal model. To get it to work, download the PCTel driver from http://linmodems.technion.ac.il/pctel-linux/, and compile it with the following commands:

% ./configure --with-hal=i8xx
% make
% make install
The installation will create a device special file /dev/ttyS15 for communication with the modem. It will also create a symbolic link to this device from /dev/modem

Then add the following to your /etc/modules.conf file:

# pctel modem
insmod_opt=-f
alias char-major-62 ptserial

The first line passes the -f option to all calls to insmod. This is necessary to load the PCTel driver, because it is distributed without an open source license and insmod will refuse to load such "tainted" modules without the "force" flag.2 The second line autoloads the ptserial module when /dev/ttyS15 is accessed.

Problems

Under the Mandrake install, the firewire device drivers appear not to be able to survive a suspend and resume cycle, rendering the external drive inoperative. If no CD was mounted at the time of the suspend, I have been able to recover from this sometimes by manually rmmod'ing the sbp2 and ohci1394 modules and then reinserting them. Worse, however, plugging and unplugging the firewire drive multiple times quickly puts the sbp2 module into a frozen state after which it can't be used or removed without a reboot. See the Slackware discussion below for a way of working around this.

I have found that loading the modem driver disables sound completely. The only solution is to manually unload the modem modules with rmmod, unload the sound modules (i810_audio), and then reload the sound modules.


Second Pass: Slackware Installation

I guess I'm a glutton for punishment. After playing with it for a day or so, I just couldn't get used to Mandrake. Among other things, Mandrake doesn't support my favorite window manager (FVWM - don't laugh), and ardently resisted my circa-1980 attempts to place my home directory under /usr/local. I also discovered that I had allocated too little room to the root partition, causing Mandrake to fill up all but about a couple of 100 MB of available space. I use a lot of /tmp, and hate running out. Another discovery that is that even the development Linux kernels have extremely limited support for writing to NTFS, and I would have to convert the NTFS partition to FAT if I wanted to create files on Linux and then copy them to Windows.

All this meant I had to reinstall anyway, and for the challenge as much as anything else, I decided to get Slackware 9.0 running on the X200. Since Slackware's boot kernels don't support the firewire drive, this called for some extreme measures:

  1. Remove the existing NTFS partition and replace it with a FAT32 partition (but keep the Dell Utilities partition!)
  2. Reinstall Windows XP on the FAT32 partition using the recovery disk provided by Dell.
  3. From within Windows copy the Slackware CDROM to the C: drive.
  4. Reboot with the Slackware boot disk, then specify the C: drive (partition /dev/hda2 as the location of the install media.
  5. Lots of post-install fussing.

Post-install fussing consisted of the following:

  1. Making 3D graphics acceleration work with X11.
  2. Getting hotplugging of the firewire CD drive to work reliably.
  3. Getting the Modem to work.

Making 3D graphics acceleration work with X11/Slackware

The stock 2.4.21 kernel needs to be modified to support XFree86-4.3's DRM (direct rendering manager) driver. I got the DRM distribution at http://dri.sourceforge.net/, which is distributed as the tarball linux-drm-4.3.0-kernelsource.tar.gz. After downloading the tarball, I went to the stock 2.4.21 kernel and ran the following commands:

% cd drivers/char
% mv drm drm.old
% tar zxvf ~/linux-drm-4.3.0-kernelsource.tar.gz
% cd drm
% rm Makefile
% ln -s Makefile.kernel Makefile

It was then simply a matter of recompiling the kernel with the support for DRM on the i830 turned on. Here are copies of my configuration files for the kernel and for XFree86:

The XF86Config also shows how I added dual support for the built-in touchpad and an external USB scrollmouse.

Hotplugging the Firewire Drive

When operational, the firewire CD appears as a SCSI CD device named /dev/scd0. I created a symbolic link from /dev/cdrom to this device, thereby allowing the default Slackware fstab to mount and unmount it. However, getting the drive to an operational stage was more of a challenge.

Newer Linux kernels supports plugging and unplugging of peripherals via the "hotplug" architecture. The architecture invokes a series of shell scripts located in /etc/hotplug whenever certain events occur. Whiole the system seems to works well for USB, the firewire system has problems, mostly I think relating to the lack of good hotplug support in the SCSI system.

As background to the discussion, you should know that there are three kernel modules involved in handling firewire drives. sbp2 is a higher level driver which manages storage devices, ohci1394 manages the particular firewire controller used in the X200, and ieee1394 contains functions that are common to the firewire protocol.

I encountered three classes of problems:

  1. firewire drive not recognized when plugged in
  2. plugging and unplugging the firewire drive causes the firewire subsystem to become unusable
  3. firewire subsystem unable to survive an apm suspend/resume

In order to solve these problems, I had to perform major surgery on /etc/hotplug and minor surgery on the APM subsystem. There were three tricks involved. One was to install a script named rescan-scsi-bus.sh written by Kurt Garloff. This script is called by the hotplug system to scan the SCSI bus and after a firewire disk install/remove event and to inform the system of any new drives added or removed. This solved problem (1). The second trick was to arrange to rmmod sbp2 whenever all devices managed by it were removed, which solved problem (2). The third trick was to automatically rmmod ohci1394 prior to an apm suspend event. Tricks (2) and (3) are definitely hack workarounds. Please contact me if you know of a better way.

Here is a new version of /etc/hotplug which contains the fixes for problems (1) and (2):

The changes are:

  1. Updated ieee1494.agent and hotplug.functions files taken from the CVS development branch of the Linux hotplugging project.
  2. ieee1394/rescan-scsi-bus.sh added to scan the SCSI bus on insertions
  3. ieee1394/sbp2 script added to invoke rescan-scsi-bus.sh and to unload the sbp2 module when no longer in use.
  4. corrected a minor bug (logical NOT) in net.agent that was preventing it from catching PC network card insertions/removals.

To fix the problem with suspend/resume, I wrote and installed the script /etc/apmd_proxy3. This simply unloads ohci1394 on suspend/standby events, and reloads it on resume events.

A problem with this approach is that if a CD is mounted when you either unplug the firewire or suspend/resume the system, then the modules don't get unloaded and are useless when you replug or resume. Always unmount the CD before unplugging or suspending!

However, there are other problems with APM-managed suspend/resume. I eventually gave up on APM entirely and went to ACPI and Software Suspend. See Installing ACPI & Swsusp for details.

Getting the Modem to Work

I used the same procedure as described above.


Other Notes

DVD Viewing
For DVD viewing I use mplayer. Playback is very smooth. However, I had to make mplayer SGID for the "disk" group:
      % chgrp disk `which mplayer`
      % chmod g+s `which mplayer`
      

CD ejecting
Similarly, I had to make eject SGID for the disk group in order for it to work as non-root.

Restoring sound mixer levels
Mandrake sets the default sound volume correctly so that it is maintained between boots, but Slackware does not. To ensure that the sound volume is maintained between reboots of the machine I installed mixerconfig, and then modified its volume save/restore script to work with the kernel module loader. My /etc/modules.conf now looks like this:
post-install i810_audio /usr/local/bin/mixerconfig -load /usr/tmp/audio.levels
pre-remove   i810_audio /usr/local/bin/mixerconfig -save /usr/tmp/audio.levels
alias sound-slot-0 i810_audio
alias sound-slot-1 i810_audio
alias sound-service-0-3 i810_audio
alias sound-service-1-0 i810_audio
      

CD Writing
For CD writing I just use mkisofs and cdrecord. These work fine and presumably more sophisticated applications will as well.

ACPI and Swsusp

After I wrote the above sections on APM, I realized that APM suspend/resume really doesn't work properly on the X200 and with 2.4.* kernels. The symptom is that after at least one cycle of suspend/resume, the APM module becomes liable to crash when the AC power status changes. The symptom is that you plug in the power cord and the system freezes up.

Perhaps there is a workaround (have the APM proxy script unload and reload the apm module itself? this seems dangerous). Instead I opted to chuck APM completely and to use ACPI. ACPI doesn't support suspend-to-RAM, but you can use an even better solution, Software Suspend (Swsusp), a kernel patch that will hibernate your entire state to a swap partition and then thaw it out at a later date. Although it is not as fast as save-to-RAM, it is a lot faster than shutting down and rebooting (~30s to hibernate and ~40s to resume), plus you don't have to worry about the suspend-state drawing current from the battery.

By this time kernel 2.4.22 was available. I recompiled it with ACPI support turned on, and discovered that everything worked except that the battery was not recognized. Since I want to know how much power is left in the battery, this was an issue. According to the Linux ACPI web site, this is due to Dell's BIOS description table being incorrect. To make a long story short, fixing this involved installing a new into the kernel. This needs to be done whenever the hardware configuration changes, as I discovered after upgrading the memory on my x200. Details of the operation are here.

After resolving this issue, I installed the BootSplash patches, and the Swsusp patches, as well as the updated DRM directory as described above, and configured the patched kernel. For your convenience, here is a complete diff between my patched and configured system and the vanilla 2.4.22 kernel. You can use this as a patch file to obtain a copy of the same kernel I use.

I then installed the following scripts, config files and utilities:

  1. /usr/local/sbin/hibernate from the Swsusp distribution.
  2. /etc/suspend.conf from the Swsusp distribution.
  3. /etc/acpi/acpi_handler.sh from the ACPI distribution.
  4. acpi, a little command-line utility for displaying battery status (but the KDE power applet also works with ACPI).
  5. The user-space splash utilities from bootsplash.org, with the standard "Linux" theme installed in /etc/bootsplash/themes.

The acpi_handler.sh script is set up so that I can initiate hibernate either by pressing the "Suspend" button (Fn-Esc) or by closing the lid. This script goes through some contortions in order to reset the firewire modules after hibernate completes. This is the only way that I found to ensure reliable restarts of the firewire bus.

Finally, here is the relevant section of /etc/lilo.conf:

# Linux bootable partition config begins
image = /boot/vmlinuz-swsusp
  root = /dev/hda3
  label = Linux
  initrd=/boot/initrd.splash
  append="resume=/dev/hda5"
  read-only
# Linux bootable partition config ends

You will need to change this for your partitioning scheme.

This was all horribly annoying and time-consuming, but I do have a reliable Linux laptop now. Maybe things will be easier by the time kernel 2.6 is stable.

Update December 3, 2004 According to Craig Maloney ACPI S3 suspend-to-ram is partially working as of kernel 2.6.9, but there are problems with the video similar to those described for APM. Here are more details about the problem: