FreeBSD 13.1 install on a Lenovo IdeaPad 5
When I originally got this machine, I needed it for $WORK. That is no longer the case, so I wanted to install FreeBSD 13.1 in combination with ZFS to gain experience with the latter.
TL;DR Nice and quiet. Slightly faster than my i7-7700 workstation. Except for wifi, everything works.
In this article, commands that can be run as a normal user are predixed with “>
”.
All other commands should be run as root
.
Hardware
Lenovo IdeaPad 5 15ALC05 specs:
- CPU: AMD Ryzen 5 5500U
- GPU: AMD Radeon RX Vega 7 (built-in, codename “renoir”)
- RAM: 16 GiB (2 GiB in use by the GPU)
- SSD: 512 GiB
- display: 15.6” FHD IPS
- battery: L19M4PF1 15V/70Wh
- wifi: Qualcomm Atheros QCA6174
- bluetooth: Qualcomm Atheros QCA61x4 Bluetooth 4.0 (via usb)
Note
The wifi chip is not supported on FreeBSD 13.1. A driver is being worked on (at10k) but the wifi subsystem needs updating, so it’s a big job. Since tethering to a smartphone or ethernet adaptor works fine this is not a deal-braker for me. I’ve never used bluetooth on a PC, so I didn’t test that either.
This laptop doesn’t have a built-in ethernet port.
So I’m using a Sitecom USB-C to ethernet adapter.
This is recognized as a ue0
device.
Download and install the software distribution
Since I’m on the amd64 platform, I downloaded FreeBSD-13.1-RELEASE-amd64-dvd1.iso
.
Installing it on a new thumbdrive:
dd if=FreeBSD-13.1-RELEASE-amd64-dvd1.iso of=/dev/da1 bs=1m conv=sync 4408+0 records in 4408+0 records out 4622123008 bytes transferred in 172.740381 secs (26757629 bytes/sec)
Note that commands as shown above are to be run as root
, unless they are
preceded by >
which means they are to be run as a normal user.
Wherever you see the username rsmith
, you should replace that with the
username of the primary user.
Installation
It is a good idea to have Chapter 2 of the FreeBSD handbook handy during installation. Below are the settings that I used.
- Keymap: default
- Hostname:
styx.erewhon.home
(yours will be different, of course) - Optional components: deselect lib32, select ports and src.
- System partitioning: Auto (ZFS)
- ZFS configuration:
- Set encrypt to YES, then “Proceed with install”. This will encrypt basically all your data including system configuration and passwords.
- Virtual device type “stripe” (since there is only one built-in drive)
- Device “nvd0”.
- Choose a strong ZFS encryption passphrase. Note that without this password the disk is unreadable. So make sure not to lose it. :-)
- Fill in a root password.
- No IP4 of IP6 or configuration at this point.
- Timezone Europe/Netherlands → CEST
- Set time and date if needed.
- Services: disable sshd.
- System hardening: enable all except “read_msgbuf”.
- New user: “rsmith”, groups “video network”. Every user that wants to run X needs to be in the video group.
- Shell: tcsh
- Homedir: /home/rsmith
- Homedir permissions: 700
- Password auth: yes
- No empty password, no random password.
- Fill in a user password.
- Exit installer.
Go into shell to make changes:
pw groupadd usb pw usermod rsmith -G wheel,video,usb,network
The usb group is used to give users access to USB devices.
The network group is used to give normal users the rights to run e.g.
ifconfig
and dhclient
via doas
.
At this point we can reboot into the new system.
Packages
Since this laptop does not have built-in ethernet, I’ve downloaded all the
packages I wanted plus their dependencies from the latest quarterly
distribution (using two self-made scripts), and put them on a USB thumbdrive in
a directory packages
.
This is mounted on styx
, and the packages are installed.
Initially, only a couple of packages are installed:
mount_msdosfs -m 644 -M 755 /dev/da0s1 /media cd /media/packages setenv SIGNATURE_TYPE none pkg add pkg-1.18.4.pkg pkg add git-2.37.3.pkg rehash
Note
If you are using a later quarterly package set, the version numbers of packages can differ.
Now we place /etc
and /usr/local/etc
under git
control to track changes:
cd /etc echo '*.db' >>.gitignore echo 'zfs/zpool.cache' >>.gitignore git init -b main . git add . git commit -m "Initial commit after setup." cd /usr/local/etc git init -b main . git add . git commit -m "Initial commit after setup."
Now to install the rest of the packages:
cd /media/packages pkg add *.pkg
This will take a while. :-)
Among these packages the following are necessary to get X to work well on
this machine (next to xorg-7.7_3.pkg
, of course):
drm-kmod-20220907_1.pkg
(kernel modules and firmware for the GPU)xf86-input-synaptics-1.9.1_9.pkg
(touchpad driver)f86-video-amdgpu-22.0.0_1.pkg
(video driver)
Unmount and remove the USB stick containing the packages, then commit the changes in the configuration files:
umount /media cd /etc/ git add . git commit -m "After packages installation." cd /usr/locat/etc git add . git commit -m "After packages installation."
System configuration
After every change to a configuration file, this is added and then committed in the same way as shown above so it can be turned back if needed.
Graphics
After testing with kldload amdgpu
, it turns out that amdgpu
kernel
module works as expected.
So we add the following to /etc/rc.conf
:
kld_list="amdgpu.ko"
Sysctl
Added the following to /etc/sysctl.conf
:
vfs.usermount=1
This is needed so that non-root users can mount disks.
Loader
CPU’s from both Intel and AMD have security issues with symmetric
multithreading (“hyperthreading” according to Intel).
In my testing it slowed down a CPU intensive multithreaded programs.
So in it is better to switch it off.
Add to /boot/loader.conf
:
machdep.hyperthreading_allowed="0"
Umount and shutdown
Since I want to be able to perform these actions as a member of the wheel
group, some modes and permissions need changing.
chmod u+s /sbin/umount
chown root:wheel /sbin/shutdown
Devfs
Create /etc/devfs.rules
with the following contents:
[laptop_usb=10] add path 'da*' mode 0660 group usb add path 'msdosfs/*' mode 0660 group usb add path 'usb/*' mode 0660 group usb add path 'ugen*' mode 0660 group usb add path 'ttyU*' mode 0660 group usb add path 'cuaU*' mode 0660 group usb
Then add to /etc/rc.conf
:
devfs_system_ruleset="laptop_usb"
This gives the members of the usb
group access to USB devices.
Daemons
Added to /etc/rc.conf
:
sysvipc_enable="YES" local_unbound_enable="YES" dbus_enable="YES" obhttpd_enable="YES" openntpd_enable="YES"
So not forget to run the setup for local-unbound:
local-unbound-setup
Configuring network dongle
Network access is handy for transferring files and remote login.
I’ve got a Sitecom USB-C to gigabit LAN adapter.
When I plug it in, it is recognized as the ue0
device.
(When I plug in my smartphone with tethering enabled, it uses the same device.
Obviously, using gigabit ethernet is preferred.)
The network can be started with:
ifconfig ue0 up dhclient ue0
Remote access
It is very handy to be able to log in remotely, especially in the setting-up
phase.
To enable that we have to configure and start the secure shell daemon, sshd
.
Edit /etc/ssh/sshd_config
:
- Change
Port
to another value XXXX > 1000. - Change
AddressFamily
toinet
. - Add
AllowUsers rsmith
- Uncomment
HostKey
for rsa and ed25519. - Change
X11Forwarding
tono
. - Change
Compression
tono
.
This allows the user rsmith
to log in via the network.
To make this work I had to add my public ssh key (~/.ssh/id_rsa.pub
on the machine
I’m calling from) to ~/.ssh/authorized_keys
on styx.
The network was started with:
ifconfig ue0 up dhclient ue0 service sshd onestart
Then I could log in remotely with ssh -p XXXX styx.erewhon.home
.
Configuring X
When starting Xorg as rsmith
, the default twm
window manager comes up with
three xterm
windows.
The modesetting driver works when the amdgpu
module is loaded.
Based on the file from another laptop, I created the
/usr/local/etc/X11/xorg.conf.d/monitor.conf
file shown below, mainly because the screen size was not recognized correctly:
Section "Monitor" Identifier "Monitor0" VendorName "CMN 151e" ModelName "built-in" DisplaySize 344 193 endsection Section "Screen" Identifier "Screen0" Monitor "Monitor0" SubSection "Display" Viewport 0 0 Depth 24 EndSubSection EndSection
With this, the screen size is correct.
To get the touchpad to work, I needed the iichid
and ig4
modules.
To enable this:
kldload iichid kldload ig4
I also added those to kld_list
in /etc/rc.conf
:
kld_list="amdgpu.ko iichid.ko ig4.ko amdtemp.ko"
(The module amdtemp
is added to be able to see the the processor temperatures.)
Based on the information found in the Linux Arch wiki, I also created this
/usr/local/etc/X11/xorg.conf.d/touchpad.conf
file:
Section "InputClass" Identifier "MSFT0001:00 04F3:3140 TouchPad" Driver "synaptics" MatchIsTouchpad "on" Option "TapButton1" "1" Option "TapButton2" "3" Option "TapButton3" "2" Option "VertEdgeScroll" "on" Option "VertTwoFingerScroll" "on" Option "HorizEdgeScroll" "on" Option "HorizTwoFingerScroll" "on" Option "CircularScrolling" "on" Option "CircScrollTrigger" "2" Option "EmulateTwoFingerMinZ" "40" Option "EmulateTwoFingerMinW" "8" Option "CoastingSpeed" "0" Option "FingerLow" "30" Option "FingerHigh" "50" Option "MaxTapTime" "125" Option "PalmDetect" "on" EndSection
The touchpad works, but could probably use some tuning.
Not sure yet if the tapping is such a good idea.
Next to modifying touchpad.conf
and restarting X, one can also use the
synclient
program in the xf86-input-synaptics-1.9.1_9.pkg
package to
see and change the settings.
Since I don’t use a desktop environment but just a windowmanager (i3), some
settings were added to my ~/.xinitrc
:
# Display settings xrandr --output eDP-1 --gamma 1:1:1 --brightness 1 # Allow local access to x server (for notify-send) xhost +local:
Sound
Out of the box, there is no sound out of the speakers. :-(
The default sound device looks sensible:
> cat /dev/sndstat Installed devices: pcm0: <ATI R6xx (HDMI)> (play) pcm1: <ATI R6xx (HDMI)> (play) pcm2: <Realtek ALC257 (Analog)> (play/rec) default pcm3: <Realtek ALC257 (Right Analog Mic)> (rec) No devices installed from userspace.
The headphones work, though.
Looking at the relevant part of sysctl dev.hdaa.1
:
dev.hdaa.1.nid33_original: 0x04211010 as=1 seq=0 device=Headphones conn=Jack ctype=1/8 loc=Right color=Black misc=0 dev.hdaa.1.nid33_config: 0x04211010 as=1 seq=0 device=Headphones conn=Jack ctype=1/8 loc=Right color=Black misc=0 dev.hdaa.1.nid33: pin: Headphones (Black Jack) Widget cap: 0x0040058d PWR UNSOL STEREO Association: 0 (0x0001) Pin cap: 0x0001001c PDC HP OUT EAPD Pin config: 0x04211010 as=1 seq=0 device=Headphones conn=Jack ctype=1/8 loc=Right color=Black misc=0 Pin control: 0x000000c0 HP OUT EAPD: 0x00000002 EAPD Output amp: 0x80000000 mute=1 step=0 size=0 offset=0 (0/0dB) Connections: 2 + <- nid=2 [audio output] (selected) + [DISABLED] <- nid=3 [audio output] [DISABLED]
It seems that audioset 1 (as=1
) is connected to the headphones and pcm2
.
However, all the speakers are disabled:
> sysctl dev.hdaa.1 | grep '^dev.*pin.*Speaker' dev.hdaa.1.nid30: pin: Speaker (None) [DISABLED] dev.hdaa.1.nid27: pin: Speaker (None) [DISABLED] dev.hdaa.1.nid26: pin: Speaker (None) [DISABLED] dev.hdaa.1.nid24: pin: Speaker (None) [DISABLED] dev.hdaa.1.nid20: pin: Speaker (Fixed) [DISABLED]
Let’s look at nid20
, because that is the only fixed speaker:
> sysctl dev.hdaa.1.nid20 dev.hdaa.1.nid20: pin: Speaker (Fixed) [DISABLED] Widget cap: 0x0040058d PWR UNSOL STEREO Pin cap: 0x00010014 PDC OUT EAPD Pin config: 0x90170120 as=2 seq=0 device=Speaker conn=Fixed ctype=Analog loc=Internal color=Unknown misc=1 Pin control: 0x00000000 EAPD: 0x00000002 EAPD Output amp: 0x80000000 mute=1 step=0 size=0 offset=0 (0/0dB) Connections: 1 + [DISABLED] <- nid=2 [audio output]
Normally, we want the sound to go to the speakers, unless the headphones are
connected.
The way to do that is to set the same audioset for both (as=1
in this
case), and them set the speakers as sequence 0 (seq=0
) and the headphones
as sequence 15.
To test this, the following commands are used:
sysctl dev.hdaa.1.nid20_config="as=1 seq=0 misc=0" sysctl dev.hdaa.1.nid33_config="as=1 seq=15" sysctl dev.hdaa.1.reconfig=1
This enables both.
Note that without misc=0
the speakers did not work.
Normally, this configuration is set in /boot/device.hints
, and that is
where I put them.
The syntax there is slightly different:
hint.hdaa.1.nid20.config="as=1 seq=0 misc=0" hint.hdaa.1.nid33.config="as=1 seq=15"
See snd_hda(4)
for more information.
Scheduler tweaks for desktop use
In /etc/sysctl.conf
, I added the following:
kern.sched.preempt_thresh=224
This improves interactivity for a desktop/laptop role.
ZFS tweak
By default, ZFS uses a lot of memory for its Adaptive Replacement Cache (“ARC”). On this machine, the ARC grew to about 85% of memory. Since it is adaptive, the cache size will reduce when programs request more memory.
If you want to reduce the amount of memory used by ZFS ARC to e.g. 2 GiB, add
the following to /boot/loader.conf
:
vfs.zfs.arc.max="2147483648"
When I did some test with a CPU and memory intensive program (CalculiX FEA) it performed significantly faster with the reduced ZFS cache. Probably because it isn’t fighting ZFS over cache memory. :-)
Asides
Transferring data
At this point I wanted to transfer the data in my $HOME
to the laptop.
since I have a point-to-point gigabit ethernet connection between my
workstation and styx, the fastest way to do that is with netcat (nc
).
First we start the “listener” on styx:
cd /home nc -l 65000 | tar xvf -
Then on the machine I’m coming from:
cd /home tar cvf - rsmith/ | nc -N styx.erewhon.home 65000
The top speeds (achieved with large files) over a gigabit point-to-point link was ≈122 MB/s. That pretty much saturates the ethernet connection.
Speed test
As a speed test, I ran the multithreaded CalculiX FEA solver on an existing calculation. On a workstation with an i7-7700 running as 3.6 GHz this takes about 27.5 seconds with symmetric multithreading (“SMT”) disabled.
On the Ryzen 5500U running at 2 GHZ, it took 24 seconds with SMT disabled. With SMT enabled it took 25 seconds.
For comments, please send me an e-mail.
Related articles
- Writing speed on FreeBSD 13.1-p2 amd64 with ZFS
- Gnumeric build fix for FreeBSD
- Writing speed on FreeBSD 12.1-STABLE amd64
- Cleaning up old port configurations
- Opencascade problem