FreeBSD 13 on Thinkpad T460s


For some reasons, I decided to use FreeBSD on my laptop. Several times have I tried it in the last few years. Several times have I stopped after the first issue that I felt was sign of it not being built for me.

This time, I’ll go for at least a whole month of using it. So I can really decide if I keep using it ; or switch back to OpenBSD.

Prepare the installation media

Read the manual . It is available online and shall be time saving. And it helps getting rid of old habbits and bad assumptions.

Download the FreeBSD-13.0-RELEASE-amd64-mini-memstick.img file and transfer it on an USB stick.

# doas dd if=FreeBSD-13.0-RELEASE-amd64-mini-memstick.img \
  of=/dev/rsd2c bs=1m

This was done running OpenBSD. Replace the of device reference with the proper one.

Restart the laptop and boot on the USB stick ; using F12 on the T460s.

Install FreeBSD

Run the installer as described in the handbook. The options I went for were:

When all done, exit the installer and reboot.

The first boot

Before being able to boot the system, the ZFS encryption passphrase is required. Note that the keyboard uses a US layout at this point. One needs to learn how to type the passphrase using it.

At the prompt, log in as root and continue further configuration.

Install a few console tools to be more comfy while continuing the configuration.

# pkg install doas tmux vim w3m

I choose to start tmux and configure a dual pane. One with the Handbook and one with a shell. I also split the shell pane in two to also have a look at the manual ; in the case I need to do more than what’s written in the Handbook.

# w3m /usr/local/share/doc/freebsd/en/books/handbook/en/book.html

Security patches

Check for security patches and apply them:

# freebsd-update fetch
# freebsd-update install

Add an automatic check in the crontab:

# crontab -e 20 20 * * * freebsd-update cron

Tell FreeBSD where to send all emails and configure an MTA:

# echo "jca" > /root/.forward
$ echo "" > /home/jca/.forward

# pkg install ssmtp
# vi /etc/mail/mailer.conf
# vi /usr/local/etc/ssmtp/revaliases
# vi /usr/local/etc/ssmtp/ssmtp.conf

Modify the packages repository to get more recent updates:

# mkdir /usr/local/etc/pkg/repos
# cat /usr/local/etc/pkg/repos/FreeBSD.conf
FreeBSD: {
  url: "pkg+${ABI}/latest",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
# pkg update

ThinkPad ACPI extras

Get support for hotkeys and specific ThinkPad components:

# echo 'acpi_ibm_load="YES"' >> /boot/loader.conf
# kldload acpi_ibm

Suspend and Resume

Check if laptop can go to sleep and wake up properly.

# zzz

The laptop turns off. The power LED is blinking. That’s good.

Power the laptop on… the screen remains black… blindly issue reboot. The laptop reboots properly. The issue is probably the graphic card. Let’s configure X Window System. That may explain why it comes first in handbook…

Configure X Window System

Install Xorg:

# pkg install xorg
# pw groupmod video -m jca

Install the DRM drivers:

# pkg install drm-kmod libva-intel-driver xf86-video-intel
# sysrc kld_list="i915kms acpi_video"

Drivers can be loaded manually but lets reboot to check everything applies properly. On reboot, kldstat shows that everythong is loaded.

Let’s try to set the laptop to sleep and wake up again… This time, the shell is properly back.

Using startx as root switches to Xorg ; with a US keyboard layout… So let’s configure a french keyboard layout.

# cat /usr/local/etc/X11/xorg.conf.d/keyboard-fr.conf
Section "InputClass"
  Identifier      "KeyboardDefaults"
  MatchIsKeyboard "on"
  Option          "XkbLayout" "fr"

I noticed that if I let FreeBSD use the modesetting driver, Xorg would die on resume. So I configured the Intel driver. And the laptop would resume properly in X.

# cat /usr/local/etc/X11/xorg.conf.d/video-intel.conf
Section "Device"
  Identifier      "Intel Graphics"
  Driver          "intel"
  Option          "AccelMethod" "sna"

Configure XDM

I don’t like to run X using startx. I’d rather use some display manager:

# pkg install xdm
#̶ ̶s̶y̶s̶r̶c̶ ̶x̶d̶m̶_̶e̶n̶a̶b̶l̶e̶=̶"̶Y̶E̶S̶"̶
# service xdm enable
# service xdm start

ctrl-alt-f1 can be used to switch to the console. There are still stuff to configure on the system.

Wireless configuration

By default, nothing is configured ; nor appears in ifconfig output… My Broadcom BCM4356 is not recognised by FreeBSD. So I plugged-in an USB dongle ; and configured it.

# sysctl net.wlan.devices net.wlan.devices: rtwn0

# cat /etc/wpa_supplicant.conf
  ssid="<my ssid>"
  psk="<my wpa key>"

# sysrc wlans_rtwn0="wlan0"
# sysrc ifconfig_wlan0="WPA SYNCDHCP"
# service netif restart

I would normally configure a link aggregation between wired and wireless interfaces. But it doesn’t seem to work with that particular wireless device. I tried another one that did ; but it was a bit slower.


Everything is configured and works out of the box.


The internal device is recognised:

# dmesg | grep ubt
ubt0 on uhub0 ubt0: <Broadcom Corp BCM2045A0, rev 2.00/1.12, addr 2> on usbus0

I don’t use it so I can’t say if it works or not and how.

User environment

I want a french localized workstation ; as much as possible:

$ vim ~/.login_conf

Finish the global configuration by setting up a desktop environment:

# pkg install xfce xfce4-goodies xfce4-pulseaudio-plugin
# sysrc dbus_enable="YES"
# service dbus start

$ echo ". /usr/local/etc/xdg/xfce4/xinitrc" > ~/.xsession

Log in via XDM and customize your XFCE session at will.

[ 2022-02-02 Request to detail ‘global menu’ by @vermaden] If you like the Global Menu display mode, ala Mac OS, there’re a few extras steps to go.

# pkg install xfce4-appmenu-plugin

$ xfconf-query -c xsettings -p /Gtk/ShellShowsMenubar -n \
  -t bool -s true
$ xfconf-query -c xsettings -p /Gtk/ShellShowsAppmenu -n \
  -t bool -s true
$ xfconf-query -c xsettings -p /Gtk/Modules -n -t string \
  -s "appmenu-gtk-module"

Then add the AppMenu plugin to an XFCE panel. And you’re done.

Install a bunch of additionnal usual apps:

# pkg install keepassxc
# pkg install firefox
# pkg install thunderbird
# pkg install nextcloudclient
# pkg install mpv libvdpau-va-gl

$ mkdir $HOME/.config/mpv
$ cat > $HOME/.config/mpv/mpv.conf

$ mpv ...
 (+) Video --vid=1 (*) (h264 1920x1080 29.970fps)
 (+) Audio --aid=1 --alang=eng (*) (aac 2ch 48000Hz)
Using hardware decoding (vaapi).
AO: [oss] 48000Hz stereo 2ch s32
VO: [gpu] 1920x1080 vaapi[nv12]
AV: 00:00:02 / 00:00:58 (4%) A-V: -0.000

Suspend the laptop from XFCE

Looks like only root can tell the laptop to zzz. Being part of the proper group allows we, the users, to do it too.

# pw groupmod operator -m jca

A log out / log in is required for the changes to be applied.

Dealing with HiDPI

I have replaced my T460s original LCD with some 2K WQHD one. The resolution is 2560x1440 and on the 14" screen, the default 96 DPI renders fonts to small (for my old eyes).

The solution I use is to set a custom DPI. I went for 144. Because it renders 10px font with the same “real” size as my other laptops. In XFCE, this can be done from the graphical configuration tool. But this can also be done by setting up a proper .Xdefaults / .Xresources files.

If I stop using XFCE, I’d set:

$ xrdb -query
Xft.antialias: 1
Xft.hinting: 1
Xft.hintstyle: hintmedium
Xft.rgba: rgb
Xft.dpi: 144

KeePassXC and Nextcloud Client are QT applications that needs extra care regarding HiDPI. In ~/.xsession, I added:


A 144 DPI value matches the 1.5 factor. This is why I choose that particular value.

Personnal thoughts on running FreeBSD

I wanted to go out of my confort zone, using an OS I haven’t used since the early 2000. The last FreeBSD I used was probably one from 4.x. Since then, I got used to OpenBSD way of doing things ; so I’m obviously biaised. But I also was ready to be impressed.

What I liked

Using FreeBSD as a workstation with Xorg feels smooth. Just like Windows, Linux or Mac OS, the windows pops up really quickly, the mouse feels super responsive and there’s no lag in hogware like Firefox when switching tabs. Things like Gimp or Libreoffice take a few seconds to launch. But as far as I can tell, those react the same way no matter the OS you use.

Most of the time, you can’t hear the laptop fan. Compiling stuff or running a full indexation with Shotwell does turn it on. But regular email reading (with Thunderbird) or web surfing (with Firefox) does not turn it on ; or not that often.

French localization is available from the console. That still leads to Mutt having some French messages and English help pages but that’s not the point. The point is about date and strftime. This means that the date will be properly localized in XFCE and other software.

There are many virtualization options: Qemu, VirtualBox, bhyve. One can run other OSes in console and graphical mode.

What I disliked

There is no wireless driver for my Broadcom BCM4356. This means I’m stuck with 2.4GHz 802.11n when that particular Broadcom card can achieve 802.11ac connection straight from the hardware.

I missed a few console tools I expected to be “standard”. Like tmux, doas/sudo, dig. They can be installed using packages so that’s not big deal. I just felt those were natural tools for UNIX-like environments.

Although the console has been configured with French keyboard layout during installation, Xorg does not benefit from that layout without specific configuration. To my understanding, this is due to Xorg being treated as an external package and not part of the system. Once the Handbook example has been reproduce, the proper layout is useable in X.

Unless I missed something, hibernation is not available. I don’t use it that often. Most of the time, suspend is quite enough. But hibernate is neet when you have a long travel time and know you won’t use laptop soon ; and don’t want to close you tenth of applications for a proper shutdown.

Modules and Services management have confused me quite a lot. Some things go into /boot/loader.conf, some other in /etc/rc.conf. Using sysrc to enable services and service to start/stop services felt like “why not using a single command with a set of args rather than having various commands”.

[2022-02-02 Update from @FiLiS]: service foo enable can be used instead of sysrc. This adds more consistency.

Configuring the network interface is still something I don’t have fully understood. The wlan layer feels so complicated to me. The usage of cloned_interfaces seem like an inherited layer from nowhere since there also is ifconfig_ directives. Translating the bhyve ifconfig example commands into an rc.conf snippet still makes me sweat.

I was surprised that options were not shipped in (all) binary packages. For example, I had to recompile from source to be able to use redshift-gtk or have face recognition in Shotwell. I expected to be able to choose between “package with” and “package without” features.

Having a distinct localization for system and ports configuration files is disturbing. Whether it’s for Xorg or third-party binaries, it does not fit me well to have rc.d and etc stuff put under /usr/local. I understand why it is good to do it this way. But I prefer to have all stuff in one place, under /etc.

Ports sync & compilation is the second item that I still haven’t fully understood. Using /usr/ports from installer, or Portsnap, or Git is not a choice I would have liked to have. After a few trial & errors, it seems using Portsnap only is a sane option. Maybe I didn’t understood when I read the Handbook. I still not understand which of Portmaster, Portupgrade or Poudriere is the simplest tool to use when you only have a few packages to build because you want to enable a specific option. This is the most complicated thing to understand on that FreeBSD release. I must have missed something. But I ended up starting a FreeBSD instance in VirtualBox and compile the few stuff using make package.

There’s a recurrent issue between Let’s Encrypt certificates, Nextcloud client and FreeBSD updates. I thought I solved it using a Forum thread but it keeps coming back as FreeBSD updates keeps reinstalling wrong certificates.

What I learned

Using FreeBSD as a workstation helped me confirm my OpenBSD servers were not slow at all. I could transfer files from a Celeron J4125 at 700Mbps using HTTPS and NFS.

All my scripts are written to run using OpenBSD’s KSH. On the few Linux box I have, they are run using BASH. But I thought they were POSIX compliant. Using them with FreeBSD’s SH prooved me I was wrong. Some of them would not run because the syntax was not acceptable. I’ll have to review them to make them more POSIX compliant.

FreeBSD allowed me to solve some issues with my Nextcloud instance. There are still weird things happening but it seems to be due to the Nextcloud Client rather than the server configuration. I could also verify that the errors were not due to my httpd/relayd configuration.

[2022-02-02 Update] This overall configuration also works for ThinkPad X260. My screen is 1080p so I set the DPI to 105 and QT_SCALE_FACTORS to 1.1.

That was an interesting one-month long experiment. Some things were great, some less. But I’ve learned much. So thank you FreeBSD!