WindowMaker as the X11 window manager

My light-weight window manager of choice is WindowMaker.  It is simple, easy to modify, and stays out of the way.  The default window manager installed with X11 on FreeBSD, however, is twm.  I first experienced twm in the Virginia Tech Computer Science Dept. UNIX lab (all FreeBSD boxes), and tvm looks exactly the same today.  I cannot pick on it too much, however.  The guy in the office next door to me at work uses tvm on his Linux box.  I suppose I ought to call it an Emacs box, since he does everything out of emacs.  I digress…

Please read this excellent tutorial on xinit and .xinitrc files from the Fluxbox project first.  The tutorial explains very clearly how the xinit program works and how .xinitrc files are processed.  In short, however, once the end of .xinitrc is reached, X11 is shutdown.  Thus you need a blocking command in xinitrc scripts that prevents the script from exiting.  In the default xinitrc script,  /usr/X11R6/lib/X11/xinit/xinitrc, I noticed towards the bottom of the script:

twm &

It was followed by three xterm commands. The first two were also run in the background, but the final xterm was not run in the background, thus preventing X11 from terminating until that terminal is closed by the user.  No more twm on this box though!  I removed the xterm commands, and changed the twm line to the following:


Now, WindowMaker is launched and until the user exits the WindowMaker session X11 will continue to run. All users on my FreeBSD will have WindowMaker when the execute startx.  I also created a .xinitrc in my user account home directory as follows:

exec wmaker

In reality, however, I have XDM to run as my “magic client” (see article linked above). Instead of managing a separate .xinitrc and .xsession file, I just symlinked the files together so that any changes are available in both files, in the cast that I ever disable XDM.

ln -s .xinitrc .xsession

After I log into the system via XDM, my .xsession file is executed and WindowMaker is launched.

Setting up XDM

The X Display Manager, or XDM, is a program that allows one to log into a system using a GUI program.  Rather than logging into a system and then manually starting X, X comes up after boot and is ready to go.  While XDM (or GDM for GNOME or KDM for KDE) is not necessary on server systems, any system where X Windows is used on a regular basis benefits from XDM.  And XDM is easy to set up too.  With FreeBSD, one can simply build and install from the ports collections:

cd /usr/ports/x11/xdm
make install clean

Now one just needs to modify /etc/ttys to enable XDM. The XDM entry is already in this file, it is just disabled on the default install. To enable XDM after installing it, change “off” to “on” between the xterm and secure parameters.

ttyv8 "/usr/local/bin/xdm -nodaemon" xterm on secure"

Unlike GDM or KDM, XDM does not allow one to select a window manager. The window manager should be executed from a .xsession script in your home directory. I setup my system so that .xsession is a symlink to a .xinitrc file (read by startx when manually starting X11) in my home directory. If you need XDM and startx to have different startup methods, then you must provide separate files with customization for each program.

Without a .xsession file, XDM and startx default to /usr/X11R6/lib/X11/xinit/xinitrc. With my default install of FreeBSD, at the bottom of the script, the window manager twm is started, along with three xterms which are opened by default.

I cannot stand twm, so next I will look at setting up a different light-weight window manager. As my experience with Ubuntu and GNOME on this machine proved, I don’t have the memory on this machine for desktop environments like GNOME or KDE.

nVidia graphics driver on FreeBSD 8.2

Update January 2016: Driver version is now 96.43.23…doesn’t build in FreeBSD 10.2. My initial guess is the clang system is catching stuff that gcc did not in the driver…

First of all, find the proper driver for your device.  I used nVidia’s driver download page to get the right version: 96.43.20.  My card is an nVidia GeForce4 MX 420, and it is not supported on higher version number drivers that support more modern video cards.

Download the driver tarball with your web brower or wget and unarchive it.

cd /root
tar -xzf NVIDIA-FreeBSD-x86-96.43.20
cd  /root/NVIDIA-FreeBSD-x86-96.43.20
vi doc/README

As you can see in the documentation, you just need to do a ‘make install’.  Before doing so, however, comment out lines 25 through 36 of src/nv-freebsd.h as this check will prevent you from being able to build the driver.  (I don’t know why this check was in here…perhaps on more modern drivers this is not necessary)

#if __FreeBSD_version >= 800000
#error This driver does not support FreeBSD 8.x/-CURRENT!
#if __FreeBSD_version >= 700000 && __FreeBSD_version < 700055 #error This driver does not support FreeBSD 7.x/-CURRENT! #endif #if __FreeBSD_version >= 600000 && __FreeBSD_version < 600034
#error This driver does not support FreeBSD 6.x/-CURRENT!
#if __FreeBSD_version < 503000
#error This driver requires FreeBSD 5.3 or later!

Build and install the driver:

make install

If the driver builds with no errors, the driver kernel module should be installed in /boot/modules.  To test the driver and make sure that everything works,

I used the nvidia-xconfig tool to create a basic xorg.conf file. The tool automatically detected my video card and setup the correct information in the Device section.

Section "Device"
    Identifier     "Device0"
    Driver         "nvidia"
    VendorName     "NVIDIA Corporation"
    BoardName      "NV17 [GeForce4 MX 420]"
    BusID          "PCI:1:0:0"

The tool also added additional required modules by the driver.

Section "Module"
	Load  "dbe"
	Load  "dri"
	Load  "dri2"
	Load  "extmod"
	Load  "glx"
	Load  "record"

I then had to customize the monitor settings. I have a wide-screen monitor that I like to run at 1920×1200. I tried explicitly setting this in the Modes subsection of the Screen section, but was unable to get the setting to work (though 1024×768 worked with no problems). Apparently, X is smart enough these days to figure out the max resolution on its own, so I simply commented out the Modes subsection.

Section "Screen"
    Identifier     "Screen0"
    Device         "Device0"
    Monitor        "Monitor0"
    DefaultDepth    24
    SubSection     "Display"
        Depth       24
#        Modes      "1920x1200" "1024x768" "800x600" "640x480"

I setup the Monitor section with more descriptive names as well as putting in the exact horizontal sync rate and vertical refresh rate from the instruction manual for my Samsung display.

Section "Monitor"
    Identifier     "Monitor0"
    VendorName     "Samsung"
    ModelName      "Syncmaster P2250"
    HorizSync       30.0 - 81.0
    VertRefresh     56.0 - 60.0
    Option         "DPMS"

To test the configuration, use the -config option on the X program, passing it the customized X configuration.

X -config /root/xorg.nvidia.conf

Once satisfied with the settings, I copied the config file to /etc/X11/xorg.conf and tried to start X Windows.

cp /root/xorg.nvidia.conf /etc/X11/xorg.conf
startx   # ugly tvm should start

Finally, with the driver working, it can be added to load automatically during boot, allowing the use of graphical log-in programs such as XDM.  To load the driver during the boot stage, add the following to /boot/loader.conf:


Next I shall look at configuring XDM so that I don’t have to always manually start X.

Routes to hosts on the local network

On my private LAN, I have a number of hosts, but the two most important are my FreeBSD box–named so creatively as “bsd”–and “trantor“, my MacBook.  Typing the IP address of “bsd” when I want to access it gets old fast, and there is an easy way to be able to access it by name.  On my MacBook, I just have to add the following to /private/etc/hosts:      bsd

On my FreeBSD box, edit /etc/hosts and add:      trantor

Before hitting my ISP’s DNS server, the hosts file is consulted and used to obtain the IP address of the host on my private LAN.

FreeBSD wireless config for Ralink NICs

Update January 2016: I installed FreeBSD 10.2 on this old box and tried to revisit the configuration. I had to fix some mistakes in this post with respect to spelling, but otherwise, nothing has changed with this process nearly 5 years later. Gotta love FreeBSD!

The adapter can be identified by looking in the messages during the boot process, which are logged to /var/run/dmesg.boot.  I have a D-Link PCI wireless NIC, and the chipset is by Ralink and thus uses the ral0 driver.  I also found my wired Ethernet NIC card too, represented by vr0, which I have hooked up on a private network with no access to the Internet.

ral0: <Ralink Technology RT2561S> mem 0xf0000000-0xf0007fff irq 5 at device 15.0 on pci0
ral0: MAC/BBP RT2561C, RF RT2527
vr0: <VIA VT3043 Rhine I 10/100BaseTX> port 0x1080-0x10ff mem 0xf0008000-0xf000807f irq 9 at device 16.0 on pci0
vr0: Quirks: 0x1
vr0: Revision: 0x6

Seeing ral0 during the boot process means that the kernel has recognized the hardware and loaded the proper driver module.  You can verify this with ifconfig:

root@bsdbox# ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
ether 00:25:9c:a8:4f:16
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
status: no carrier

I did not perform the wireless configuration during installation of FreeBSD. I tried, but it failed for some reason, so I gave up and decided I would debug later. As such, this machine is not configured for wireless access, and thought there is an entry for ral0 in the ifconfig output, the  status is ‘no carrier’ indicating that I am not connected to the wireless access point.

For WPA, wpa_supplicant handles the encryption, where we must provide the SSID of the access point as well as the access point passphrase, which gets encrypted as a PSK.  Since I am using WPA Personal, I need to use wpa_passphrase to generate a config file that I can provide to the wpa_supplicant module with the proper SSID and PSK.  The file should be stored as /etc/wpa_supplicant.conf.

wpa_passphrase [ssid] [passphrase] > /root/wpa.conf      # keep a backup
cp  /root/wpa.conf /etc/wap_supplicant.conf

One can also directly edit /etc/wpa_supplicant.conf file and modify the SSID and PSK.

root@bsdbox# less /etc/wpa_supplicant.conf


With the security out of the way, we only have to configure the wlan module.  It would appear that in the past you could try to bring up the interface via the driver name, but the 802.11 system has changed and you now must create a wlanX device for use with ifconfig rather than the actual device itself.  This is not as hard as it sounds.  Add the following to your /etc/rc.conf file.

root@bodbox# /etc/rc.conf
ifconfig_wlan0=”WPA SYNCDHCP”

The device ral0 is now mapped to wlan0 through the wlan module, and ifconfig is told that wlan0 expects WPA authentication and should use SYNCDHCP to obtain an IP address for the interface wlan0.  After restarting the networking services I checked on the wlan0 interface:

root@bsdbox# ifconfig wlan0
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
ether 00:25:9c:a8:4f:16
inet netmask 0xffffff00 broadcast
media: IEEE 802.11 Wireless Ethernet OFDM/48Mbps mode 11g
status: associated
ssid ….. channel 1 (2412 MHz 11g) bssid 00:7f:28:11:a3:34
country US authmode WPA2/802.11i privacy ON deftxkey UNDEF
AES-CCM 2:128-bit AES-CCM 3:128-bit txpower 0 bmiss 7 scanvalid 60
bgscan bgscanintvl 300 bgscanidle 250 roam:rssi 7 roam:rate 5
protmode CTS roaming MANUAL

root@bsdbox# ifconfig ral0
ral0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 2290
ether 00:25:9c:a8:4f:16
media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
status: associated

Now the status for the interface card ral0 should say ‘associated’ rather than ‘no carrier’, and you should have an IP address for wlan0 as well.  Try to connect to an outside source to verify the wireless link is working, such as pinging

And that is all there is to it, much easier than I thought!

Returning to FreeBSD

I have an old PC that I bought in 1999 just before entering college.  It came with Windows NT 4.0 and after my first semester I ended up installing FreeBSD in a separate disk partition and dual-booting (of course these days one would just use a VM).  My university taught FreeBSD rather than Linux in the computer science courses, and we were running FreeBSD 3.x.  At the time there was little support for my nVidia Riva TNT graphics card, so I mostly used FreeBSD for school work and learning UNIX.

After finishing school I did not take the machine with me overseas, so it mostly sat in storage.  I’ve been using laptops at home since then, and I hadn’t really given the machine much though.  However, thirteen years later, this machine is still solid.  All of the original parts work, minus the CD-RW drive.  I had to replace one in 2002, and the replacement drive is no longer working well.  The Iomega Zip drive still works perfectly (no click of death yet!), and with 256 MB of RAM and a that old graphics card it runs Windows 2000 like a champ.  I can even get 1900×1200 on my LCD monitor.

The problem is I don’t have much of use for Windows.  I only use ModelSim, which is overkill on this old machine, so I usually run Windows in VirtualBox on my MacBook.  So what to do with this old PC then?  I have wanted to get into Linux kernel mode programming, so I thought I would install Linux on the machine.  My workstation at my job runs Ubuntu 11 which I quite enjoy.  So what not start there?

Ubuntu 11.04 – easy config and setup, but you need memory

I downloaded the Ubuntu CD ISO and tried to install it on the old PC.  The installer would fail after booting the live CD, and after searching on the Internet, I found that 256 MB of RAM was not enough to run the graphical installer.  I downloaded the text-code Ubuntu CD and then proceeded to install it.  The install went smoothly and everything seemed well.  Everything was installed and I was able to connect to my wireless network with ease.  However, when I tried to launch the terminal, it took nearly 20 seconds for the terminal to appear.  I tried opening Firefox, and it took nearly a minute to load.  Clearly I still did not have enough memory to run Ubuntu.  I really like the debian package management system though, I hate battling ‘yum’, ‘zypper’, and the rpm management tools on the servers at work.  So perhaps I’ll just try Debian?

Debian 6 – Lightweight, but be prepared to spend days getting it to work

I have never tried Debian before.  In the past at least, it had a reputation for being difficult to configure and use.  To my surprise though, the install process was quite smooth.  Perhaps I just know what is going on now that I’ve been working with UNIX for a few years at work?  I logged into the gnome on my newly installed Debian box only to find that there was no way to setup wireless networking.  I only had disk 1, and the geniuses at Debian decided that disk 4 would have network-manager, disk 5 would have gnome-network-manager, and disk 2 would have many of the dependencies for both of those packages.  I eventually installed all of the packages manually with dpkg, and even when I had the gnome-network-manager installed and usable, I still could not connect to my wireless network.  I put that aside and tried to install nVidia’s legacy driver for my graphics card.

No go.  On this minimalist Debian system, even binutils were not installed by the Debian installer!  Luckily binutils were on disk 1, but even after installing them, the nVidia installer would not run.  I became fed up and gave up on Debian.  Debian was light-weight enough to run on this machine, but with packages spread over 30+ CDs and no connection to my wireless network, I decided to try to move on.  Well, there’s always Fedora Core, right?

Fedora Core – memory, memory, memory

I considered Fedora Core as it was the distro that I had used in the past quite a bit.  A quick look at the Fedora webpage and I had already given up–I needed at least 768 MB of RAM, three times what i had in this machine.

Longing for Solaris and SPARC

At this point I was longing for my Sun Blade 150 that I owned while living in Tokyo.  It was an old machine too, and Ultrasparc III with just 512 MB of RAM and a DVD-ROM drive.  However, that machine was slick.  Installing Solaris 10 was a breeze, and everything just worked out of the box.  As with Apple products, when the hardware and software are controlled by one company, things just work…at a price though!  I thought briefly about the idea of Solaris x86, but quickly decided that was not a good idea.

Back to FreeBSD

So it was back to FreeBSD after  many years away from it.  I downloaded the single CD for the install, and though slightly simplified, the install screen looks just as it did back in the year 2000 when I first installed FreeBSD on this same machine.  Back in 2000, the machine had a powered by Windows NT sticker which I covered up with a FreeBSD sticker.  How ironic that this same machine was running FreeBSD again.  I installed the kernel developer base, and running have a very learn machine with no GUI yet, but wireless networking, vim 7, and gcc 4.6, all installed over the wire.  FreeBSD just works.


I really just need to buy a modern PC.  I still want to muck around with the Linux kernel, but I don’t want to spend days configuring the machine with no network connection.  I have built embedded computer systems, bringing up these systems from nothing, writing the firmware for the processors and FPGAs, and making them fully functional products.  Yet I have never built my own PC from parts…perhaps it is time for me to give that a try?  Somehow that seems more daunting to me than building systems with microcontrollers and FPGAs.  It shouldn’t be though, I just have to carefully select the parts.  So the Linux kernel stuff can wait until I have figured my PC build.

With this old PC, I will let it run FreeBSD happily.  I’ve never custom complied my own FreeBSD kernel, and that is one of the projects I have planned.  Perhaps I can try to run my own DNS server so that I can connect to my MacBook by CNAME rather than IP address?  I’m sure more ideas will come out over the coming days.

Fixing a botched /etc/rc.conf file

In an effort to get my wireless NIC working, I added a line to /etc/rc.conf and decided to reboot the system. On start-up, however, the system reported a syntax error and presented me with the option to fix it.

/usr was not mounted, so I was unable to edit the file with vi. I tried using /bin/ed to edit the file, but the system reported that the system was read-only. I was not sure what to do, but luckily the FreeBSD team has splendid documentation and FAQs.

As the FAQ states, one has to mount the root file system as read/write in order to modify any of the files. I rebooted and when presented with the syntax error, escaped to the shell. I then proceeded to mount the root file system with write access:

mount -urw /
mount -a -t ufs    # for vi

After making the changes, I did a quick reboot and sure enough the problem was fixed.