# 21.9 故障排除与未竟事宜

本章将系统地介绍 Linux 兼容层在实际使用过程中可能遇到的若干常见问题及其相应的解决方案与技术建议。

## Linux 兼容层的声音

目前 chroot 的 Linux 兼容层内部如果没有声音，你可能需要在 FreeBSD 中直接运行 Linux 程序，而非 chroot。

Ubuntu 兼容层：

编辑 `/compat/ubuntu/etc/asound.conf`，写入以下两行，注意那是英文感叹号 `!` 不是数字 `1`。

```sh
pcm.!sysdefault pcm.plug:oss
pcm.!default pcm.sysdefault
```

## 直接从 FreeBSD 的命令行运行软件（基于 Ubuntu 兼容层）

直接从 FreeBSD 的命令行运行软件而不需要 chroot 的方法：

①

```sh
# sysctl compat.linux.emul_path=/compat/ubuntu # 立即生效
# echo compat.linux.emul_path=/compat/ubuntu >> /etc/sysctl.conf # 永久化设置
```

②

```sh
# mv /compat/ubuntu/lib64/ld-linux-x86-64.so.2  /compat/ubuntu/lib64/ld-linux-x86-64.so.2.back
# ln -s /compat/ubuntu/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /compat/ubuntu/lib64/ld-linux-x86-64.so.2
```

然后就不需要 chroot 可以直接在终端运行 Linux 的程序了（只是部分程序），需要指定绝对路径。

**Arch 和 openSUSE 兼容层只需要 ①，无需 ②**

### 参考文献

* Micski D K. FREEBSD, SYSTEM ADMINISTRATION Install Ubuntu base system into FreeBSD’s Linux Binary Compatibility\[EB/OL]. (2021-12-21)\[2026-03-25]. <https://www.micski.dk/2021/12/21/install-ubuntu-base-system-into-freebsds-linux-binary-compatibility/>. 该文章详细介绍在 FreeBSD 上构建 Ubuntu 兼容层的完整技术流程，为本章节实践提供重要参考。

## 以普通用户权限运行 QQ

兼容层的用户与 FreeBSD 用户存在 UID 映射关系。

假设你在 FreeBSD 的普通用户名是 ykla，UID 是 1001（正常情况下默认为 1001）：

```sh
# useradd --uid 1001 --gid 0 -m ykla # 此步骤在兼容层里操作！
```

> **警告**
>
> 在 Arch 中创建用户 ykla 后，此用户无法用于 yay 安装软件，仍然需要使用 shell 脚本默认创建的 test 用户。

## 从图标启动程序

* QQ.desktop 内容（以 Ubuntu 兼容层为例）：

```ini
[Desktop Entry]
Name=QQ
Exec=/compat/ubuntu/opt/QQ/qq --no-sandbox --in-process-gpu %U
Terminal=false
Type=Application
Icon=/compat/ubuntu/usr/share/icons/hicolor/512x512/apps/qq.png
StartupWMClass=QQ
Categories=Network;
Comment=QQ
MimeType=x-scheme-handler/tencent;
```

* Chrome.desktop 内容（以 Ubuntu 兼容层为例）：

```ini
[Desktop Entry]
Version=1.0
Type=Application
Name=Chrome
Comment=
Exec=/compat/ubuntu/opt/google/chrome/chrome --no-sandbox --in-process-gpu
Icon=/compat/ubuntu/opt/google/chrome/product_logo_256.png
Path=
Terminal=false
StartupNotify=false
```

## 运行 Chrome（以 Ubuntu 兼容层为例）

```sh
# wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb # 无需代理软件，可以直连。此时已经位于 Ubuntu 兼容层了。
# apt install ./google-chrome-stable_current_amd64.deb # 此时已经位于 Ubuntu 兼容层了。
```

```sh
# /usr/bin/google-chrome-stable --no-sandbox --no-zygote --in-process-gpu  # 此时已经位于 Ubuntu 兼容层了。
```

## 代理软件（以 Clash for Windows 为例）

Linux 兼容层的代理软件同时会影响 FreeBSD 的网络状态，因此直接在兼容层安装 Clash for Windows，设置代理的话 FreeBSD 一样可以使用代理访问网站。正常安装配置即可。

## Linux 兼容层网络（Linux QQ 没有网络）

如果本机有以太网卡 em0，和无线网卡 wlan0，但使用的是 wlan0 的网络，则 Linux 兼容层可能会出现没有网络的情况。因为 FreeBSD 的 em0 对应兼容层的 eth0，wlan0 对应 eth1，以此类推。但是 Linux 兼容层不能自动识别哪个有网，且默认使用 eth0。

所以，如果以太网 em0 没用，用的 wlan0，这时候要给不用的以太网卡 em0 随便指定一个不用的 IP：

* 临时设置（重启失效）：`# ifconfig em0 192.168.11.1`
* 永久性设置：即在 FreeBSD `/etc/rc.conf` 中加入（不影响该网卡正常使用）：

```sh
# ifconfig_em0_alias0="inet 192.168.11.1 netmask 255.255.255.0"
```

以上 `192.168.11.1` 为未分配的假 IP，可以自行设置成别的。

## 中文输入

将 `/home` 下的 `.profile` 放到兼容层的 `/` 目录下：

```sh
export LANG=zh_CN.UTF-8
export LANGUAGE=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8

export XMODIFIERS='@im=fcitx'
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
```

如果遇到类似 “sh: warning: setlocale: LC\_ALL: cannot change locale (zh\_CN.UTF-8)” 这样的错误，以 openSUSE 为例，安装 `glibc-lang` 和 `glibc-locale` 这两个包，退出兼容层后重新进入即可。其他系统可以搜索相似的包，例如 CentOS 兼容层，应该安装 `glibc-locale-source`、`glibc-langpack-zh`。

## sysctl 变量

```sh
# sysctl -a -d  | grep -E "linux|compat.linux"
```

可以列出常用变量。

## 使用命令行下载软件时报错 `403 Forbidden`

国内某些镜像站或出于流量限制等原因，只允许通过包管理器来获取软件包，禁止通过浏览器或其他方式获取软件包。当使用非指定包管理器拉取软件时，就会报错 “403 Forbidden”（禁止访问）。

这一般是通过限制包管理器 UA (User-Agent) 来实现的。

因此最简单的方法是换一个没有限制的镜像站，比如 TUNA/USTC Mirror。

## 课后习题

1. 尝试在不使用 `compat.linux.emul_path` 的情况下，直接在 FreeBSD 命令行运行 Linux 程序，分析该参数如何通过路径转换机制控制 Linux 进程的文件系统视图。
2. 修改 Ubuntu 兼容层中的 `ld-linux-x86-64.so.2` 链接，对比不同链接方式对 Linux 程序启动的影响。
3. 在 Linux 兼容层中配置代理软件，观察其对 FreeBSD 原生网络的影响和原理。
