How to Install Ubuntu on FreeBSD | Linux Binary Compatibility

This article will discuss the procedure for installing a basic Ubuntu system into FreeBSD's built-in Linux Binary Compatibility, so that Ubuntu and Debian-based desktop applications, such as Signal, Spotify and Netflix, can run directly on FreeBSD. The discussion in this article uses Ubuntu 20.04 which will be installed into the FreeBSD 13.2 Stable system for the AMD64 64-bit architecture.

FreeBSD's built-in Linux Binary Compatibility allows FreeBSD users, running 32-bit i386, 64-bit amd64 or 64-bit arm64 architectures, to install and run 32-bit and 64-bit Linux binaries directly on FreeBSD machines. This is done through system call tables, which means, Linux applications can run without emulation or virtualization. FreeBSD's built-in Linux Binary Compatibility was introduced in the 90s.


1. Ubuntu Linux Kernel

The first step that must be taken to run Ubuntu on FreeBSD is to activate the Ubuntu Linux kernel on the FreeBSD machine. Basically FreeBSD has built-in binary compatibility with Linux. This makes it possible to run Ubuntu and Linux binaries. This is activated by loading a Linux kernel module. The following is the Linux kenel in FreeBSD.

kldload linux
kldload linux64
kldload fdescfs
kldload linprocfs
kldload tmpfs
kldload linsysfs
So that the Linux kernel can be active on the FreeBSD machine, so that when the computer reboots/restarts the kernel can be directly read by FreeBSD. Enter the Linux kernel script in the /boot/loader.conf file.

root@ns1:~ # ee /boot/loader.conf
linux_load="YES"
linux64_load="YES"
fdescfs_load="YES"
linprocfs_load="YES"
tmpfs_load="YES"
linsysfs_load="YES"
The script above will make the Ubuntu Linux kernel permanent on the FreeBSD system. After the kernel becomes permanent, create the rc.d script in the /etc/rc.conf file.

root@ns1:~ # ee /etc/rc.conf
kld_list="linux linux64 cuse fusefs /boot/modules/i915kms.ko"
linux_enable="YES"
ubuntu_enable="YES"


2. Create the rc.d Ubuntu Base System Script

Type the following script to start activating the Ubuntu Base System.

root@ns1:~ # touch /usr/local/etc/rc.d/ubuntu
root@ns1:~ #
chmod +x /usr/local/etc/rc.d/ubuntu
root@ns1:~ #
ee /usr/local/etc/rc.d/ubuntu
#!/bin/sh
#
# PROVIDE: ubuntu
# REQUIRE: archdep mountlate
# KEYWORD: nojail
#

. /etc/rc.subr

name="ubuntu"
desc="Ubuntu for FreeBSD Linux Binary Compatibility"
rcvar="ubuntu_enable"
start_cmd="${name}_start"
stop_cmd=":"

unmounted()
{
[ `stat -f "%d" "$1"` == `stat -f "%d" "$1/.."` -a `stat -f "%i" "$1"` != `stat -f "%i" "$1/.."` ]
}

ubuntu_start()
{
local _tmpdir
load_kld -e 'linux(aout|elf)' linux
case `sysctl -n hw.machine_arch` in
amd64)
load_kld -e 'linux64elf' linux64
;;
esac
if [ -x "/compat/ubuntu/sbin/ldconfigDisabled" ]; then
_tmpdir=`mktemp -d -t linux-ldconfig`
/compat/ubuntu/sbin/ldconfig -C ${_tmpdir}/ld.so.cache
if ! cmp -s "${_tmpdir}/ld.so.cache" "/compat/ubuntu/etc/ld.so.cache"; then
cat "${_tmpdir}/ld.so.cache" > "/compat/ubuntu/etc/ld.so.cache"
fi
rm -rf ${_tmpdir}
fi
load_kld pty
if [ `sysctl -ni kern.elf64.fallback_brand` -eq "-1" ]; then
sysctl kern.elf64.fallback_brand=3 > /dev/null
fi
if [ `sysctl -ni kern.elf32.fallback_brand` -eq "-1" ]; then
sysctl kern.elf32.fallback_brand=3 > /dev/null
fi
sysctl compat.linux.emul_path="/compat/ubuntu"
unmounted "/compat/ubuntu/dev" && (mount -o nocover -t devfs devfs "/compat/ubuntu/dev" || exit 1)
unmounted "/compat/ubuntu/dev/fd" && (mount -o nocover,linrdlnk -t fdescfs fdescfs "/compat/ubuntu/dev/fd" || exit 1)
unmounted "/compat/ubuntu/dev/shm" && (mount -o nocover,mode=1777 -t tmpfs tmpfs "/compat/ubuntu/dev/shm" || exit 1)
unmounted "/compat/ubuntu/home" && (mount -t nullfs /home "/compat/ubuntu/home" || exit 1)
unmounted "/compat/ubuntu/proc" && (mount -o nocover -t linprocfs linprocfs "/compat/ubuntu/proc" || exit 1)
unmounted "/compat/ubuntu/sys" && (mount -o nocover -t linsysfs linsysfs "/compat/ubuntu/sys" || exit 1)
unmounted "/compat/ubuntu/tmp" && (mount -t nullfs /tmp "/compat/ubuntu/tmp" || exit 1)
unmounted /dev/fd && (mount -o nocover -t fdescfs fdescfs /dev/fd || exit 1)
unmounted /proc && (mount -o nocover -t procfs procfs /proc || exit 1)
true
}

load_rc_config $name
run_rc_command "$1"

The script above will enable the Ubuntu Base System on a FreeBSD machine. So when the computer reboots/restarts the FreeBSD system it will automatically read the Ubuntu Base System script above. Let's try restarting the Ubuntu Base System now.

root@ns1:~ # service ubuntu restart


3. Create a ZFS Datasheet Linux Compatibility Directory

ZFS Linux datasheets are used to create snapshots, delete files and delete entire volume contents safely without disturbing the FreeBSD directory file system. Follow the script below to create a ZFS datasheet for Linux.

root@ns1:~ # zfs create -o compression=on -o mountpoint=/compat zroot/compat
root@ns1:~ #
zfs snapshot -r zroot/compat@2022-04-22
If the ZFS Linux datasheet has been created, continue by creating a directory for the Ubuntu Base System.

root@ns1:~ # mkdir -p /compat/ubuntu/{dev/fd,dev/shm,home,proc,sys,tmp}
Activate Ubuntu Base System

root@ns1:~ # service ubuntu restart
compat.linux.emul_path: /compat/ubuntu -> /compat/ubuntu

4. Installing the Ubuntu Base System into the Linux Compatibility Directory

The Ubuntu Base System installation file is "debootstrap". This file will be used to download and install a base Ubuntu system by specifying an Ubuntu target, such as focal for Focal Fossa, which is the 20.04 LTS version of Ubuntu.

root@ns1:~ # pkg install linux-sublime-text4
root@ns1:~ #
pkg install debootstrap
Download and install the Ubuntu Base System into the Linux compatibility directory.

root@ns1:~ # debootstrap --arch=amd64 --no-check-gpg focal /compat/ubuntu
I: Configuring netcat-openbsd...
I: Configuring isc-dhcp-client...
I: Configuring debconf-i18n...
I: Configuring vim-tiny...
I: Configuring ca-certificates...
I: Configuring libapt-pkg6.0:amd64...
I: Configuring gir1.2-glib-2.0:amd64...
I: Configuring whiptail...
I: Configuring keyboard-configuration...
I: Configuring libpython3.8-stdlib:amd64...
I: Configuring python3.8...
I: Configuring libxml2:amd64...
I: Configuring libpython3-stdlib:amd64...
I: Configuring apt...
I: Configuring apt-utils...
I: Configuring python3...
I: Configuring python3-six...
I: Configuring python3-gi...
I: Configuring shared-mime-info...
I: Configuring python3-netifaces...
I: Configuring lsb-release...
I: Configuring python3-cffi-backend...
I: Configuring python3-pkg-resources...
I: Configuring python3-dbus...
I: Configuring python3-yaml...
I: Configuring netplan.io...
I: Configuring ubuntu-advantage-tools...
I: Configuring python3-nacl...
I: Configuring networkd-dispatcher...
I: Configuring python3-pymacaroons...
I: Configuring console-setup-linux...
I: Configuring console-setup...
I: Configuring kbd...
I: Configuring ubuntu-minimal...
I: Configuring libc-bin...
I: Configuring systemd...
I: Configuring ca-certificates...
I: Base system installed successfully.
Fix dynamic links (ELF interpreter) with symbolic links.

root@ns1:~ # cd /compat/ubuntu/lib64/
root@ns1:/compat/ubuntu/lib64 #
rm ./ld-linux-x86-64.so.2
root@ns1:/compat/ubuntu/lib64 #
ln -s ../lib/x86_64-linux-gnu/ld-2.31.so ld-linux-x86-64.so.2
Restart Ubuntu.

root@ns1:/compat/ubuntu/lib64 # service linux restart
root@ns1:/compat/ubuntu/lib64 #
service ubuntu restart
compat.linux.emul_path: /compat/ubuntu -> /compat/ubuntu

5. Ubuntu Configuration

To configure Ubuntu on a FreBSD system, we must enter a chroot jail, which will limit the configuration process to the base Ubuntu file system. If Ubuntu displays a message about a missing group ID, this can be ignored. You will see, that the Command Prompt will change.

root@ns1:~ # chroot /compat/ubuntu /bin/bash
root@ns1:/#
printf "%b\n" "0.0 0 0.0\n0\nUTC" > /etc/adjtime
root@ns1:/#
dpkg-reconfigure tzdata

Current default time zone: 'Asia/Jakarta'
Local time is now: Sun Jul 9 14:31:08 WIB 2023.
Universal Time is now: Sun Jul 9 07:31:08 UTC 2023.


root@ns1:/#
printf "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00aptitude
root@ns1:/#
printf "APT::Cache-Start 251658240;" > /etc/apt/apt.conf.d/00aptitude
root@ns1:/#
printf "deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse" > /etc/apt/sources.list
root@ns1:/#
exit
exit
root@ns1:~ #
If the above script has been executed, it means that we have enabled Linux Binary Compatibility on FreeBSD and installed the Ubuntu base system onto it. With Ubuntu Linux active on FreeBSD, now we can install the Ubuntu repository on FreeBSD. Now we test by updating Ubuntu with the basic Ubuntu script, namely "apt update"

root@ns1:~ # chroot /compat/ubuntu /bin/bash
root@ns1:/#
apt update
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Get:2 http://archive.ubuntu.com/ubuntu focal/main amd64 Packages [970 kB]
Get:3 http://archive.ubuntu.com/ubuntu focal/main Translation-en [506 kB]
Get:4 http://archive.ubuntu.com/ubuntu focal/restricted amd64 Packages [22.0 kB]
Get:5 http://archive.ubuntu.com/ubuntu focal/restricted Translation-en [6212 B]
Get:6 http://archive.ubuntu.com/ubuntu focal/universe amd64 Packages [8628 kB]
Get:7 http://archive.ubuntu.com/ubuntu focal/universe Translation-en [5124 kB]
Get:8 http://archive.ubuntu.com/ubuntu focal/multiverse amd64 Packages [144 kB]
Get:9 http://archive.ubuntu.com/ubuntu focal/multiverse Translation-en [104 kB]
Fetched 15.8 MB in 9s (1715 kB/s)
Reading package lists... Done
Building dependency tree... Done
All packages are up to date.
From the script display above, everything is running normally. We continue again by upgrading Ubuntu.

root@ns1:/# apt list --upgradable
Listing... Done
root@ns1:/#
apt upgrade
Reading package lists... Done
Building dependency tree... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

root@ns1:/#
apt autoremove
Reading package lists... Done
Building dependency tree... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

root@ns1:/#
apt clean
root@ns1:/#
Perfect, all configurations are nothing wrong and Ubuntu has been running normally on the FreeBSD machine. Now you can install Ubuntu-based programs on FreeBSD. To be more convincing, we test install the NGINX application on Ubuntu.

root@ns1:~ # chroot /compat/ubuntu /bin/bash
root@ns1:/#
apt update
Hit:1 http://archive.ubuntu.com/ubuntu focal InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.

root@ns1:/#
apt install nginx
Reading package lists... Done
Building dependency tree... Done
The following additional packages will be installed:
fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6 libgd3 libjbig0 libjpeg-turbo8 libjpeg8
libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libpng16-16
libtiff5 libwebp6 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxpm4 libxslt1.1 nginx-common nginx-core
Suggested packages:
libgd-tools fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
fontconfig-config fonts-dejavu-core libfontconfig1 libfreetype6 libgd3 libjbig0 libjpeg-turbo8 libjpeg8
libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream libpng16-16
libtiff5 libwebp6 libx11-6 libx11-data libxau6 libxcb1 libxdmcp6 libxpm4 libxslt1.1 nginx nginx-common nginx-core
0 upgraded, 25 newly installed, 0 to remove and 0 not upgraded.
Need to get 3851 kB of archives.
After this operation, 12.8 MB of additional disk space will be used.
Do you want to continue? [Y/n]
y
To install Ubuntu applications on a FreeBSD machine, what you have to pay attention to is changing the command prompt. Consider the following example.

root@ns1:~ #   
root@ns1:~ #
chroot /compat/ubuntu /bin/bash
root@ns1:/#
The script above explains root@ns1:~ # is a FreeBSD command prompt, you cannot run Ubuntu applications at this command prompt. After running the chroot /compat/ubuntu /bin/bash command, the command prompt will change to root@ns1:/#, meaning we are active in the Ubuntu command prompt and can install Ubuntu applications at the root@ns1:/# command prompt.
Iwan Setiawan

I Like Adventure: Mahameru Mount, Rinjani Mount I Like Writer FreeBSD

Post a Comment

Previous Post Next Post