# 12.4.高级主题

所有与 Linux 相关的 [sysctl(8)](https://man.freebsd.org/cgi/man.cgi?query=sysctl\&sektion=8\&format=html) 控制项列表可以在 [linux(4)](https://man.freebsd.org/cgi/man.cgi?query=linux\&sektion=4\&format=html) 中找到。

某些应用程序需要挂载特定的文件系统。

这通常由 /etc/rc.d/linux 脚本处理，但可以通过执行以下命令在启动时禁用该脚本：

```sh
sysrc linux_mounts_enable="NO"
```

由 rc 脚本挂载的文件系统对于 chroot 或 jail 中的 Linux 进程无效；如有需要，请在 /etc/fstab 中进行配置：

```sh
devfs      /compat/linux/dev      devfs      rw,late                    0  0
tmpfs      /compat/linux/dev/shm  tmpfs      rw,late,size=1g,mode=1777  0  0
fdescfs    /compat/linux/dev/fd   fdescfs    rw,late,linrdlnk           0  0
linprocfs  /compat/linux/proc     linprocfs  rw,late                    0  0
linsysfs   /compat/linux/sys      linsysfs   rw,late                    0  0
```

由于 Linux 二进制兼容层已经支持运行 32 位与 64 位 Linux 二进制文件，因此无法再将仿真功能静态链接进自定义内核中。

## 12.4.1. 手动安装额外的库文件

> **注意**
>
> 对于使用 [debootstrap(8)](https://man.freebsd.org/cgi/man.cgi?query=debootstrap\&sektion=8\&format=html) 创建的基本系统子目录，请改为参照上文说明。

如果在配置好 Linux 二进制兼容层后某个 Linux 应用程序仍报告缺少共享库，请手动确定该 Linux 二进制程序所需的共享库并安装它们。

可以在使用相同 CPU 架构的 Linux 系统中使用 `ldd` 来确定该程序依赖哪些共享库。

例如，要查看 `linuxdoom` 所需的共享库，可在已安装 Doom 的 Linux 系统中运行以下命令：

```sh
% ldd linuxdoom
```

输出应类似如下：

```sh
libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0
libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0
libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29
```

然后，将输出中最后一列的所有文件从 Linux 系统复制到 FreeBSD 系统的 /compat/linux 下。复制完成后，为这些文件创建符号链接，链接名称使用输出中第一列的名称。

此示例将在 FreeBSD 系统上生成如下文件：

```sh
/compat/linux/usr/X11/lib/libXt.so.3.1.0
/compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3.1.0
/compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0
/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
```

如果某个 Linux 共享库已经存在，并且其主版本号与 `ldd` 输出中第一列相匹配，则无需复制输出中最后一列所指向的文件，因为已有的库通常可以正常工作。但如果复制的是更新版本的库，建议仍进行替换。只要符号链接指向新版本，就可以删除旧版本。

例如，FreeBSD 系统上已有以下库：

```sh
/compat/linux/lib/libc.so.4.6.27
/compat/linux/lib/libc.so.4 -> libc.so.4.6.27
```

而 `ldd` 显示某个程序需要较新的版本：

```sh
libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29
```

由于已有的库版本只是在末尾小数字位相差一两个版本，该程序应仍然可以使用这个稍旧的版本。但更稳妥的做法是使用更新版本替换：

```sh
/compat/linux/lib/libc.so.4.6.29
/compat/linux/lib/libc.so.4 -> libc.so.4.6.29
```

通常，在最初几次在 FreeBSD 上安装 Linux 程序时，才需要检查其依赖的共享库。随着系统上积累的 Linux 共享库越来越多，今后安装的新 Linux 程序通常就可以直接运行，无需额外处理。

## 12.4.2. 为 Linux ELF 可执行文件加标牌标识

FreeBSD 内核使用多种方式来判断一个待执行的可执行文件是否为 Linux 程序：它会检查 ELF 文件头中的标牌信息，查找已知的 ELF 解释器路径，并检查 ELF 注记；最后，默认情况下，如果一个 ELF 可执行文件没有标牌标识，也会被认为是 Linux 程序。

如果以上方法全部失败，尝试执行该程序时可能会出现如下错误信息：

```sh
% ./my-linux-elf-binary
```

输出可能如下：

```sh
ELF binary type not known
Abort
```

为了帮助 FreeBSD 内核区分 FreeBSD ELF 可执行文件与 Linux 可执行文件，可以使用 [brandelf(1)](https://man.freebsd.org/cgi/man.cgi?query=brandelf\&sektion=1\&format=html) 命令：

```sh
% brandelf -t Linux my-linux-elf-binary
```

## 12.4.3. 安装基于 Linux RPM 的应用程序

要安装基于 Linux 的 RPM 应用程序，首先安装软件包或 port [archivers/rpm4](https://cgit.freebsd.org/ports/tree/archivers/rpm4/) 。待安装完成，`root` 用户可以使用以下命令安装 `.rpm` 文件：

```sh
# cd /compat/linux
# rpm2cpio < /path/to/linux.archive.rpm | cpio -id
```

如有必要，请对安装后的 ELF 可执行文件使用 `brandelf`。注意，这样做将无法实现干净的卸载。

## 12.4.4. 配置主机名解析器

如果 DNS 无法使用，或者出现如下错误：

```sh
resolv+: "bind" is an invalid keyword resolv+:
"hosts" is an invalid keyword
```

请按如下方式配置 `/compat/linux/etc/host.conf`：

```ini
order hosts, bind
multi on
```

这表示先查找 `/etc/hosts`，然后再使用 DNS。当 `/compat/linux/etc/host.conf` 不存在时，Linux 应用程序会使用主系统中的 `/etc/host.conf`，但该文件在 FreeBSD 中默认不存在，因此会报错。如果没有使用 `/etc/resolv.conf` 配置名称服务器，请去掉 `bind`。

## 12.4.5. 其他信息

关于 Linux® 二进制兼容的工作机制，更多信息可参考文章 [Linux emulation in FreeBSD](https://docs.freebsd.org/en/articles/linux-emulation/)。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/hanbook/di-12-zhang-linux-er-jin-zhi-jian-rong-ceng/12.4.-gao-ji-zhu-ti.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
