# 11.7 Gentoo Linux 兼容层

Gentoo 兼容层通过 stage3 tarball 构建基本系统，构建前需启用 linux 内核模块。本节给出从守护进程配置到基本系统完成的完整脚本。

## 构建基本系统

构建 Gentoo Linux 兼容层前需启用核心守护进程。

### 守护进程

```sh
# service linux enable       # 设置 Linux 内核模块开机自启
# service linux start        # 启动 Linux 内核模块
# service dbus enable        # 设置 dbus 服务开机自启（一般桌面环境已配置）
# service dbus start         # 启动 dbus 服务（一般桌面环境已配置）
```

### 获取基本系统镜像

下载 Gentoo Stage3 镜像：

```sh
# fetch https://mirrors.ustc.edu.cn/gentoo/releases/amd64/autobuilds/20230101T164658Z/stage3-amd64-systemd-20230101T164658Z.tar.xz
```

上述链接会随版本更新，请自行获取最新链接。

创建 Gentoo 兼容层目录：

```sh
# mkdir -p /compat/gentoo
```

将 Gentoo 镜像解压到兼容层目录：

```sh
# tar xpvf stage3-amd64-systemd-20230101T164658Z.tar.xz -C /compat/gentoo --numeric-owner
```

### fstab 文件

编辑 **/etc/fstab** 文件，加入：

```sh
# Device        Mountpoint              FStype          Options                      Dump    Pass#
devfs           /compat/gentoo/dev      devfs           rw,late                      0       0
tmpfs           /compat/gentoo/dev/shm  tmpfs           rw,late,size=1g,mode=1777    0       0
fdescfs         /compat/gentoo/dev/fd   fdescfs         rw,late,linrdlnk             0       0
linprocfs       /compat/gentoo/proc     linprocfs       rw,late                      0       0
linsysfs        /compat/gentoo/sys      linsysfs        rw,late                      0       0
/tmp            /compat/gentoo/tmp      nullfs          rw,late                      0       0
#/home           /compat/gentoo/home     nullfs          rw,late                      0       0
```

项目结构：

```sh
/compat/gentoo/
├── dev/                  # 设备文件系统
│   ├── fd/               # 文件描述符文件系统
│   └── shm/              # 内存文件系统
├── etc/
│   ├── portage/
│   │   ├── make.conf     # Portage 配置文件
│   │   └── repos.conf/
│   │       └── gentoo.conf # Gentoo 仓库配置
│   └── resolv.conf       # DNS 配置
├── home/                 # 用户主目录（可选）
├── proc/                 # Linux 进程文件系统
├── sys/                  # Linux 内核对象文件系统
├── tmp/                  # 临时目录
└── usr/
    └── share/
        └── portage/
            └── config/
                └── repos.conf # 默认仓库配置
```

验证 **/etc/fstab** 文件中定义的所有文件系统的挂载情况：

```sh
# mount -al # 检查是否有编写错误
```

编辑 **/compat/gentoo/etc/portage/make.conf** 文件，加入：

```sh
MAKEOPTS="-j2"                                                                 # 设置 Gentoo 编译时使用的并行作业数为 2
GENTOO_MIRRORS="https://mirrors.ustc.edu.cn/gentoo"                            # 指定 Gentoo 镜像源为中国科学技术大学镜像
FEATURES="-ipc-sandbox -mount-sandbox -network-sandbox -pid-sandbox -xattr -sandbox -usersandbox"  # 禁用 Gentoo Portage 编译系统中的各种沙箱功能及扩展属性保留
```

进行基本配置：

```sh
# mkdir -p /compat/gentoo/etc/portage/repos.conf/                                        # 在 FreeBSD 系统中创建 Gentoo Portage 仓库配置目录
# cp /compat/gentoo/usr/share/portage/config/repos.conf /compat/gentoo/etc/portage/repos.conf/gentoo.conf  # 在 FreeBSD 系统中复制 Gentoo 的默认仓库配置文件
# cp /etc/resolv.conf /compat/gentoo/etc/                                                   # 在 FreeBSD 系统中将 DNS 配置复制到 Gentoo 兼容层
```

### 修改 Gentoo 的软件源

在 FreeBSD 下，编辑 **/compat/gentoo/etc/portage/repos.conf/gentoo.conf** 文件，修改 Gentoo 仓库配置文件：将 `sync-uri = rsync://rsync.gentoo.org/gentoo-portage` 修改为 `sync-uri = rsync://mirrors.tuna.tsinghua.edu.cn/gentoo-portage`。

进入 Gentoo 兼容层环境，使用 Bash 作为 shell：

```sh
# chroot /compat/gentoo /bin/bash # 此处位于 Gentoo!
```

使用 Gentoo 的 webrsync 工具同步 Portage 树：

```sh
# emerge-webrsync	# 获取 Gentoo ebuild 数据库快照。
```

## 测试使用

使用 Gentoo Portage 安装 screenfetch 工具，并显示详细输出：

```sh
# emerge -v screenfetch
```

在 Gentoo 环境中运行 `screenfetch` 命令，显示系统信息：

```bash
ykla / # screenfetch
         -/oyddmdhs+:.                root@ykla
     -odNMMMMMMMMNNmhy+-`             OS: Gentoo
   -yNMMMMMMMMMMMNNNmmdhy+-           Kernel: x86_64 Linux 6.2.10
 `omMMMMMMMMMMMMNmdmmmmddhhy/`        Uptime: 36m
 omMMMMMMMMMMMNhhyyyohmdddhhhdo`      Packages: 317
.ydMMMMMMMMMMdhs++so/smdddhhhhdm+`    Shell: bash 5.3.3
 oyhdmNMMMMMMMNdyooydmddddhhhhyhNd.   Disk: 2.4G / 187G (2%)
  :oyhhdNNMMMMMMMNNNmmdddhhhhhyymMh   CPU: 12th Gen Intel Core i7-1260P @ 16x 2.496GHz
    .:+sydNMMMMMNNNmmmdddhhhhhhmMmy   RAM: 2881MiB / 4053MiB
       /mMMMMMMNNNmmmdddhhhhhmMNhs:
    `oNMMMMMMMNNNmmmddddhhdmMNhs+`
  `sNMMMMMMMMNNNmmmdddddmNMmhs/.
 /NMMMMMMMMNNNNmmmdddmNMNdso:`
+MMMMMMMNNNNNmmmmdmNMNdso/-
yMMNNNNNNNmmmmmNNMmhs+/-`
/hMMNNNNNNNNMNdhs++/-`
`/ohdmmddhys+++/:.`
  `-//////:--.
```

## shell 脚本

脚本内容：

```sh
#!/bin/sh

rootdir=/compat/gentoo   # 设置 Gentoo 根目录路径
fetch https://mirrors.ustc.edu.cn/gentoo/releases/amd64/autobuilds/latest-stage3-amd64-systemd.txt   # 下载最新 Stage3 构建列表
gentoodownload=$(grep 'stage3-amd64-systemd' latest-stage3-amd64-systemd.txt | awk '{print $1}')   # 提取最新 Stage3 文件名
rm latest-stage3-amd64-systemd.txt   # 删除临时文件

url="https://mirrors.ustc.edu.cn/gentoo/releases/amd64/autobuilds/"   # Gentoo 下载基础 URL

echo "Starting Gentoo Linux installation..."   # 输出开始信息
echo "check modules ..."   # 输出模块检查提示

# 检查 linux 模块是否启用
if [ "$(sysrc -n linux_enable)" = "NO" ]; then
        echo "linux module should be loaded. Continue? (Y|n)"   # 提示用户是否继续
        read answer   # 读取用户输入
        case $answer in
                [Nn][Oo]|[Nn])
                        echo "linux module not loaded"   # 提示模块未加载
                        exit 1   # 退出脚本
                        ;;
                [Yy][Ee][Ss]|[Yy]|"")
                        sysrc linux_enable=YES   # 启用 linux 模块
                        ;;
        esac
fi
echo "start linux"   # 输出启动信息
service linux start   # 启动 linux 模块

# 检查 dbus 是否安装
if ! /usr/bin/which -s dbus-daemon;then
        echo "dbus-daemon not found. Install it [Y|n]"   # 提示安装 dbus
        read  answer   # 读取用户输入
        case $answer in
            [Nn][Oo]|[Nn])
                echo "dbus not installed"   # 提示未安装
                exit 2   # 退出脚本
                ;;
            [Yy][Ee][Ss]|[Yy]|"")
                pkg install -y dbus   # 安装 dbus
                ;;
        esac
    fi

# 检查 dbus 是否启用
if [ "$(sysrc -n dbus_enable)" != "YES" ]; then
        echo "dbus should be enabled. Continue? (Y|n)"   # 提示是否启用
        read answer
        case $answer in
            [Nn][Oo]|[Nn])
                        echo "dbus not running"   # 提示未运行
                        exit 2
                        ;;
            [Yy][Ee][Ss]|[Yy]|"")
                        service dbus enable   # 启用 dbus 服务
                        ;;
        esac
fi
echo "start dbus"   # 输出启动信息
service dbus start   # 启动 dbus 服务

echo "now we will bootstrap gentoo"   # 提示开始 bootstrap

fetch ${url}/$gentoodownload   # 下载最新 Stage3 文件
mkdir -p ${rootdir}   # 创建 Gentoo 根目录
tar xpvf stage3-amd64-systemd*.tar.xz -C ${rootdir} --numeric-owner   # 解压 Stage3 文件
rm stage3-amd64-systemd*.tar.xz   # 删除压缩包

# 检查 nullfs 是否启用
if [ ! "$(sysrc -f /boot/loader.conf -qn nullfs_load)" = "YES" ]; then
        echo "nullfs_load should be loaded. Continue? (Y|n)"
        read answer
        case $answer in
            [Nn][Oo]|[Nn])
                echo "nullfs is not loaded"
		exit 3
                ;;
            [Yy][Ee][Ss]|[Yy]|"")
                sysrc -f /boot/loader.conf nullfs_load=yes   # 设置 nullfs 自动加载
                ;;
        esac
fi

# 加载 nullfs 模块
if ! kldstat -n nullfs >/dev/null 2>&1;then
        echo "load nullfs module"
        kldload -v nullfs
fi

echo "mount some fs for linux"   # 输出挂载提示
echo "devfs ${rootdir}/dev devfs rw,late 0 0" >> /etc/fstab   # 配置 devfs
echo "tmpfs ${rootdir}/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0" >> /etc/fstab   # 配置 tmpfs
echo "fdescfs ${rootdir}/dev/fd fdescfs rw,late,linrdlnk 0 0" >> /etc/fstab   # 配置 fdescfs
echo "linprocfs ${rootdir}/proc linprocfs rw,late 0 0" >> /etc/fstab   # 配置 linprocfs
echo "linsysfs ${rootdir}/sys linsysfs rw,late 0 0" >> /etc/fstab   # 配置 linsysfs
echo "/tmp ${rootdir}/tmp nullfs rw,late 0 0" >> /etc/fstab   # 配置 /tmp
mount -al   # 挂载所有文件系统

echo "For Gentoo Linux, we should change 'compat.linux.osrelease' to upgrade Linux kernel version, Continue? (Y|n)"
read answer
case $answer in
	[Nn][Oo]|[Nn])
		echo "close to success"
		exit 4
		;;
	[Yy][Ee][Ss]|[Yy]|"")
		echo "compat.linux.osrelease=6.2.10" >> /etc/sysctl.conf   # 设置内核版本兼容
		sysctl compat.linux.osrelease=6.2.10   # 立即生效
                ;;
esac
echo "complete!"   # 提示完成
echo "to use: chroot ${rootdir} /bin/bash"   # 提示如何进入 Gentoo 环境
echo ""
echo "I will set resolv.conf to Ali DNS"   # 提示将设置 DNS
echo "continue?[Y|n]"
read answer
case $answer in
	[Nn][Oo]|[Nn])
		echo "Set up your Gentoo by yourself. Bye!"   # 用户选择不自动配置
		exit 0
		;;
	[Yy][Ee][Ss]|[Yy]|"")
		echo "nameserver 223.5.5.5" >> ${rootdir}/etc/resolv.conf   # 设置 DNS
esac
echo "Now write MAKEOPTS FEATURES in /compat/gentoo/etc/portage/make.conf -- using USTC mirrors for GENTOO_MIRRORS"
echo "MAKEOPTS=\"-j2\"" >> ${rootdir}/etc/portage/make.conf   # 设置 MAKEOPTS
echo "GENTOO_MIRRORS=\"https://mirrors.ustc.edu.cn/gentoo\"" >> ${rootdir}/etc/portage/make.conf   # 设置镜像源
echo "FEATURES=\"-ipc-sandbox -mount-sandbox -network-sandbox -pid-sandbox -xattr -sandbox -usersandbox\"" >> ${rootdir}/etc/portage/make.conf   # 设置 FEATURES

echo "Now configuring software sources -- Using TUNA mirror for emerge-webrsync"
mkdir -p ${rootdir}/etc/portage/repos.conf/   # 创建 repos.conf 目录
cp ${rootdir}/usr/share/portage/config/repos.conf ${rootdir}/etc/portage/repos.conf/gentoo.conf   # 复制仓库配置
sed -i "" 's/rsync.gentoo.org/mirrors.tuna.tsinghua.edu.cn/' ${rootdir}/etc/portage/repos.conf/gentoo.conf   # 修改为清华镜像

echo "I will run emerge-webrsync"
chroot ${rootdir} /bin/bash -c "emerge-webrsync"   # 在 Gentoo 环境同步 Portage 树

echo "all done."   # 提示完成
echo "Now you can run '#chroot /compat/gentoo/ /bin/bash' to enter Gentoo"   # 提示如何进入 Gentoo 环境
```


---

# 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/di-11-zhang-linux-er-jin-zhi-jian-rong-ceng/di-11.7-jie-gentoo-linux-jian-rong-ceng.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.
