Easily Migrate from Linux to FreeBSD
If you are already experienced with Linux, FreeBSD should feel very familiar. The operating systems have a lot in common, due both to their Unix heritage and many shared modern components. Much of what may be unfamiliar to a Linux user adopting FreeBSD is also inconsistent between Linux distributions themselves.
In this article, we will cover some of the conceptual differences between Linux and FreeBSD, and go on to contrast some aspects of the basic system utilities and the differing views of hardware given by the two systems.
Structure and Organization
The fact that FreeBSD is a more unified entity is a significant difference of note. On Linux there is a diverse range of choices covering the core components needed to build on the kernel to form a usable working system. While this diversity does bring an element of choice it can lead to a lack cohesion. FreeBSD components are all developed together so where a change has an impact across subsystems developers can consider the full picture. Though we have a FreeBSD focus here, it is actually Linux that is the outlier in this regard–most operating systems are complete unified entities with a clear separation to applications.
In practical terms the apparent difference if you come to FreeBSD with existing knowledge of Linux is greater separation between the base system and user-installed packages. The base system includes all necessary core functionality, and is updated as a single unit. Additional optional software is installed from ports or packages and managed separately.
This separation is reflected in the filesystem hierarchy, as any program installed via ports or packages is located in /usr/local/bin or /usr/local/sbin, while similar core system utilties run from /usr/bin or /usr/sbin. For the duration of a release (a major version number like 13.*), the base system ABI and API remains stable, and the distinction between base system and installed packages remains clear. Being able to combine a stable base system with up-to-date 3rd party applications and packages can be an advantage over Linux distributions where using long-term support releases often entails being pinned to older versions of the packages as well.
Under FreeBSD, the ports system enables easy access to and building of optional software from source, while the pkg command retrieves binary packages and is analogous to tools like apt, yum, dnf and pacman on Linux.
There is also the option to configure and compile both ports and the base system manually. We went into more detail on this in the article “Customizing FreeBSD Ports and Packages”. [https://klarasystems.com/articles/customizing-freebsd-ports-and-packages/]
You might also be interested in
Get more out of your FreeBSD development
Kernel development is crucial to many companies. If you have a FreeBSD implementation or you’re looking at scoping out work for the future, our team can help you further enable your efforts.
From the early days of Linux, the GNU project was used as the source for many traditional Unix command-line utilities. GNU conventions for such things as command-line options have thus been influential on Linux.
On FreeBSD, many commands lack the GNU-inspired long form and optional options, and don’t allow options to come after non-optional arguments. For example, in the following command the long form –all is not recognized, so the -l will be treated as a filename instead of the “long-form listing” argument:
ls --all file –l
You’ll find some commands like grep and diff on FreeBSD that are largely compatible with their GNU counterparts, but many commands have remained somewhat simpler, only picking up the more useful enhancements. Should a FreeBSD user need them, the GNU coreutils themselves may also be installed directly from ports or packages.
One prominent command where you may notice significant differences when coming from Linux is the ps command. The origins of this go back to earlier Unix history and the division between System V and BSD. System V adopted the conventional ‘-’ prefix for options to ps but used different letters. On Linux, ps accepts either the BSD options without a ‘-’ prefix or the System V ones with it.
If you’re accustomed to typing a command like ps -ef to list every process with full details then you’ll discover that doesn’t work on FreeBSD. This may be the case if your early Unix experience was on a System V based OS such as Solaris or IRIX.
While the option letters differ, the functionality is much the same. To list all processes you would use ps ax. There isn’t a direct counterpart to -f unless you select explicit fields to output with -o but ps aux is a common short form that includes more detail in the output. Arguably, BSD syntax is a better choice even for Linux users themselves, since it functions as well under most Linux distros as it does under BSD—which makes using the BSD syntax an easy way to increase portability of scripts and a sysadmin’s working toolkit.
Linux also exposes a lot of information about processes in a special filesystem mounted at /proc. FreeBSD can optionally provide this as part of the Linuxulator compatibility subsystem, but the corresponding native interface is via the procstat command rather than a special psuedo filesystem.
Managing hardware is one of the primary roles of an operating system. Both Linux and FreeBSD present special device files in /dev which correspond to hardware devices such as disks. These special files allow applications to interact with hardware device drivers using standard input/output operations, and act as a mechanism for identifying and naming devices.
In the past you would find a fixed static structure below /dev but on a modern system, you’ll find a dynamically updated view of currently attached hardware. This means that the ls command on /dev works as a simple way to discover what hardware is available on the system.
FreeBSD and Linux populate /dev using different mechanisms. FreeBSD has a special in-kernel devfs filesystem which exposes the device view based on the internal kernel structures, while Linux uses udev to implement a similar system in userspace. Putting that detail aside, both systems include commands to give richer details of the detected hardware.
On Linux, there are a number of commands with names starting with ls. This can vary between distributions but examples include lsblk, lspci, lsusb, lsscsi, lshw, lscpu and lsmem. Some of these have fairly direct counterparts on FreeBSD like pciconf for lspci and usbconfig for lsusb.
For some basic values, you can use the sysctl command, for example sysctl -n hw.physmem outputs the amount of RAM and sysctl -n kern.disks lists the attached disks.
On Linux, lsblk is used for listing disks (block devices). These typically have names like /dev/sda, /dev/sdb etc with numeric suffixes for partitions, e.g. /dev/sda1. This naming covers most hardware types but you may come across other names such as /dev/sr0 for an optical drive or /dev/mmcblk0 for MMC memory.
On FreeBSD, device names reflect the hardware driver with documentation in a man page in section 4, e.g. ada(4) for the ATA driver. While there is an lsblk command in FreeBSD ports there are also options within the base system. There are two relevant subsystems:
- CAM unifies the interface to low-level SCSI, ATA, NVMe etc devices.
- GEOM deals with block devices and layering further block level features like RAID and encryption on them.
Using the CAM subsystem, we can list disks with the command camcontrol devlist. This requires root permissions, and produces a succinct list of devices and their hardware address. camcontrol allows various low-level commands to be sent to disk devices. One simple example is camcontrol eject which can be used to eject removable devices such as CDs.
Using the GEOM layer, the command for listing disks would be geom disk list. This outputs a good amount of detail—but unlike the Linux lsblk command, FreeBSD’s lsblk doesn’t include disk partitions. To list partitions under FreeBSD, use geom part list or just gpart list.
Aside from the obsoleted fdisk tool, gpart is FreeBSD’s primary tool for managing disk partitions.
A technical curiosity you may notice is that disks appear as character devices on FreeBSD but as block devices on Linux. In ls listings, this is visible as a c rather than a b in the first character on each line:
freebsd% ls -l /dev/ada0 crw-r----- 1 root operator 0x67 16 Jul 08:04 /dev/ada0 linux$ ls -l /dev/sda brw-rw---- 1 root disk 8, 0 Feb 27 13:17 /dev/sda
On other Unix systems you may have had to contend with both forms existing and needing to know to use the block device with the mount command and the character device with most other commands. The use of a character device ensures unbuffered, raw access rather than implying single byte reads and writes.
While FreeBSD dropped block device files, Linux added a flag for programs to use when opening the device to select raw access. The upshot is that on either Linux or FreeBSD, you’ll only need to be concerned with one canonical device file when identifying a storage device.
The canonical device names found directly under /dev can depend on the order in which disks are detected, so are not guaranteed to be stable between reboots under either Linux or FreeBSD. It is wise to use a stable device name in /etc/fstab or when adding disks to a ZFS pool. On Linux, stable device names can be found in /dev/disk/by-id or /dev/disk/by-label.
FreeBSD provides similar stable device names in /dev/gpt for GPT partition labels, as well as /dev/diskid and /dev/gptid for autogenerated IDs, but the autogenerated IDs are disabled by the installer. They can be enabled by adding the following lines to /boot/loader.conf:
After a reboot, /dev/diskid and /dev/gptid will be available.
In addition to providing a stable device name, labels allow descriptive information to be attached such as the physical location—so it’s good practice to label your disks.
FreeBSD mirrors the device files under names reflecting labels under /dev/label or /dev/gpt where GPT partitioning is used. Run glabel status to list existing labels. glabel also allows labels to be added, for example:
glabel label slot3 /dev/ada2
For NVMe drives FreeBSD exposes both an nvd and nvme device file. The nvd(4) driver is used with GEOM to expose the disk but some things like the smartd(8) disk monitoring daemon needs to use the nvme(4) device.
Once you’ve identified your disk, commands like fsck and mount work much the same between FreeBSD and Linux, although the available filesystems differ. For things like USB sticks, the old DOS FAT filesystem is named msdosfs on FreeBSD rather than vfat. And the equivalent for Linux bind mounts involves a special nullfs filesystem.
Modern FreeBSD installations typically use OpenZFS as the default filesystem, whereas most Linux distributions default to ext4. When OpenZFS isn’t desired or appropriate, FreeBSD offers UFS2 as an effective, simpler filesystem roughly similar in performance, capabilities, and resource consumption to Linux’s ext4.
Most Linux distributions moved away from the traditional Unix tools like netstat, route, arp, and ifconfig for network configuration in favor of the new ip command. However, the older tools are still generally available on Linux— perhaps because it is very simple to use ifconfig and route, and they can be fairly forgiving to variations in exact syntax.
To list available network interfaces under FreeBSD, the most well-known command is ifconfig -l but it is useful to be aware of netstat -i which provides a more succinct list along with packet statistics. The interfaces have names based on the driver, so em0 would be the first device created with the em(4) driver. Configuring an interface with an IP address and using it for a static route can be as simple as the following example:
ifconfig em0 10.0.1.2/24 route add 10.0.128.0/24 10.0.1.1
To list routes, the command is netstat -rn, which may not be as obvious as ip route show on Linux. The Linux ss command for probing sockets often gets mentioned as being a replacement for netstat, but netstat is focused on statistics and covers much else besides sockets. For listing open network sockets, FreeBSD’s sockstat tool is generally easier to use than netstat -a.
FreeBSD configures network devices on boot with stanzas in /etc/rc.conf. This style of configuration is similar to /etc/network/interfaces found in older versions of Debian, or /etc/sysconfig/network-scripts in older Redhat versions.
FreeBSD does not currently offer dynamic, desktop-focused management of network interfaces similar to what the netplan or NetworkManager systems provide to Linux distributions—but for more typical and largely static network configurations, you won’t miss the added complexity those solutions bring with them.
The basic commands for creating and managing users on FreeBSD are well covered in the FreeBSD handbook [https://docs.freebsd.org/en/books/handbook/basics/#users-synopsis] and don’t differ markedly from what you may have seen on Linux. The recommended commands on Linux can vary between distributions, but typically you’ll find combinations of either useradd or adduser.
FreeBSD also offers a pw utility which combines all of adding, removing, and modifying both users and groups into a single tool. For user management, a more general configuration management tool such as ansible can be worth considering. Ansible has the advantage of using identical syntax across operating systems.
On Linux systems, it is very common to use sudo for operations that require root permissions. FreeBSD traditionally relies on the simpler su command instead, and does not include sudo by default, although it is available to install as a package.
From a security standpoint, the benefit of sudo is that it is more granular, as only individual commands are run privileged. Needing to prefix specific commands may also protect against typing errors and user-error relative to an interactive root session. However, the fact that the shell lacks privileged access to the filesystem can make sudo less convenient, needing tricks such as running sudo tee as a workaround for redirection.
Fundamentally, sudo adds significant attack surface because it is a powerful tool with many features like support for security policies defined in LDAP, so the system is likely more secure without it. If you need the additional functionality sudo offers, either sudo or doas (a minimal alternative) may easily be installed from ports or packages.
When setting up a FreeBSD system note that only users that are members of the wheel group are permitted to change to root with su. This adds a layer of security, and is similar to the sudo and/or wheel groups often found on Linux distributions.
Subscribe to the Klara articles feed to get notified when the next part of our migrating from Linux to FreeBSD series is published.