在龙芯笔记本(8089D)上安装 Gentoo

我手头有一个十一年前买的龙芯笔记本——逸珑 8089D,当时买来纯粹是用来作纪念的,毕竟它算是第一个批量出售的搭载国产 CPU(Loongson 2F)的笔记本。

本子自带的是什么系统已经不记得了,不过后来我在上面装过 Debian,装过 Fedora,不过因为这些系统的镜像都太旧了,放了很长时间之后基本就没有办法更新了。加上硬盘容量只有 8G,也没有什么可以折腾的空间。

后来我在换电脑的时候,从旧的电脑上拆下了 500G 的 SATA 固态硬盘。因为新的电脑用的都是 NVME 的固态,所以这个硬盘就没有用了,于是安到了龙芯笔记本上。

这个时候,还有官方支持龙芯 2F 的系统,基本就只剩下 OpenBSDNetBSD 了。于是我就选择安装了 OpenBSD。

最近又把这个本子翻了出来,主要有两个原因。一是想把它连接上打印机,这样我在打印的时候,就不用把笔记本抱到打印机旁边了。另一个是想把它作为 Samba 服务器,放一些电视剧,分享给老的 iPad 2 播放。

1. 使用 OpenBSD 遇到的问题

起初我把 OpenBSD 更新到了最新的 7.5 版本,这个很简单,基本上按照官方给的帮助文件 一步步来就可以了。

然后尝试编译安装需要的软件。不过由于我对 OpenBSD 并不熟悉,一些简单的问题我还可以处理,稍微困难一些的我就解决不了了。

比如在安装 vim 的时候,发现它依赖的 security/libsodium 无法安装。找了一圈问题,最后发现是需要把 /usr/include/loongson/param.h 里面的 #ifdef _KERNEL 删掉,直接引入 #define PAGE_SHIFT 14 的定义,相当于回退了 openbsd/src#184e245

又比如在安装 textproc/icu4c 的时候,下载的文件校验有问题,发现是上游源文件有更新

1
2
3
ftp https://github.com/openbsd/ports/commit/4f32770.patch -o /tmp/4f32770.patch
cd /usr/ports/textproc/icu4c
patch -Np1 < /tmp/4f32770.patch

不过遇到的最大的问题,是有软件依赖 GCC,而 GCC 又无法编译安装,这个我就无能为力了。

于是我放弃了继续使用 OpenBSD,开始寻找其它的解决方案。

2. 选择安装 Gentoo

之前我曾经尝试过安装 Gentoo,不过官方 提供的镜像 比较老,现在已经没有办法更新了。

我也尝试过从 stage3 开始安装,不过各种问题层出不穷。旧的内核可以直接拿过来用,倒是能够直接登录,不过会有各种报错。编译新的内核,结果又有问题,启动不起来(我对内核编译并不熟悉)。还有遇到过在安装过程中,无法使用 passwd 更新密码的情况,这个是因为旧的网络启动镜像 无法挂载 /dev 分区,原因未知。

不过这次这些问题都得到了解决。Druggo Yang 作了一个新的网络启动镜像,可以正常加载 /dev 分区。dramforever 给出了一个比较新的内核配置,也可以直接拿过来使用。

3. 交叉编译内核

首先是在笔记本上给龙芯交叉编译内核。我是在 WSL 里面安装的 Gentoo,目前官方的文档 已经足够详细了,直接按照说明安装即可。

按照官方的说明,需要先把下载的 stage3 压缩包解压再导入 WSL。
实测并不需要,直接导入 tar.xz 文件即可:

1
wsl --import Gentoo D:\Gentoo\ .\stage3-amd64-openrc-********T*****Z.tar.xz --version 2

首先安装必需的软件:

1
2
3
4
5
6
7
8
## crossdev: https://wiki.gentoo.org/wiki/Crossdev
## eselect/repository: https://wiki.gentoo.org/wiki/Eselect/Repository
emerge -avqn sys-devel/crossdev app-eselect/eselect-repository
## 添加并同步 crossdev 仓库
eselect repository create crossdev
emerge --sync crossdev
## 后续不需要再更新 crossdev 仓库
echo "auto-sync = no" >> /etc/portage/repos.conf/eselect-repo.conf

然后配置交叉编译的环境:

1
crossdev -t mips64el-unknown-linux-gnuabi64

龙芯 2F 使用的是 64 位 MIPS3 架构,支持 o32、n32、n64 三种 ABI。官方的 multilib 默认使用 n32,但 Rust 和 Go 都只支持 o32 和 n64,不支持 n32。因此我直接使用了 n64 的 ABI。

由于最新的 stage3 使用的是 merged-usr 配置,因此对交叉编译环境也做相应的调整:

1
2
3
emerge -avqn sys-apps/merge-usr
merge-usr --root /usr/mips64el-unknown-linux-gnuabi64
ln -sv usr/bin /usr/mips64el-unknown-linux-gnuabi64/bin

选择相应的 PROFILE:

1
2
3
4
5
6
7
8
# PORTAGE_CONFIGROOT=/usr/mips64el-unknown-linux-gnuabi64 \
# eselect profile set default/linux/mips/23.0/mipsel/n64
## 这个地方建议使用绝对路径。
## 对编译内核没有影响,但如果后续使用 qemu 的话,
## 使用绝对路径可以保证 chroot 之后链接位置依然是正确的。
rm /usr/mips64el-unknown-linux-gnuabi64/etc/portage/make.profile
ln -sv /var/db/repos/gentoo/profiles/default/linux/mips/23.0/mipsel/n64 \
/usr/mips64el-unknown-linux-gnuabi64/etc/portage/make.profile

/usr/mips64el-unknown-linux-gnuabi64/etc/portage/make.conf 文件末尾添加以下内容:

1
2
3
4
## 设置下载镜像
GENTOO_MIRRORS="https://mirrors.tuna.tsinghua.edu.cn/gentoo"
## 虚拟软件和二进制软件没有必要构建二进制包
EMERGE_DEFAULT_OPTS="--buildpkg-exclude 'acct-*/* sys-kernel/*-sources virtual/* app-alternatives/* */*-bin'"

先安装需要的补丁文件:

1
2
3
4
5
6
7
8
mkdir -p /etc/portage/patches/sys-kernel/gentoo-sources
cd /etc/portage/patches/sys-kernel/gentoo-sources

## 参考:https://github.com/dramforever/nixos-loongson2f/blob/main/flake.nix
wget https://github.com/loongson-community/linux-2f/commit/08fda2d.patch \
-O 0001-MIPS-Loongson2EF-Correct-SCI-Event-numbers.patch
wget https://github.com/loongson-community/linux-2f/commit/ad2584d.patch \
-O 0002-MIPS-Loongson2EF-Yeeloong-platform-driver.patch

然后安装内核源文件:

1
emerge -avqn sys-kernel/gentoo-sources:6.6.37

交叉编译内核:

1
2
3
4
5
6
7
8
9
10
export ARCH=mips
export CROSS_COMPILE=mips64el-unknown-linux-gnuabi64-
export MAKEFLAGS="-j$(nproc)"

cd /usr/src/linux-6.6.37-gentoo
wget https://raw.githubusercontent.com/dramforever/nixos-loongson2f/main/lemote2f_config -O .config
sed -i 's/hda3/sda2/' .config
## 所有新选项保持默认即可
make oldconfig
make all

打包编译好的内核:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export INSTALL_MOD_PATH='ROOT'
export INSTALL_PATH='ROOT/boot'

rm -rf ROOT && mkdir -pv ROOT/boot
make modules_install
make install

## 必不可少的步骤,否则解压的时候会覆盖掉 `/lib` 的软链接
mkdir -pv ROOT/usr
mv ROOT/lib ROOT/usr

KERNEL_VERSION=$(make kernelversion)
cd ROOT && tar -cf $HOME/linux-${KERNEL_VERSION}.tar .

unset ARCH CROSS_COMPILE MAKEFLAGS INSTALL_MOD_PATH INSTALL_PATH

4. 准备其它的文件

除了编译好的内核外,还需要准备以下几个文件:

  • 下载好的 stage3 包
  • 文件系统表 fstab
  • PMON 启动配置文件 boot.cfg

后两个不是必需的,也可以在安装的时候直接输入。这里为了方便,我就提前编辑好了需要的内容,这样安装的时候直接复制过去就可以了。

然后在本地启动一个 http 服务器,可以直接访问上面的文件即可。

  • 如果已经安装了 python 3 的话,可以使用 python -m http.server 80 即可;
  • 如果已经安装 nodejs,可以使用 http-server
  • 也可以使用了 MobaXterm 的 HTTP Server 功能。

5. 准备网络引导镜像

首先下载网络引导镜像:

1
wget https://druggo.org/tmp/netboot-yeeloong-6.6.21.img

然后启动一个 tftp 服务器,可以访问下载的镜像文件。

  • 可以使用 tftpd32/tftpd64
  • 也可以使用 MobaXterm 的 TFTP Server 功能。

6. 启动龙芯笔记本。

上面的准备工作都做完了,就可以开始正式安装了。

这里我们要采用网络引导的方式,因此需要将龙芯笔记本插上网线,连接到路由器上。

也可以使用 usb 安装,参考 Gentoo Wiki
需要把 U 盘格式化成 ext2 格式,而且不能大小超过 2G (?),否则无法识别。

启动龙芯笔记本,并连续按右上角的 Del 键,进入 PMON 引导界面。

首先配置网络,然后加载网络引导镜像并启动。

1
2
3
PMON> ifaddr rtl0 192.168.2.101
PMON> load tftp://192.168.2.38/netboot-yeeloong.img
PMON> g

7. 安装 Gentoo 系统

启动镜像之后,就可以开始安装系统了,基本上可以分成以下几步:

  1. 对硬盘进行分区,并格式化;
  2. 安装 stage3 和 kernel;
  3. 加载 chroot 环境,并进行必要的配置;
  4. 安装完成,重启!

7.1. 硬盘分区

首先使用 fdisk 对硬盘进行分区:

分区 挂载点 文件系统 大小
/dev/sda1 /boot ext2 128M
/dev/sda2 swap swap 4G
/dev/sda3 / ext4 剩余所用空间

这里我给 swap 分区分的比较大,因为之间在使用 OpenBSD 的时候,发现 1G 的交换分区不够用,最后是又添加了 3G 的交换文件才能成功编译一些软件。

然后进行格式化:

1
2
3
4
5
6
## 刷新 /dev
mdev -s

mke2fs /dev/sda1
mkswap /dev/sda2
mkfs.ext4 /dev/sda3

接下来就可以挂载硬盘了:

1
2
3
4
mkdir -p /mnt/gentoo
mount /dev/sda3 /mnt/gentoo
mkdir -p /mnt/gentoo/boot
mount -t ext2 /dev/sda1 /mnt/gentoo/boot

7.2. 安装 stage3 包和内核

1
2
3
4
5
6
7
8
9
10
11
12
cd /mnt/gentoo
wget http://192.168.2.38/stage3.tar.xz
wget http://192.168.2.38/linux-6.6.37-gentoo.tar

tar xf stage3.tar.xz
tar xf linux-6.6.37-gentoo.tar

## 获取 boot.cfg 和 fstab
## 一定仔细检查一下这两个文件
## 如果这两个文件出错,系统将无法正常启动
wget http://192.168.2.38/boot.cfg -O /mnt/gentoo/boot/boot.cfg
wget http://192.168.2.38/fstab -O /mnt/gentoo/etc/fstab

7.3. 加载 chroot 环境

在 chroot 之前,需要挂载必要的文件系统:

1
2
3
4
5
6
7
8
9
## 挂载 /proc,/sys,/dev
mount -t proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev

## 进入 chroot 环境
chroot /mnt/gentoo /bin/bash

7.4. 配置系统

这里的做法和 Gentoo Wiki 里面有所不同,我们只进行最简单的配置,较为复杂的配置都等到重启之后再进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
## 可以让终端更好看一些,非必要步骤
source /etc/profile
export PS1="(chroot) $PS1"

## 配置 sshd 服务,之后可以直接 ssh 到笔记本
sed -i 's/^#PermitRootLogin .*/PermitRootLogin yes/' /etc/ssh/sshd_config
rc-update add sshd default

## 修改 root 密码
passwd

## 退出 chroot 环境
exit

然后卸载硬盘,并重启即可。

1
2
3
4
5
6
7
8
9
umount /mnt/gentoo/dev/shm
umount /mnt/gentoo/dev/pts
umount /mnt/gentoo/dev
umount /mnt/gentoo/sys
umount /mnt/gentoo/proc
umount /mnt/gentoo/boot
umount /mnt/gentoo

reboot

8. 远程登录笔记本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 复制主机公钥
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.2.101

## 配置使用密钥登录 ssh
cat <<EOF >> ~/.ssh/config

Host yeeloong
HostName 192.168.2.101
User root
IdentityFile ~/.ssh/id_rsa

EOF

## 登录笔记本
ssh yeeloong

9. 进行基础配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## 删除下载的压缩包
rm /stage3.tar.xz /linux-6.6.37-gentoo.tar

## 修改字符集
sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
eselect locale set en_US.utf8
source /etc/profile

## 修改时区
echo "Asia/Shanghai" > /etc/timezone
emerge --config sys-libs/timezone-data

## 修改主机名
echo yeeloong > /etc/hostname

## 开启系统服务日志
sed -i 's/#rc_logger="NO"/rc_logger="yes"/' /etc/rc.conf

## 取消使用密码登录 ssh
sed -i 's/^PermitRootLogin yes/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
rc-service sshd restart

10. 配置 Portage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## GCC 优化
sed -i "s/-march=mips3/-march=loongson2f/" /etc/portage/make.conf

## 启用官方仓库
mkdir -p /etc/portage/repos.conf
cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf

## 使用清华大学镜像
sed -i "s#^sync-uri = .*#sync-uri = rsync://mirrors.tuna.tsinghua.edu.cn/gentoo-portage#" \
/etc/portage/repos.conf/gentoo.conf
echo -e '\nGENTOO_MIRRORS="https://mirrors.tuna.tsinghua.edu.cn/gentoo"' >> /etc/portage/make.conf

## 同步镜像
emerge --sync

11. 安装软件

配置 /usr/src/linux

1
2
3
4
5
6
7
8
9
10
11
mkdir -p /etc/portage/patches/sys-kernel/gentoo-sources

pushd /etc/portage/patches/sys-kernel/gentoo-sources
wget https://github.com/loongson-community/linux-2f/commit/08fda2d.patch \
-O 0001-MIPS-Loongson2EF-Correct-SCI-Event-numbers.patch
wget https://github.com/loongson-community/linux-2f/commit/ad2584d.patch \
-O 0002-MIPS-Loongson2EF-Yeeloong-platform-driver.patch
popd

emerge -avq gentoo-sources:6.6.37
eselect kernel set linux-6.6.37-gentoo

安装常用系统服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## mlocate:快速搜索文件
## dcron:定时运行任务
## chroy:NTP 时间同步
emerge -avq mlocate dcron chrony

## 启用 cron 日志
sed -i 's@DCRON_OPTS.*@DCRON_OPTS="-L /var/log/crond.log"@' /etc/conf.d/dcron
## 配置 dcron,使之可以运行 /etc/cron.{daily,hourly,monthly,weekly} 目录下的文件
crontab /etc/crontab
## 启用 dcron 服务
rc-service dcron start
rc-update add dcron default

## 启用 chrony 服务
rc-service chronyd start
rc-update add chronyd default

安装常用软件:

  • 编辑器:vim
  • 版本控制:git
  • Portage 相关:eix, genlop, gentoolkit, pkgdev
  • 系统监控:htop, strace, nload, dfc, lsof
  • 无线网络:wpa_supplicant
  • 查看硬件:pciutils, usbutils
  • 其它:tree, the_silver_searcher (ag)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
mkdir -p /etc/portage/package.accept_keywords

echo 'app-editors/vim perl python tcl' >> /etc/portage/package.use/vim

echo 'dev-vcs/subversion * ~*' >> /etc/portage/package.accept_keywords/git
echo 'dev-libs/libutf8proc * ~*' >> /etc/portage/package.accept_keywords/git
echo 'dev-vcs/git tk subversion' >> /etc/portage/package.use/git
echo 'dev-vcs/subversion perl' >> /etc/portage/package.use/git

echo 'dev-util/pkgdev * ~*' >> /etc/portage/package.accept_keywords/pkgdev
echo 'dev-util/pkgcheck * ~*' >> /etc/portage/package.accept_keywords/pkgdev
echo 'dev-libs/tree-sitter-bash * ~*' >> /etc/portage/package.accept_keywords/pkgdev
echo 'dev-libs/tree-sitter * ~*' >> /etc/portage/package.accept_keywords/pkgdev
echo 'dev-python/tree-sitter * ~*' >> /etc/portage/package.accept_keywords/pkgdev

echo 'sys-fs/dfc * ~*' >> /etc/portage/package.accept_keywords/dfc

## 因为远程链接时间太长的话会话可能会中断,因此使用 nohup 后台运行
nohup emerge -vq vim dev-vcs/git eix genlop gentoolkit pkgdev htop strace nload dfc lsof \
app-text/tree wpa_supplicant pciutils usbutils &

命令 ag 安装起来相对麻烦,仓库里面有一个 patch 会导致编译失败,需要去掉才能安装。
可以复制到 local 仓库手动修改 ebuild 文件,也可以使用用户补丁:

1
2
3
4
5
6
7
8
emerge -avq patchutils

mkdir -p /etc/portage/patches/sys-apps/the_silver_searcher

interdiff -q /var/db/repos/gentoo/sys-apps/the_silver_searcher/files/the_silver_searcher-2.2.0-no_lfs64.patch /dev/null \
> /etc/portage/patches/sys-apps/the_silver_searcher/Revert_the_silver_searcher-2.2.0-no_lfs64.patch

emerge -avq the_silver_searcher

之后再配置好 .vimrc.bashrc 就可以正常使用了😀。