目標:在FreeBSD跑Linux才有的圖形應用程式。
測試環境:
- FreeBSD 14.0 Release
- Linux Jail的系統版本為Ubuntu 22.04
1. 說明#
本文用到的軟體:
- Linuxulator
- FreeBSD chroot Jail
跑Linux程式我首先想到的是Docker,但目前FreeBSD 14的Docker得用bhyve虛擬機跑,Distrobox不可行,所以要高效率的跑Linux程式,得用Linuxulator。
Linuxulator功能類似轉譯Windows程式的Wine,讓我們可以在FreeBSD系統以原生效能執行Linux的二進位檔。準確來說,Linuxulator不是轉譯,而是重新實現Linux ABI。
有了Linuxlator,就可以搭配FreeBSD內建的chroot指令,建立一個Linux的Jail。Jail就是讓程式跑在受限制的監獄,或可理解為容器吧。在Docker出現以前,chroot也是Linux上最常見的一種容器。
Linuxulator本身就可以執行Linux二進位檔,為何還要建立Jail呢?Jail並非必要的步驟,但Linuxulator只能執行單一的Linux二進位執行檔,有時還要補動態連結檔;即使FreeBSD的套件庫有收一些Linux移植過來的程式,可數目有限。
相較之下Jail建立的Linux環境附有userspace的Linux套件,環境比較完整,可以無縫使用Linux的套件管理器來安裝軟體。
例如我們可以在FreeBSD建立Ubuntu的Jail,再使用APT安裝軟體。這樣安裝軟體很方便,又不會跟FreeBSD系統的套件衝突。
且由於很多Linux發行版都有提供"bootstrap"一類的工具,所以要安裝Arch Linux、Alpine Linux、Fedora等其他發行版的Linux Jail也不是問題的。
2. 設定Linuxulator#
Linuxulator是FreeBSD內建功能,無需安裝。
- 設定開機啟用Linux服務,並載入linux核心模組。設定之後重開機。
sudo sysrc dbus_enable="YES"
sudo sysrc linux_enable="YES"
sudo sysrc kld_list+="linux linux64"
- 根據FreeBSD Wiki記載,FreeBSD 14僅相容到Linux核心4.4的ABI。有些Linux程式可能會顯示
FATAL: Kernel too old
的錯誤。這時Linux核心的版本可以用變數compat.linux.osrelease
強制覆寫,但不保證功能正常:
echo "compat.linux.osrelease=6.6.37" | sudo tee -a /boot/loader.conf
此外,在Linux Jail裡面使用uname
指令的時候,系統回報的依然是FreeBSD,而非Linux版本。
3. 安裝Ubuntu Jail#
相關文章: debootstrap建立Ubuntu系統的使用方式
- 我們需要安裝debootstap,這個工具可以用來建立Ubuntu或Debian的rootfs。
sudo pkg install debootstrap
在安裝後應會自動建立
/compat/ubuntu/
目錄,Ubuntu的rootfs要放到這裡。(不要使用/compat/linux
,因為它是保留給CentOS相關的linux-base-c7
套件使用的)用debootstrap,從台灣伺服器下載Ubuntu 22.04系統到那個目錄
sudo debootstrap jammy "/compat/ubuntu/" "http://tw.archive.ubuntu.com/ubuntu"
- 將Linux需要的目錄掛載,以下內容請寫入到
/etc/fstab
。
devfs /compat/ubuntu/dev devfs rw,late 0 0
tmpfs /compat/ubuntu/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0
fdescfs /compat/ubuntu/dev/fd fdescfs rw,late,linrdlnk 0 0
linprocfs /compat/ubuntu/proc linprocfs rw,late 0 0
linsysfs /compat/ubuntu/sys linsysfs rw,late 0 0
/tmp /compat/ubuntu/tmp nullfs rw,late 0 0
- 其中掛載home目錄的時候要注意,FreeBSD手冊是直接掛進去以方便共享檔案,但我希望Jail內的home跟FreeBSD的home是隔離的:
/home/user/UbuntuHome /compat/ubuntu/home nullfs rw,late 0 0
若有FreeBSD目錄想跟Jail裡面的Linux共享,再額外掛載:
/home/user/Downloads /compat/ubuntu/mnt/host_shared nullfs rw,late 0 0
- 重開機,這樣就能用chroot指令進入Ubuntu Jail了:
sudo chroot /compat/ubuntu /bin/bash
- 編輯
/etc/apt/sources.list
apt update
apt install vim
vim /etc/apt/sources.list
- 補上main、restricted、universe的套件庫
deb [trusted=yes] http://tw.archive.ubuntu.com/ubuntu jammy main restricted universe
deb [trusted=yes] http://tw.archive.ubuntu.com/ubuntu jammy-security main restricted universe
deb [trusted=yes] http://tw.archive.ubuntu.com/ubuntu jammy-updates main restricted universe
- 更新套件庫後就可用APT安裝套件。
apt update
chroot Linux內執行的X11程式應會直接顯示在FreeBSD的螢幕上,但不會吃到3D加速
如果沒有的話執行xhost指令允許所有X客戶端連線:
xhost local:
至於Fcitx5輸入法得在Linux容器另外安裝。
注意chroot內無法使用systemd相關指令,所以跑服務你都得手動輸入二進位檔的絕對路徑來啟動。
還有,Docker、Flatpak、Snap是無法在chroot內使用的。