I bought a DellInspiron6000 to replace my aging iBook. The iBook was a good machine, but it's currently in a state where it doesn't boot reliably and the battery lasts 45 minutes at best. Since it's 3 years old, I decided I'd stop spending money trying to fix it up and just buy another laptop for myself. And I went PC instead of Mac since I just put Linux on my Mac anyway, and at that point you might as well have a PC (Macs are still good laptops though, and if you want a light laptop and like OS X enough to live with it, then go for it, you won't regret it!)

Anyway, being the geek that I am, I of course want GentooLinux on my DellInspiron6000. I use this page and some page to keep track of all the things I've done and how I got everything working:

Description

Working

Overall, this is a very good Linux machine and I'm pretty happy with it. Most things work well (as you can see above) and the battery life is usually more than 5 hours. The machine is a little big, but I really like the nice big screen, so it's worth it for me.

Things TODO

HOWTO

Gentoo install

I did a stage 3 install using the pentium3 tarball. CFLAGS are -march=pentium3 -O2 -pipe; I like to keep it simple. Remember that the Pentium M really is a P3 derivative, not a P4.

If you need to do the install over wireless and you need NdisWrapper, get the RR4 livecd (even if you don't want Reiser 4) since it has NdisWrapper on it. Before wiping the Windows NTFS partition that was on the disk, I mounted it and copied the wireless drivers off to get NdisWrapper going during the install:

Of course, if you have the Intel PRO wireless or you're doing the install over ethernet then the standard Gentoo ISO will be fine.

Kernel

My [kernel .config] file (for 2.6.17.11). In addition to that, I use some [patches], containing bugfixes to various drivers and suspend-related issues.

If you don't use my config file, make sure you enable SATA in the kernel, with the Intel PIIX controller. I just compiled it into my kernel, because I like to avoid dealing with initrd whenever I can. Note that because the system uses SATA, your hard disk will be accessed via /dev/sda, and the DVD drive via /dev/scd0.

Apply the patches as follows:

Then configure, compile and install your kernel as usual.

CPU throttling

Here's my file:

[General]
	pidfile=/var/run/cpufreqd.pid
	poll_interval=2
	verbosity=4
[/General]

[Profile]
name=On Demand High
minfreq=50%
maxfreq=100%
policy=ondemand
[/Profile]

[Profile]
name=On Demand Low
minfreq=25%
maxfreq=75%
policy=ondemand
[/Profile]

[Profile]
name=Powersave
minfreq=25%
maxfreq=50%
policy=powersave
[/Profile]

##
# Basic states
##
# when AC use performance mode
[Rule]
name=AC Rule
ac=on                    # (on/off)
profile=On Demand High
[/Rule]
 
# conservative mode when not AC
[Rule]
name=AC Off - Low Battery
ac=off                   # (on/off)
battery_interval=0-30
profile=Powersave
[/Rule]

# conservative mode when not AC
[Rule]
name=AC Off - Medium Battery
ac=off                   # (on/off)
battery_interval=30-70
profile=On Demand Low
[/Rule]

# stay in performance mode for the first minutes
[Rule]
name=AC Off - High Battery
ac=off                   # (on/off)
battery_interval=70-100
profile=On Demand High
[/Rule]

##
# Special Rules
##
# CPU Too hot!
[Rule]
name=CPU Too Hot
acpi_temperature=55-100
cpu_interval=50-100
profile=On Demand Low
[/Rule]

# use performance mode if I'm watching a movie
# I don't care for batteries! 
# But don't heat too much.
[Rule]
name=Movie Watcher
programs=xine,mplayer,gmplayer
battery_interval=0-100
acpi_temperature=0-60
cpu_interval=0-100
profile=On Demand High
[/Rule]

Suspend to RAM

Once you have a kernel with the above patch installed, this is actually pretty easy to set up. First you'll need vbetool installed, to reset video after resuming:

Then, you'll want the following in /usr/local/sbin/acpi_sleep:

#!/bin/sh

FGCONSOLE=/usr/bin/fgconsole
MODPROBE=/sbin/modprobe
VBETOOL=/usr/sbin/vbetool
KILLALL=/usr/bin/killall
UMOUNT=/bin/umount
UNAME=/usr/bin/uname
CHVT=/usr/bin/chvt
SYNC=/usr/bin/sync
FIND=/usr/bin/find
GREP=/bin/grep
AWK=/usr/bin/awk
CUT=/usr/bin/cut
SED=/usr/bin/sed
MEDIA=/media
IFACES="eth0 wlan0"
ACTION="$(basename $0)"
KMAJOR=$($UNAME -r |$SED -re 's/(^[0-9]\.[0-9]).*/\1/')
MODLOAD=/etc/modules.autoload.d/kernel-$KMAJOR

# determine current console number
currentvt=$($FGCONSOLE 2> /dev/null)

# switch away from X11, to avoid touchpad lockup on resume
if [ ! "$currentvt" = "12" ]; then
    $CHVT 12 2> /dev/null
fi

# flush buffers to disk
$SYNC
$SYNC

# unmount media and nfs filesystems
$UMOUNT -aft nfs
for i in $($FIND $MEDIA -type d |$GREP -vE "^\\$MEDIA\$" 2> /dev/null); do
    $UMOUNT $i 2> /dev/null
done

# stop network
for i in $IFACES; do
    /etc/init.d/net.$i stop > /dev/null 2>&1
done

# in case network was started outside scripts
$KILLALL -HUP dhcpcd > /dev/null 2>&1

# unload modules (except sound and vmware)
for i in $($AWK '{print $1}' /proc/modules |$GREP -vE "^(snd|vm)" 2> /dev/null); do
    $MODPROBE -r $i 2> /dev/null
done

# flush buffers to disk
$SYNC
$SYNC

# go into standby
case "$ACTION" in
suspend)
    echo -n mem >/sys/power/state
    ;;
hibernate)
    echo -n disk >/sys/power/state
    ;;
*)
    echo "Unknown sleep action $0"
    ;;
esac

# emerge from standby on resume

# load modules
for i in $($GREP -vE '^(#|[:space:]*$)' $MODLOAD |$CUT -d '#' -f 1); do
    $MODPROBE $i 2> /dev/null
done

# reinitialize video to get text console working again on resume
$VBETOOL post

# switch back to original console/X11 screen
if [ ! "$currentvt" = "12" ]; then
    $CHVT $currentvt
fi

You might ask "do I really need all this junk?" I find it is generally a good idea to shut down network interfaces when suspending; you will probably not be on the same network when you wake up anyway. Similarly, unmounting nfs and local media makes sense; they may not be available when you wake up. Unloading and reloading modules, however, isn't strictly necessary. However, I have found that doing this improves the stability of suspend. Some modules apparently still don't play nice with suspend, so the fewer you have loaded when you suspend, the more likely it is that resume will succeed.

Now symlink this to the suspend and hibernate actions:

Now edit /etc/acpi/default.sh to have an entry for the "sleep" button:

#!/bin/sh
# Default acpi script that takes an entry for all actions

set $*

group=${1/\/*/}
action=${1/*\//}

case "$group" in
        button)
                case "$action" in
                        power)  /sbin/init 0
                                ;;
                        sleep)  /usr/local/sbin/suspend
                                ;;
                        *)      logger "ACPI action $action is not defined"
                                ;;
                esac
                ;;

        *)
                logger "ACPI group $group / action $action is not defined"
                ;;
esac

Finally, you'll need the button ACPI module loaded (if you did indeed compile it as a module; my .config does have it as a module):

Now when you push Fn-Esc, which is the "stand by" key, your laptop should go to sleep! Pushing the power button will (hopefully) bring it back. For me, everything worked after resume; wireless, sound, touchpad, etc. were all fine. I was pretty surprised; I expected it not to work.

Xorg @ native LCD resolution

Add the following:

# Sketchy x11 because stable one is slooooow
media-libs/mesa ~x86
x11-base/xorg-server ~x86
x11-drivers/synaptics ~x86
x11-drivers/xf86-input-evdev ~x86
x11-drivers/xf86-input-keyboard ~x86
x11-drivers/xf86-input-mouse ~x86
x11-drivers/xf86-video-i810 ~x86
x11-drivers/xf86-video-vesa ~x86

Add the following:

# Xorg features
VIDEO_CARDS="i810 vesa"
INPUT_DEVICES="evdev mouse keyboard synaptics"

Here are the relevant sections of my file:

Section "Monitor"
    Identifier  "Dell 1680x1050 LCD"
    HorizSync   31.5 - 100
    VertRefresh 60
    DisplaySize 320 200
    Option      "DPMS"
EndSection

Section "Device"
    Identifier  "Intel i915"
    Driver      "i810"
EndSection

Section "Screen"
    Identifier  "Screen 1"
    Device      "Intel i915"
    Monitor     "Dell 1680x1050 LCD"
    DefaultDepth 24

    Subsection "Display"
        Depth       8
        Modes       "1680x1050" "1280x1024" "1024x768" "800x600" "640x480"
        ViewPort    0 0
    EndSubsection
    Subsection "Display"
        Depth       16
        Modes       "1680x1050" "1280x1024" "1024x768" "800x600" "640x480"
        ViewPort    0 0
    EndSubsection
    Subsection "Display"
        Depth       24
        Modes       "1680x1050" "1280x1024" "1024x768" "800x600" "640x480"
        ViewPort    0 0
    EndSubsection
EndSection

Note that this will leave X displaying rather large fonts. To make things a bit more sane, I modified the startx script to pass -dpi 100 to the X server:

defaultserverargs="-dpi 100 -nolisten tcp -br"

Screen blanking

I didn't do anything fancy to have different delays blanking the display when plugged in vs. on battery. That would be a good idea if I were, for example, planning to give a presentation with this machine :) Right now, it just blanks (and by "blank" I mean VESA standby mode, not drawing black) after 5 minutes in.

First, we modify /etc/conf.d/local.start to do a setterm so consoles blank properly:

# Set terminals to VESA powerdown after 5 minutes to save batter power.
/usr/bin/setterm -blank -powerdown 5 > /dev/null 2>&1

And then the following in /etc/X11/xorg.conf does the same in X11:

Section "ServerLayout"
    ...
    Option      "BlankTime"     "0"
    Option      "StandbyTime"   "5"
    Option      "SuspendTime"   "10"
    Option      "OffTime"       "15"
    ...
EndSection

Trackpad scrolling

If you have a recent kernel (recent >= 2.6.11.x, I believe) no kernel patching is necessary. Make sure you have evdev built. Then you'll need the synaptics X driver:

Here are the relevant sections of my config:

Section "Module"
    ...
    Load        "synaptics" # probably not strictly necessary
    ...
EndSection
...
Section "InputDevice"
    Identifier  "ALPS GlidePoint"
    Driver      "synaptics"

    Option      "Device"                "/dev/psaux"
    Option      "Protocol"              "auto-dev"
    Option      "LeftEdge"              "120"
    Option      "RightEdge"             "830"
    Option      "TopEdge"               "120"
    Option      "BottomEdge"            "560"  # comment out this entire line to disable horizontal scroll/click ability
    Option      "FingerLow"             "14"
    Option      "FingerHigh"            "15"
    Option      "EmulateMidButtonTime"  "70"
    Option      "VertScrollDelta"       "20"
    Option      "HorizScrollDelta"      "20"
    Option      "MaxTapTime"            "0"    # 0 disables tap-to-click, set it to 100 to re-enable
    Option      "MinSpeed"              "0.3"
    Option      "MaxSpeed"              "0.75"
    Option      "AccelFactor"           "0.015"
    Option      "EdgeMotionMinSpeed"    "200"
    Option      "EdgeMotionMaxSpeed"    "200"
    Option      "UpDownScrolling"       "1"
    Option      "LeftRightScrolling"    "1"
    Option      "CircularScrolling"     "0"
EndSection

Section "InputDevice"
    Identifier  "External Mouse"
    Driver      "mouse"

    Option      "Device"                "/dev/input/mice"
    Option      "Protocol"              "imps/2"
    Option      "Emulate3Buttons"       "no"

    Option      "Buttons"               "5"
    Option      "ZAxisMapping"          "4 5"
EndSection
...
Section "ServerLayout"
    ...
    InputDevice "ALPS GlidePoint" "CorePointer"
    InputDevice "External mouse" "AlwaysCore"
    ...
EndSection

Adding in both mice lets you just plug in a USB mouse and have it work right away, in addition to the touchpad, which is handy.

Lazy?

For the lazy, here is a link to my [complete xorg.conf].

Multimedia keys

If you are using [GNOME] or [KDE] then there is probably already a method for you to setup special multimedia keys in that environment. I use [Ion] on my laptop, so I need something else. hotkeys fits the bill nicely:

Here's my file:

<?xml version="1.0"?>

<definition>

  <config model="Dell Inspiron 6000 Keyboard">

    <PrevTrack  keycode="144"/>
    <Stop       keycode="164"/>
    <Play       keycode="162"/>
    <NextTrack  keycode="153"/>

    <VolUp      keycode="176" adj="2"/>
    <VolDown    keycode="174" adj="2"/>
    <Mute       keycode="160"/>

  </config>

  <contributor>
    <name>Some Guy</name>
    <email>someguy@foo.com</email>
  </contributor>

</definition>

Now we need to edit /etc/hotkeys.conf and set Kbd=inspiron6000.

Finally, edit /etc/X11/Sessions/ion2 to make sure hotkeys is started whenever an [Ion] Xsession is started:

#!/bin/sh
HOTKEYS="$(which hotkeys 2> /dev/null)"
if [ -x "$HOTKEYS" ]; then
    "$HOTKEYS" -o 1 -F 1 -Z > /dev/null 2>&1 &
fi

# Below: poor man's gnome-session :P
DBUS_LAUNCH="$(which dbus-launch 2> /dev/null)"
if [ -x "$DBUS_LAUNCH" ]; then
    GNOME_VOLUME_MANAGER="$(which gnome-volume-manager 2> /dev/null)"
    if [ -x "$GNOME_VOLUME_MANAGER" ]; then
        "$DBUS_LAUNCH" "$GNOME_VOLUME_MANAGER" > /dev/null 2>&1 &
    fi

    GNOME_KEYRING_DAEMON="$(which gnome-keyring-daemon 2> /dev/null)"
    if [ -x "$GNOME_KEYRING_DAEMON" ]; then
        eval "$("$DBUS_LAUNCH" "$GNOME_KEYRING_DAEMON" 2> /dev/null)"
        export GNOME_KEYRING_SOCKET
        export GNOME_KEYRING_PID
    fi

    BEAGLED="$(which beagled 2> /dev/null)"
    if [ -x "$BEAGLED" ]; then
        "$DBUS_LAUNCH" "$BEAGLED" > /dev/null 2>&1
    fi

    GNOME_SERVERDIR="$(pkg-config --variable=libgnome_serverdir libgnome-2.0)"
    GNOME_SETTINGS_DAEMON="$GNOME_SERVERDIR/gnome-settings-daemon"
    if [ -x "$GNOME_SETTINGS_DAEMON" ]; then
        "$DBUS_LAUNCH" "$GNOME_SETTINGS_DAEMON" > /dev/null 2>&1 &
    fi
else
    DBUS_LAUNCH=""
fi

SSH_AGENT="$(which ssh-agent 2> /dev/null)"
"$SSH_AGENT" "$DBUS_LAUNCH" /usr/bin/ion2

This session script launches the dbus session bus, gnome-settings-daemon (useful if you want your gnome settings to actually be applied), gnome-volume-manager, gnome-keyring-daemon, beagled and ssh-agent. Obviously if you don't want any of those things running you should remove them.

MMC/SD card reader

This is working via the sdhci kernel module; it is enabled in my config file, and there is a bugfix in my patchset (though the driver is now included in mainline 2.6.17). I haven't used it extensively, but it does seem to work. You will need to modprobe sdhci and mmc_block. The device appears as /dev/mmcblk0, with the first partition being /dev/mmcblk0p1.

Wireless

I recently purchased an Intel PRO/wireless 2200bg card and have been using the in-kernel ipw2200 module. The only small piece of configuration work I did was to install ipw-firmware and use udev to ensure the interface always gets named wlan0:

KERNEL=="eth*", SYSFS{address}=="00:00:00:00:00:00", NAME="wlan0" # you will need to fill in your own MAC address

The stock kernel module is now working very reliably, as of 2.6.17. I would recommend buying an Intel PRO/wireless card if you got stuck with the Broadcom one; they're only about 30USD and the Linux support is much better.

There is also now an open-source native driver for the Broadcom cards, available in gentoo as bcm43xx. I tried it briefly and didn't have much luck, but it is always getting better. The following information about NdisWrapper is now no longer relevant for me, but it might be useful for some people:

Note that I was experiencing intermittent lockups when modprobing ndiswrapper on battery power. Upgrading from kernel 2.6.11.7 to 2.6.11.10, adding kernel parameters pci=bios and setting the BIOS boot mode to "thorough" seems to have stopped the lockups. However, I'm not sure which of these 3 things actually fixed it, since they all happened at roughly the same time. I'm betting it's the pci=bios kernel parameter, though.

Anyway, aside from that caveat, getting NdisWrapper going is pretty easy:

Ethernet

Just Works. Use b44 module.

Disk spindown

If you use the kernel patch posted above, you can set some parameters with hdparm, including in particular the spindown time. You'll obviously need hdparm

My file has only one uncommented line

sda_args="-S36" # set spindown time to 3 minutes

You'll also probably want to use laptop-mode. It's pretty simple to get going (I didn't modify the default configuration):

ALSA dmix sound mixing

Edit /etc/asound.conf and add the following:

pcm.dsp0 {
    type plug
    slave.pcm "dmix"
}

ctl.mixer0 {
    type hw
    card 0
}

pcm.!default {
    type plug
    slave.pcm "dmix"
}

Now set every application you use for sound to use alsa. Fortunately, this isn't too bad because many applications use [GStreamer] and you can set alsa for all those applications all at once using gstreamer-properties. Then I also set beep-media-player (set in the GUI preferences), mplayer (set ao=alsa in /etc/mplayer.conf) and mplayerplug-in (set ao=alsa in /etc/mplayerplug-in.conf) manually.

For applications that only support oss, you can still make them use dmix:

Now put this wrapper script in /usr/local/bin/aoss_wrapper:

#!/bin/bash
EXC_DIR_REAL="$(dirname $0)"
EXC_DIR_LINK=""
if [ "$EXC_DIR_REAL" = "." ]; then
  EXC_DIR_REAL="$(/bin/pwd)"
  EXC_DIR_LINK="$(pwd)"
fi

PATH_LIST="$(echo "$PATH" |perl -pe 's/:/ /g')"
PATH_SAFE=""

# clean the script directory out of path
for i in $PATH_LIST; do
  if [ "$i" = "$EXC_DIR_REAL" -o "$i" = "$EXC_DIR_LINK" ]; then
    continue
  fi

  if [ -z "$PATH_SAFE" ]; then
    PATH_SAFE="$i"
  else
    PATH_SAFE="$PATH_SAFE:$i"
  fi
done

PATH="$PATH_SAFE"
APP_NAME="$(basename $0)"
APP_REAL="$(which "$APP_NAME")"

export LD_PRELOAD="libaoss.so"
exec "$APP_REAL"

Now to run those pesky oss-only applications using dmix, all you have to do is:

Unfortunately, this doesn't work properly with quake 3. If I use the wrapper the sound is all messed up. However, it does work for firefox. That way flash can still play sound if another app has /dev/dsp open. A lot of media players keep /dev/dsp open even when they're not playing music or, so this is useful. Having flash be able to play sound is somewhat dubious.