Sunday 31 January 2016

ThinkPad X61 config

Fully functional ThinkPad X61 config

 

FreeBSD is a solid OS with good performance under high loading which makes it an excellent choice as a server OS. My love with it doesn't stop there. It has a great support community. Good documentation. A consistent init system. You may learn more about it in A FreeBSD 10 Desktop How-to.

As much as I love FreeBSD to be my main desktop OS, it has quite a few drawbacks. Due to its conservative out-of-the-box settings it's tedious to configure it. Lots of information on the Internet are somewhat outdated. Lack of software like Skype and Flash (despite its evilness). So I decided to write this guide for those, like me, who happen to own a ThinkPad X61 and want to slab a FreeBSD onto it. It also serves as a personal reminder for myself in case I need to start from scratch again.

It is an extensive setup guide that makes most of the things work, at least for 10.2-RELEASE-p7. See below for the complete list.

What works:
  • Graphics - vt, X11
  • Sound
  • Wifi
  • Ethernet
  • USB
  • Suspend/resume
  • Generic keyboard shortcuts - batt info, sleep, bluetooth on/off, trackpoint on/off, brightness, ThinkLight
What doesn't work or not tested:
  • TPM
  • Modem (who still uses it nowadays?)


/boot/loader.conf
linprocfs_load="YES"
linsysfs_load="YES"
acpi_ibm_load="YES"

# Do not load tpm as it's known to break suspend.
#tpm_load="YES"

ichsmb_load="YES"
ichwd_load="YES"
hwpmc_load="YES"
acpi_video_load="YES"
smapi_load="YES"
hifn_load="YES"
smbios_load="YES"
nvram_load="YES"
coretemp_load="YES"
i915kms_load="YES"
#sdhci_load="YES"
#mmc_load="YES"
vboxdrv_load="YES"

kern.vty=vt
kern.vt.gb.default_mode="1024x768"
#hw.vga.textmode="1"
drm.i915.enable_rc6=7
hw.acpi.reset_video=1

# Enable Trackpoint support
hw.psm.trackpoint_support="1"




/etc/sysctl.conf
dev.pcm.0.play.vchans=4
dev.pcm.0.rec.vchans=4

# Debug suspend/resume problem
#debug.acpi.resume_beep=1

vfs.usermount=1

dev.acpi_ibm.0.events=1
dev.acpi_ibm.0.handlerevents=0x17
hw.acpi.lid_switch_state=S3

# Enable shared memory support for Chromium
kern.ipc.shm_allow_removed=1

hw.psm.trackpoint.sensitivity=255

# The CentOS ports infrastructure has replaced Fedora 10 as default
# See UPDATING entry 20141209 for details
compat.linux.osrelease=2.6.18



/boot/device.hints
# Disable CPU throttling
#hw.pci.do_power_nodriver="3"
hint.acpi_throttle.0.disabled="1"
hint.p4tcc.0.disabled="1"



/etc/rc.conf
hostname="muon"
keymap="us.ctrl.kbd"
wlans_wpi0="wlan0"
ifconfig_wlan0="WPA DHCP"
sshd_enable="YES"
moused_enable="YES"
moused_flags="-z 4 5 6 7"
ntpd_enable="YES"
powerd_enable="YES"
#powerd_flags="-i 85 -r 60 -p 100"
performance_cx_lowest="Cmax"
economy_cx_lowest="Cmax"
uhidd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"
tcsd_enable="YES"
hald_enable="YES"
dbus_enable="YES"
syslogd_enable="YES"
syslogd_flags="-a freebsdap03.thds.mooo.com:* -v -v"
#proftpd_enable="YES"
cuse4bsd_load="YES"
webcamd_enable="YES"
linux_enable="YES"
fuse_enable="YES"

devfs_system_ruleset="system"
devfs_system_ruleset="localrules"

vboxnet_enable="YES"

nfs_server_enable="YES"
rpcbind_enable="YES"
mountd_flags="-r"
mountd_enable="YES"

amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"
automounter_enable="YES"




/usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf
Section "InputClass"
        Identifier "sysmouse0"
        MatchDevicePath "/dev/sysmouse"
        Option "EmulateWheel" "true"
        Option "EmulateWheelButton" "2"
        Option "YAxisMapping" "4 5"
        Option "XAxisMapping" "6 7"

EndSection



/usr/local/bin/acpi_osd
#!/bin/sh
#

DISPLAY_PIPE=/tmp/acpi_ibm_display
OSD="osd_cat"
FONT="-*-lucidatypewriter-*-*-*-*-*-240-*-*-*-*-*-*"
COLOR=Green
TIME=1
OPTS="--font=$FONT -c $COLOR -p top -o 50 -i 50 -d $TIME"

trap "rm -f $DISPLAY_PIPE" EXIT

[ -p $DISPLAY_PIPE ] || mkfifo $DISPLAY_PIPE

while true
do
        if read line <$DISPLAY_PIPE; then
                echo $line | $OSD $OPTS
        fi
done

exit 0



~/.xinitrc
if [ -x /usr/local/bin/acpi_osd ]; then
        /usr/local/bin/acpi_osd &
fi

Sunday 17 January 2016

FreeBSD 10.2 on Lenevo R61


This is a setup guide supplementary to the official handbook and FreeBSD 10.1 Desktop. With these settings you should be able to turn your R61 into a (almost) fully working laptop (see list below). Although these settings are tested on ThinkPad R61 only, if it works for your model, please make a comment and share your experience.

It assumes you're familiar with at least one text editor, the UNIX/Linux style commands and the setup files of FreeBSD, i.e. rc.conf, sysctl.conf, loader.conf. For a more general FreeBSD desktop setup guide, you're suggested to read these two articles apart from the excellent handbook:

 So, what works:
  • Most hotkeys and with OSD, i.e battery info, suspend, bluetooth switch, trackpoint/touchpad switch, hibernate, mute, vol up/down, brightness up/down, ThinkLight, ThinkVantage key
  • Multimedia keys (Fn + arrow keys)
  • TrackPoint and Touchpad with vertical and horizontal scrolling
  • Suspend/resume, hibernate
  • Fingerprint sensor
What doesn't or not tested:
  • A few hotkeys, i.e. video switch, dock eject, zoom (Fn + spacebar)
  • TPM device (it breaks suspend/resume)
For setting up the fingerprint reader, you may want to check out Gawen's blog since it's not specific to ThinkPad R61.


Update: On 10.2-RELEASE-p10, the X mouse driver refused to play nicely with moused. In my case, I had to
  1. turn off the "-V -H" options for moused in /etc/rc.conf
  2. use XAxisMapping and YAxisMapping instead of ZAxisMapping in /usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf

The list of files edited:
/boot/loader.conf
/etc/sysctl.conf
/etc/rc.conf
/usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf
/etc/devd/tp.conf
/usr/local/bin/acpi_osd
/usr/local/sbin/acpi_oem_exec.sh
/usr/local/etc/sudoers.d/moused


1. Now let's get down to business. First, install a few packages:

# pkg install nvidia-driver-340 xosd fprintd sudo
# pkg install xf86-input-synaptics xf86-input-mouse


2. Load the kernel modules:

/boot/loader.conf
zfs_load="YES"
acpi_ibm_load="YES"
acpi_dock_load="YES"
acpi_wmi_load="YES"

ichsmb_load="YES"
ichwd_load="YES"
coretemp_load="YES"


# NVIDIA module needs linux ABI
nvidia_load="YES"
linux_load="YES"


linsysfs_load="YES"
linprocfs_load="YES"
smb_load="YES"
speaker_load="yes"


# Filesystems in Userspace (for NTFS mount)
fuse_load="YES"


sbp_load="YES"


# Firewire module
fwe_load="YES"

i915kms_load="YES"


# For brightness
acpi_video_load="YES"

# Userland char device driver for webcams
cuse4bsd_load="YES"

# Asynchronous I/O
aio_load="YES"

#hw.acpi.reset_video=1

# Required by gamin
kern.maxfiles="25000"
hw.psm.synaptics_support="1"

# Reduce interrupt rate to save power
kern.hz=100

# Use vt instead of sc
#kern.vty=vt
#kern.vt.fb.default_mode="1440x900"
#hw.vga.textmode=1



/etc/sysctl.conf
# Enable horizontal scrolling
hw.psm.synaptics.vscroll_hor_area=1300


# Enable multiple sound input
dev.pcm.0.play.vchans=4
dev.pcm.0.rec.vchans=4


# Allow users to mount USB disks

vfs.usermount=1

dev.acpi_ibm.0.events=1
dev.acpi_ibm.0.handlerevents=0x17

# Enable shared memory support for Chromium
kern.ipc.shm_allow_removed=1




3. Start up services.


/etc/rc.conf
# Set up hosntame
hostname="your_hostname.domain"

# Keymap and fonts
keymap="us.pc-ctrl"

# Network setup with wireless fallback
ifconfig_em0="up"
wlans_ath0="wlan0"
ifconfig_wlan0="WPA"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport wlan0 laggport em0 DHCP"

# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="AUTO"

# Enable high resolution (with sc only)
allscreens_flags="MODE_357"

# Enable SSH
sshd_enable="YES"

# Enable moused

moused_enable="YES"
moused_flags="-a 1.3 -A 1.6 -VH -z 4 5 6 7"
moused_type="auto"
moused_port="/dev/psm0"

# Device permissions for normal users
devd_enable="YES"
devfs_system_ruleset="system"

# Enable ntpd
ntpd_enable="YES"
ntpd_sync_on_start="YES"

# Enable powerd
powerd_enable="YES"
performance_cx_lowest="Cmax"
economy_cx_lowest="Cmax"


# Enable this for ZFS

zfs_enable="YES"

# Webcam daemon
dbus_enable="YES"
webcamd_enable="YES"

# Enable SMART
smartd_enable="YES"

# Clear temporary files
clear_tmp_enable="YES"
clear_tmp_X="YES"

# Add bridged networking support for VBox
vboxnet_enable="YES"





4. Now the exciting part. The pointing devices with scrolling.


/usr/local/etc/X11/xorg.conf.d/10-sysmouse.conf
Section "InputClass"
        Identifier "sysmouse0"
        MatchDevicePath "/dev/sysmouse"
        Option "Buttons" "15"
        Option "EmulateWheel" "true"
        Option "EmulateWheelButton" "2"
        #Option "YAxisMapping" "4 5"
        #Option "XAxisMapping" "6 7"
        Option "ZAxisMapping" "4 5 6 7"
EndSection

If you start your X session with startx, add the following line to your ~/.xinitrc. If you use KDE or GNOME, add it to your Autostart script.

xinput set-button-map sysmouse 1 2 3 5 4 7 6 5 4 7 6

This part deserves a bit of explanation. There are lots of discussions on the Internet about setting up scrolling for both the UltraNav device (TrackPoint and Touchpad). They usually suggest turning off moused. Bad move!

In order for them to work properly (I mean with scrolling), we need moused (on /dev/psm0) with proper parameters. Moused will then pass the mouse input information through to /dev/sysmouse. Then we tell X to use /dev/sysmouse.

The result: scrolling up, down, left, right on TrackPoint are translated into buttons 4 5 6 7, whereas Touchpad 8 9 10 11. Finally, we map buttons 8 9 10 11 (of Touchpad) to 4 5 6 7 with xinput.

Note that for the touchpad, it's two finger scroll. Personally, I prefer the edge (and circular) scroll which I couldn't get it to work unfortunately.


5. The hotkeys

This file tells devd to call /usr/local/sbin/acpi_oem_exec.sh for all IBM ACPI events.
/etc/devd/tp.conf
notify 10 {
        match "system"      "ACPI";
        match "subsystem"   "IBM";
        action              "/usr/local/sbin/acpi_oem_exec.sh $notify ibm";
};




You need to run acpi_osd when launching X. Adding the following lines to .xinitrc if you use startx, or your Autostart script:
if [ -x /usr/local/bin/acpi_osd ]; then
        /usr/local/bin/acpi_osd &
fi

All mouse events come from moused and since it is run as root, the suspend mouse event hotkey (Fn + F8 ) needs the help of sudo.
/usr/local/etc/sudoers.d/moused
 ALL ALL = NOPASSWD: /usr/bin/killall -USR1 moused


This file handles the hotkey events and setup OSD messages. You might want to tweak/extend it to suit your need, e.g. customize what the ThinkVantage button does, the video switching hotkey (Fn + F7), the zoom hotkey (Fn + spacebar). Right now they do nothing (and honestly I don't need them at all).
/usr/local/sbin/acpi_oem_exec.sh
#!/bin/sh

if [ "$1" = "" -o "$2" = "" ]
then
        echo "usage: $0 notify oem_name"
        exit 1
fi
NOTIFY=`echo $1`
LOGGER="logger"
CALC="bc"
BC_PRECOMMANDS="scale=2"
ECHO="echo"
CUT="cut"
MAX_LCD_BRIGHTNESS=7
MAX_VOLUME=14
OEM=$2
DISPLAY_PIPE=/tmp/acpi_${OEM}_display
ACPICMD="acpiconf"

case ${NOTIFY} in
        0x05)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.bluetooth`
                if [ "$LEVEL" = "1" ]
                then
                        sysctl dev.acpi_${OEM}.0.bluetooth=0
                        MESSAGE="bluetooth disabled"
                else
                        sysctl dev.acpi_${OEM}.0.bluetooth=1
                        MESSAGE="bluetooth enabled"
                fi
                ;;
        0x10|0x11)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.lcd_brightness`
                PERCENT=`${ECHO} "${BC_PRECOMMANDS} ; \
                        ${LEVEL} / ${MAX_LCD_BRIGHTNESS} * 100" |\
                        ${CALC} | ${CUT} -d . -f 1`
                PERCENT=`sysctl -n hw.acpi.video.lcd0.brightness`
                MESSAGE="brightness level ${PERCENT}%"
                ;;
        0x12)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.thinklight`
                if [ "$LEVEL" = "1" ]
                then
                        MESSAGE="thinklight enabled"
                else
                        MESSAGE="thinklight disabled"
                fi
                ;;
        0x15|0x16)
                case ${NOTIFY} in
                        0x15)
                                (( LEVEL-- ))
                                mixer vol -7
                                ;;
                        0x16)
                                (( LEVEL++ ))
                                mixer vol +7
                                ;;
                        *)
                                ;;
                esac
                MESSAGE="`mixer -s vol`%"
                ;;
        0x17)
                LEVEL=`sysctl -n dev.acpi_${OEM}.0.mute`
                if [ "$LEVEL" = "1" ]
                then
                        MESSAGE="volume muted"
                else
                        MESSAGE="volume unmuted"
                fi
                ;;
        0x02)
                MESSAGE="screen lock on"
                # FIXME
                DISPLAY=localhost:0 xscreensaver-command -lock
                ;;
        0x03)
                LEVEL=`${ACPICMD} -i0 | awk '/Remaining capacity/ {print $NF}'`
                MESSAGE=`${ACPICMD} -i0 | awk '/Remaining capacity/'`
                ${ACPICMD} -i0 | $OSD_CAT
                ;;
        0x08)
                killall -USR1 moused
                MESSAGE="TrackPoint/Trackpad toggle"
                ;;
        0x14)
                MESSAGE="Zoom"
                ;;
        0x18)
                MESSAGE="ThinkVantage Button"
                ;;
        0x04)
                MESSAGE="suspend to RAM"
                ${ACPICMD} -s 3
                ;;
        0x0c)
                MESSAGE="suspend to disk"
                ${ACPICMD} -s 4
                ;;
        *)
                ;;
esac
${LOGGER} "${MESSAGE}"
if [ -p ${DISPLAY_PIPE} ]
then
        ${ECHO} "${MESSAGE}" >> ${DISPLAY_PIPE} &
fi
exit 0





6. Volume keys and multimedia keys (Fn + arrow keys)

These keys generate standard XF86Audio keycodes. It may work for your DE (GNOME or KDE) out of the box. Otherwise you'll need to add them manually to your WM as keyboard shortcuts.

Here's the relevant section of my .bbkeysrc config:
  [Execute]  (XF86AudioLowerVolume) {/usr/local/sbin/acpi_oem_exec.sh 0x15 ibm}
  [Execute]  (XF86AudioRaiseVolume) {/usr/local/sbin/acpi_oem_exec.sh 0x16 ibm}
  [Execute]  (XF86AudioPrev) {xmms --rew}
  [Execute]  (XF86AudioPlay) {xmms --play-pause}
  [Execute]  (XF86AudioNext) {xmms --fwd}
  [Execute]  (XF86AudioStop) {xmms --stop}



7. Display OSD

This file sets up a fifo that waits for messages to be displayed onscreen.
/usr/local/bin/acpi_osd
#!/bin/sh

DISPLAY_PIPE=/tmp/acpi_ibm_display
OSD="osd_cat"
FONT="-*-lucidatypewriter-*-*-*-*-*-240-*-*-*-*-*-*"
COLOR=Green
TIME=1
OPTS="--font=$FONT -c $COLOR -p bottom -o -10 -i 50 -d $TIME"

trap "rm -f $DISPLAY_PIPE" EXIT

[ -p $DISPLAY_PIPE ] || mkfifo $DISPLAY_PIPE

while true
do
        if read line <$DISPLAY_PIPE; then
                echo $line | $OSD $OPTS
        fi
done

exit 0 


8. Now restart the computer. Voila.