注意:这里说的是基于 QEMU 的开发环境,不是真的 riscv64 机器,买真机请找 SiFive 下单 HiFive Unmatched 板子。


首先,你要有一台 Arch Linux 的机器。

准备工作

需要在一台 Arch Linux 机器上;

假如 ssh 连接不稳定,跑 extra-* 命令时推荐使用 nohup 或类似物;

确保 Linux 内核版本 >= 5.8,否则 glibc 会出问题,还会报怨找不到 /lib/ld-linux-riscv64-lp64d.so.1

  1. 将全部软件包的 riscv64 patch 下载到本地:

    1
    git clone https://github.com/felixonmars/archriscv-packages
  2. 修改 /etc/pacman.conf,在文件末尾添加两行(SiFive 板子上不需要,archlinuxcn 没有 riscv64 的源):

    1
    2
    [archlinuxcn]
    Server = https://repo.archlinuxcn.org/$arch
  3. 安装依赖:

    1
    2
    3
    sudo pacman -Sy
    sudo pacman -S base-devel asp pacman-contrib qemu-user-static binfmt-qemu-static devtools-riscv64 # 板子上不需要最后三个
    sudo pacman -S archlinux-keyring archlinuxcn-keyring # 板子上不需要最后一个

    注意,这里曾经需要手动给 devtools 打 patch,现在不需要了,肥猫已经将 devtools-riscv64 放到了 archlinuxcn 源里。如果是 SiFive 板子,可能得手动从 archlinuxcn 拉取 devtools-riscv64 的源代码(PKGBUILD 等)并手动 makepkg -si 得到 .tar.zst 再用 pacman -U foobar.tar.zst 来安装。

  4. 更新 asp 记录:

    1
    asp update
  5. 创建 alias

    1
    2
    3
    cd ~
    mkdir pkg # 用来放缓存之类的,不用管它
    alias rv64build="extra-riscv64-build -- -d ~/pkg:/var/cache/pacman/pkg"
  6. 配置 ~/.makepkg.conf

    1
    echo 'MAKEFLAGS="-j15"' >> ~/.makepkg.conf  # 假如你有 16 个核

开发

(假设你的工作目录为 $HOME,以下用 ~ 代替)

  1. 更新 riscv64 patch 仓库:

    1
    2
    3
    cd ~/archriscv-packages  # 就是最开始 git clone 的目录
    git pull
    cd ~ # 回到工作目录
  2. 获取 x86_64 版本的包源码:

    1
    asp checkout package-name
  3. 将对应的 riscv64 patch(如果存在的话)移动到 x86_64 版本的包源码所在目录:

    1
    cp ./archriscv-packages/package-name/*.patch ./package-name/trunk/
  4. 切换目录,应用 riscv64.patch

    1
    2
    cd ./package-name/trunk/
    patch -Np0 -i ./riscv64.patch # 可能有多个 patch 但需要手动应用的只有这个
  5. 修改 PKGBUILD 中的 arch

    修改前:

    1
    2
    3
    arch=(any)  # 这种不用修改
    arch=(x86_64)
    arch=("x86_64")

    分别对应到修改后:

    1
    2
    3
    arch=(any)
    arch=(riscv64)
    arch=("riscv64")

    总之就是把 x86_64 替换成 riscv64,别的不用动。这一步需要在应用 riscv64.patch 之后完成,顺序颠倒可能导致 patch 打不上。

  6. 编译:

    1
    2
    3
    # 需要位于 PKGBUILD 所在的目录中
    # 使用刚刚在「准备工作」里创建的 alias
    rv64build

PKGBUILD 说明

编译的过程其实就是使用 chroot 切换到一个干净的环境中,然后开始解析 PKGBUILD 文件。riscv64.patch 也是针对 PKGBUILD 文件的。

PKGBUILD 里会有一些东西:

  • source 数组,标明代码来源,在编译时会自动下载到本地。
    • 手动下载可以使用 updpkgsums,它在下载源码的同时会更新 PKGBUILD 中的 checksum。
  • prepare() 负责准备工作,通常是打 patch 和跑一些 sed 命令。
  • build() 负责编译工作,通常是 configure make cmake 之类的。
  • check() 负责测试工作,常见内容:make test 或者 npm run test 或者 ctest 之类的。
  • package() 负责最后的打包工作,例如指定依赖的 .so 文件,不用管。

手动操作进入 RISC-V 环境

首先,下载镜像并解压:

1
2
3
4
5
cd ~
wget -c https://archriscv.felixc.at/images/archriscv-20210601.tar.zst
sha512sum archriscv-20210601.tar.zst
mkdir ~/archriscv
sudo bsdtar -xvf archriscv-20210601.tar.zst -C archriscv

其中,sha512sum 结果应为

1
6f012a169fe6f1ea15aeb3283091466e7992f78d823951ee2170940fa030e7fa2394aee11bf67c29943d21579ab42d2262a3d5ca973b5de8be779f338ba1dd44  archriscv-20210601.tar.zst

随后,启动这个 archriscv 容器:

1
sudo systemd-nspawn -D ~/archriscv/ --machine archriscv -a -U

启动容器后,更新软件包:

1
pacman -Syu

检查自己是否在 riscv64 环境下:

1
2
$ uname -m
riscv64

安装一些软件包:

1
pacman -S vim nodejs-lts-gallium

不是所有 x86_64 的包都能装上,我们还在做艰苦的迁移工作。

比如:electron 当前还不支持 riscv64 架构,自然也就无法安装。

可能遇到的问题

GPG unknown public key

如果遇到报错如下:

1
FAILED (unknown public key FC1B547C8D8172C8)

那么说明需要导入 GPG Key。

导入命令:

1
gpg --recv-keys FC1B547C8D8172C8  # 这里的 hash 换成你在报错里看到的 key 就可以了

你也可以 cat PKGBUILD 并一次性导入其中提到的所有 key。

Failed retrieving file 'core.db'

如果你参考了 Arch Linux Wiki - Building in a clean chroot,在 riscv64 环境下(nspawn,或者你真的有 SiFive 的板子)使用如下命令:

1
2
mkarchroot $CHROOT/root base-devel
arch-nspawn $CHROOT/root pacman -Syu

那么你可能会在 pacman -Syu 时遇到这个报错:

1
error: failed retrieving file 'core.db' from archriscv.felixc.at : The requested URL returned error: 404

这是因为默认的 /etc/pacman.d/mirrorlist 配置有误,可以按如下方式修改:

1
echo "Server = https://archriscv.felixc.at/repo/$arch" > /etc/pacman.d/mirrorlist

之后重新 pacman -Syu 就可以了。

引用

该镜像的 pacman 软件源由中科院软件所 PLCT 实验室 Arch Linux 小队维护。

参考链接:

  1. 使用 QEMU 和 systemd nspawn 搭建 RISC-V 轻量级用户模式开发环境
  2. archbuild 脚本解读
  3. archbuild 使用参考
  4. FS#69563 - core/glibc 2.33 prevents Archlinux runing under systemd-nspawn

来源:https://blog.jiejiss.com/