10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

「FreeBSD使いたいけど、Linuxアプリが動かないと困る...」

安心して。FreeBSDはLinuxバイナリをそのまま動かせる

エミュレーションじゃなくて、カーネルレベルでLinuxシステムコールをサポートしてる。

Linuxulatorとは

┌─────────────────────────────────────────────────────────────┐
│                Linuxulator Architecture                      │
│                                                              │
│  ┌─────────────────────────────────────────────────────┐    │
│  │               Linux バイナリ                         │    │
│  │            (ELF, glibc, etc.)                       │    │
│  └─────────────────────────────────────────────────────┘    │
│                          ↓ syscall                          │
│  ┌─────────────────────────────────────────────────────┐    │
│  │          linux.ko (Linuxシステムコール変換)          │    │
│  │                                                      │    │
│  │  sys_linux_open() → sys_open()                      │    │
│  │  sys_linux_stat() → sys_stat()                      │    │
│  │  ...                                                 │    │
│  └─────────────────────────────────────────────────────┘    │
│                          ↓                                   │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              FreeBSD カーネル                        │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

カーネルモジュールがLinuxのシステムコールをFreeBSDのシステムコールに変換する。

有効化

カーネルモジュールのロード

kldload linux64

永続化

# /etc/rc.conf
linux_enable="YES"

# または /boot/loader.conf
linux64_load="YES"

確認

kldstat | grep linux
# 4    1 0xffffffff82400000   41000 linux64.ko

Linuxユーザーランドのインストール

CentOS 7ベース(推奨)

pkg install linux_base-c7

これで/compat/linux/にLinuxのベースシステムがインストールされる。

ls /compat/linux/
# bin  dev  etc  lib  lib64  opt  proc  root  run  sbin  sys  tmp  usr  var

必要に応じて追加パッケージ

pkg install linux-c7-gtk3
pkg install linux-c7-alsa-lib
pkg install linux-c7-dbus-libs
pkg install linux-c7-nss

procfsとlinprocfsのマウント

Linuxアプリが/procを使う場合に必要。

# /etc/fstab
linprocfs   /compat/linux/proc  linprocfs  rw          0  0
linsysfs    /compat/linux/sys   linsysfs   rw          0  0
tmpfs       /compat/linux/dev/shm tmpfs    rw,mode=1777 0  0

# マウント
mount /compat/linux/proc
mount /compat/linux/sys
mount /compat/linux/dev/shm

動作確認

Linuxのlsを実行

/compat/linux/bin/ls --version
# ls (GNU coreutils) 8.22

brandelfで確認

brandelf /compat/linux/bin/ls
# File '/compat/linux/bin/ls' is of brand 'Linux'.

実用例1: Linuxバイナリを直接実行

# Linuxのbashを実行
/compat/linux/bin/bash

# Linuxのpythonを実行(インストール済みの場合)
/compat/linux/usr/bin/python3

実用例2: Steamを動かす

# 依存パッケージ
pkg install linux-steam-utils

# Steamを起動
steam

トラブルシューティング

# 32bitライブラリが必要な場合
pkg install linux_base-c7
pkg install linux-c7-nss
pkg install linux-c7-alsa-plugins

# GPUドライバ
pkg install linux-nvidia-libs  # NVIDIA
pkg install linux-c7-dri       # Mesa

実用例3: LinuxのDockerを動かす(実験的)

# linux64 with Docker support (FreeBSD 14+)
pkg install linux-docker

※完全な互換性はまだない。本格的にDockerを使うならjailやbhyveを検討。

実用例4: Spotifyを動かす

# 必要なライブラリ
pkg install linux-c7-gtk3
pkg install linux-c7-alsa-plugins
pkg install linux-c7-nss
pkg install linux-c7-libcurl

# Spotifyをダウンロード(debパッケージを展開)
fetch https://repository-origin.spotify.com/pool/non-free/s/spotify-client/spotify-client_1.2.8.923_amd64.deb
ar x spotify-client_*.deb
tar xf data.tar.xz -C /compat/linux/opt/

# 実行
/compat/linux/opt/spotify/spotify

実用例5: VS Code(code-oss)

# Electronアプリには追加のライブラリが必要
pkg install linux-c7-gtk3 linux-c7-libxkbcommon linux-c7-nss

# VS Codeをダウンロード・展開
fetch https://update.code.visualstudio.com/latest/linux-x64/stable -o code.tar.gz
tar xf code.tar.gz -C /compat/linux/opt/

# 実行
/compat/linux/opt/VSCode-linux-x64/code

環境変数の設定

Linuxアプリを快適に使うための設定。

# ~/.bashrc または ~/.profile
export LD_LIBRARY_PATH=/compat/linux/usr/lib64:/compat/linux/lib64
export LIBGL_DRIVERS_PATH=/compat/linux/usr/lib64/dri

デバッグ

システムコールのトレース

truss /compat/linux/bin/ls

エラーの確認

# linuxのライブラリが見つからない場合
ldd /compat/linux/opt/someapp/bin/app
# libsomething.so.1 => not found

# 足りないライブラリを探す
pkg search linux-c7 | grep something

LD_DEBUGで詳細表示

LD_DEBUG=libs /compat/linux/opt/someapp/bin/app

パフォーマンス

LinuxulatorはエミュレーションではなくABI互換レイヤーなので、オーバーヘッドはほぼゼロ

# ネイティブ vs Linux版
time /bin/ls -laR /usr > /dev/null
# real 0.123s

time /compat/linux/bin/ls -laR /usr > /dev/null  
# real 0.125s  # ほぼ同じ

制限事項

動かないもの

  • Linuxカーネルモジュール(当然)
  • /devの特殊なデバイス(一部)
  • ptraceを使う高度なデバッガ(一部制限)
  • 最新のLinuxカーネル機能を使うアプリ

要注意

  • セキュリティパッチ: CentOS 7のライブラリは古い
  • glibcバージョン: 新しいLinuxバイナリは動かない可能性
  • 32bit: linux_base-c7はx86_64用

Ubuntuベースを使いたい場合

CentOS 7じゃなくてUbuntuを使いたい場合、debootstrapを使う。

pkg install debootstrap

# Ubuntu chrootを作成
debootstrap --arch=amd64 jammy /compat/ubuntu http://archive.ubuntu.com/ubuntu

# /etc/fstabに追加(procfs等)

ただし公式サポートはCentOS 7なので、自己責任で。

jail内でLinuxを動かす

より隔離された環境でLinuxバイナリを動かしたい場合。

# jail.conf
exec.start = "/compat/linux/bin/sh /compat/linux/etc/rc";
allow.mount.linprocfs;
allow.mount.linsysfs;

まとめ

FreeBSDのLinuxバイナリ互換機能:

  • linux64.koでシステムコールを変換
  • linux_base-c7でCentOS 7ユーザーランド
  • Steamなどのゲームも動く
  • パフォーマンスオーバーヘッドはほぼゼロ

「FreeBSDだとあのアプリが使えない」という言い訳はもう通用しない。

この記事が役に立ったら、いいね・ストックしてもらえると嬉しいです!

10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?