cwm freebsd tutorial


techno-mage has her old machine remade from scratch.

FreeBSD minimum desktop guide

Beastie was here

I'm not going to cover the installation process, but it's worth noting you might want to add your user to the groups: 'wheel operator video'.

The few services I use by default are local_unbound, powerd and ntpd. local_unbound caches dns requests and needs no configuration, powerd adjusts cpu frequency as is needed and enables hibernation and suspending, ntpd makes your clock synced.

Once it's installed, I get the handbook from the post-installation menu. One benefit is that this will also set up pkg and save you 10 seconds, when you install packages for the first time.

Most of these steps are optional, so read carefully and decide for yourself which are applicable to your usecase. This is simply what I do to get a bare minimum FreeBSD desktop.

Let's reboot.

> If you see a line beginning with ' # ', that's a command to be run as
> root.
> If the line starts with ' $ ', that's a command to be run as local 
> user.
> Blocks between '```' are contents of files.

first things tmux

The first thing I do is install tmux. Log in as root, or log in as user and run ' $ su -' (this is why you would want your user to be in the group wheel).

 # pkg install tmux

ksh is king

FreeBSD does not come with ksh and ksh is what I need. If you're like me, spoiled by the perfection that is OpenBSD's ksh, there is oksh in FreeBSD's ports, which is the portable version of the spiked fish's shell.

 # pkg install oksh
 # ln -s /usr/local/bin/oksh /bin/ksh

The second command makes a symbolic link to ksh in /bin/ksh. This is just my habit of having ksh in the same place on all my machines. Next up I change the default shell for both root and the user.

 # chsh
 # chsh user

In both cases I change the line:

Shell: /bin/shell
Shell: /bin/ksh

I add set -o vi to /root/.profile to get vi-like keybindings for the root user.

 # echo "set -o vi" >> /root/.profile

Similarly I setup .profile for the user.

 $ vi ~/.profile

This is what my .profile looks like, I only keep the original fortune line. I like to store away my scripts and programs in ~/.local/bin, so I change PATH accordingly and mkdir the path.

$ mkdir -p ~/.local/bin
export EDITOR=vi
export PAGER=less
export ENV=$HOME/.kshrc
export PS1="\$ "
if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune freebsd-tips ; fi

ENV is where you might want customize your ksh experience. For example:

 $ vi ~/.kshrc
set -o vi
alias l='ls -l'

pf firewall

pf in FreeBSD is a fork of OpenBSD's pf, but the general use of it for a desktop machine is virually the same.

Append rc.conf:


Customize your pf ruleset in /etc/pf.conf. The following is a bare minimum you can do. Blocks everything and only allows reaching ports 80, 443, 22, 70 and 1965, dns and ntp servers for ip4 and ip6.

You can reach the www, gopher and gemini like this, ping ips, but not much else.

tcp_serv="{http https ssh 70 1965}"
udp_serv="{domain ntp}"

set skip on lo0

block log all

pass out inet proto tcp to port $tcp_serv
pass out inet proto udp to port $udp_serv
pass out inet6 proto tcp to port $tcp_serv
pass out inet6 proto udp to port $udp_serv

pass out inet proto icmp
pass out inet6 proto icmp6
 # service pf start


Finally we install a graphical environment and drivers for our graphics card.

 # pkg install xorg gpu-firmware-intel-kmod-kabylake drm-510-kmod cwm xdm

Notice I'm not downloading the entire drm meta package. I only pick the one my machine will use. You can do the same by finding your graphics card/CPU here and selecting the proper driver:

Use kldload to load the drm driver and put it in rc.conf so that it is loaded on boot.

 # kldload i915kms

I use xdm as a display manager. I have yet to find something better.

Add to /etc/rc.conf:


I use cwm in this example. Before starting X or xdm, you must edit .xsession or .xinitrc in your HOME. (the former if you're using a display manager, the latter if you're starting x manually.)

 $ vi ~/.xsession
. ~/.profile
xset b off # disable bell
setxkbmap -layout us,cz -option grp:switch -option caps:escape
# us and czech layout, switch between by holding right alt, capslock is esc

exec cwm

If your user is not in the group video, add it now:

 # pw groupmod video -m user

Now you can start X or xdm and login.

 $ startx 


 # service xdm start

It is done?

At this point you should have a fully working FreeBSD desktop machine, with not much on it.

Here are a few tips that may or may not be relevant to you.


Xorg comes with xterm, which is the only terminal emulator I use. Some other tools I get at this point is the following:

 # pkg install links sacc amfora mpv neomutt msmtp feh xlockmore

Changing default audio output

In some cases, you might want to change the default audio output. For example the sound doesn't come out of the speakers but from somwhere within the box. If that's your issue, check the default sound device:

 $ sysctl hw.snd.default_unit

Change it to a higher/lower number.

 $ sysctl hw.snd.default_unit=2

To have it persist over reboots, append /etc/sysctl.conf:



I have a keyboard with a bunch of special keys for various tasks. Suspending, volume control, calculator.. etc. These wont work unless the following is done:

Append kld_list in /etc/rc.conf:

kld_list="i915kms usbhid"

And append /boot/loader.conf


You have to reboot. Then the keys can be bound to anything you want. You can use:

 $ xev

to check if the keys are being registred and see what they are called.

volume control

Volume control is done via mixer(8). By default, mixer does not remember last volume level when muted. To get the usual sound toggle functionality, I use the following script:

touch /tmp/mixervol
VOL=$(mixer | awk -F ':' '/vol/{print $2}')
if [ $VOL -gt 0 ]; then
echo "${VOL}" > /tmp/mixervol
mixer vol 0 
OVOL=$(cat /tmp/mixervol)
mixer vol ${OVOL} 

In my case it is placed in ~/.local/bin/vol-tog. Be sure to make it executable.

 $ chmod u+x ~/.local/bin/vol-tog

To bind volume keys in cwm, we'll edit ~/.cwmrc and append like so:

bind-key XF86AudioRaiseVolume "mixer vol +3"
bind-key XF86AudioLowerVolume "mixer vol -3"
bind-key XF86AudioMute "/home/user/.local/bin/vol-tog"

LControl-LAlt-LShift-r to reload cwm config.

powerd and apm

If you want to suspend your machine, run

 $ zzz

As stated at the top, you need the powerd service running. If it's not, append /etc/rc.conf

 # service powerd start

Your user must be in the operator group. Otherwise you will have to run zzz as root.

 # pw groupmod operator -m user

have fun and keep on computing