写在前面

开发环境是 Archlinux ,本来是想直接用 Archlinux 的 riscv 工具链来交叉编译内核的,但是 gcc12 疯狂爆炸。所以最终选择了在 debian sid 的 chroot 环境中交叉编译。测试 gcc10 和 11 是好的。

它的资料也比较少的样子,文章主要对照着 Debian Wiki 针对上一代 VisionFive 的页面 和官方的 Github 仓库 里的 README 编写。

这里只是给出一套相对完整的验证过的步骤,关于原理性的和细节性东西还是请参考前面提到的 Debian Wiki 和官方 Github 仓库。

环境:

OS: Arch Linux x86_64
Kernel: 5.15.83-1-lts
Shell: zsh 5.9

准备交叉编译环境

制作 debian sid x86_64 rootfs ,这个环境只用于交叉编译内核↓

$ sudo pacman -S debootstrap
$ sudo debootstrap sid /srv/chroot/sid https://mirrors.bfsu.edu.cn/debian
$ sudo systemd-nspawn -D /srv/chroot/sid -M debian --bind-ro=/etc/resolv.conf
$ passwd root
$ logout

启动到 systemd-nspawn 容器↓

$ sudo systemd-nspawn -b -D /srv/chroot/sid -M debian --bind-ro=/etc/resolv.conf

安装需要的软件包,和 gcc11 或更低的交叉工具链↓

$ sudo apt-get install libncurses-dev libssl-dev bc flex bison make gcc gcc-11-riscv64-linux-gnu
$ sudo apt-get install build-essential devscripts rsync git
$ sudo ln -s /usr/bin/riscv64-linux-gnu-gcc-11 /usr/bin/riscv64-linux-gnu-gcc

构建内核 deb 包

获取内核源码↓

$ git clone --depth 1 https://github.com/starfive-tech/VisionFive2.git
$ cd VisionFive2
$ git branch
$ git checkout JH7110_VisionFive2_devel
$ git submodule init
$ git submodule update --depth 1 linux

定制并构建内核,可以在 menuconfig 打开 Device Drivers ---> Network device support ---> Wireless LAN 下面你需要的无线网卡模块。

$ cd linux/
$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- starfive_jh7110_defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc) bindeb-pkg LOCALVERSION=-starfive

完成后在上级目录可以找到编译获得的二进制包。

退出 chroot 环境↓

$ exit

制作 debian riscv rootfs

制作 debian sid riscv rootfs ,我们将在 /srv/chroot/riscv-chroot 建立一个可以直接拷贝到 SD 卡使用的根目录环境。

$ sudo pacman -S qemu-user-static qemu-user-static-binfmt debian-ports-archive-keyring
$ sudo debootstrap --arch=riscv64 --keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg --include=debian-ports-archive-keyring unstable /srv/chroot/riscv-chroot https://deb.debian.org/debian-ports/

如果你在 debootstrap 遇到 “Unable to execute target architecture” 这样的错误,则尝试下面的命令↓

$ sudo debootstrap --foreign --arch=riscv64 --keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg --include=debian-ports-archive-keyring unstable /srv/chroot/riscv-chroot http://deb.debian.org/debian-ports
$ sudo mkdir -p /srv/chroot/riscv-chroot/usr/bin/
$ sudo cp "$(which qemu-riscv64-static)" /srv/chroot/riscv-chroot/usr/bin/
$ sudo chroot /srv/chroot/riscv-chroot/ /debootstrap/debootstrap --second-stage

在 SD 卡建立文件系统

SD 卡上至少要有三个分区:

  • 第一分区 不使用
  • 第二分区 为 EFI 分区
  • 第三分区 为 /boot 分区,这个分区包含内核、 initramfs 和启动配置

在这篇文章中,采用了传统的 extlinux.conf 方式启动,如果希望使用 EFI + GRUB 的方式,可以参考之前提到过的 Debian Wiki 页面的 “Option 2: EFI with grub” 。另外文章中采用的分区方式中 /boot 并不是单独的分区,而是根文件系统的一部分。如果你希望使用单独的 /boot 分区,可以参考之前提到过的 Debian Wiki 页面末尾部分 “Tips to handle a separate /boot partition” 。

推荐 GPT 分区表,同时 MBR 分区表也是被支持的。

在 VisionFive2 上, SD 卡设备为 /dev/mmcblk1 ,下面的命令也假设你的设备名是这个。这些命令将格式化整个 SD 卡,请提前做好数据备份,仔细确认每条命令的正确性。

在格式化 SD 卡时,别忘了在第三分区标记 “legacy BIOS bootable” 标志。

$ sudo sgdisk -g --clear --new=1:0:+16M: --new=2:0:+100M: -t 2:EF00 --new=3:0:-1M: --attributes 3:set:2 -d 1 /dev/mmcblk1
$ sudo fdisk -l /dev/mmcblk1 # double check your work
sudo mkfs.vfat /dev/mmcblk1p2
sudo mkfs.ext4 -m 0 -L root /dev/mmcblk1p3
sudo mkdir -p /srv/chroot/riscv-chroot/boot/efi

配置 debian riscv rootfs

在 debootstrap 完成后,拷贝之前构建的内核软件包↓

$ sudo cp /srv/chroot/sid/root/VisionFive2/*.deb /srv/chroot/riscv-chroot/root/kernel-debs/

进入 chroot↓

$ sudo systemd-nspawn -D /srv/chroot/riscv-chroot/ -M debian --bind-ro=/etc/resolv.conf

此时你已经以 root 用户身份进入 chroot 环境。

安装内核↓

$ apt-get update
$ apt-get upgrade
$ apt-get install initramfs-tools openssh-server systemd-timesyncd rsync bash-completion
$ apt-get install ./kernel-debs/linux-*.deb

配置网络和主机名↓

$ cat <<EOF >> /etc/network/interfaces
allow-hotplug eth0
iface eth0 inet dhcp
EOF
$ echo visionfive > /etc/hostname

root 用户密码↓

$ passwd

如果不想配置 root 用户密码,可以安装 sudo 并建立普通用户,假设用户名为 youmu

$ apt-get install sudo
$ useradd -m -G sudo youmu
$ passwd youmu
$ chsh -s /bin/bash youmu

配置 u-boot ↓

$ cat <<EOF > /boot/uEnv.txt
kernel_comp_addr_r=0xb0000000
kernel_comp_size=0x10000000
EOF

链接一下所用的设备树↓

$ cd /lib/linux-image-5.15.0-starfive-g7b7b4eddd8d5/starfive/
$ sudo ln -s jh7110-visionfive-v2.dtb starfive_visionfive2.dtb

配置使用 extlinux 的 u-boot 启动↓

$ apt-get install u-boot-menu
$ cat <<EOF >> /etc/default/u-boot
U_BOOT_PARAMETERS="rw console=tty0 console=ttyS0,115200 earlycon rootwait stmmaceth=chain_mode:1 selinux=0"
EOF
$ cat /etc/default/u-boot # double check your work
$ dpkg-reconfigure linux-image-5.15.0-starfive-g7b7b4eddd8d5
$ cat /boot/extlinux/extlinux.conf
$ sed -i -e 's|root=[^ ]*|root=/dev/mmcblk1p3|' /boot/extlinux/extlinux.conf

配置 fstab ↓

$ cat <<EOF > /etc/fstab
/dev/mmcblk1p2 /boot/efi vfat umask=0077 0 1
EOF

其他重要的软件包↓

$ apt-get install locales
$ apt-get install wpasupplicant neofetch

清理↓

$ apt-get clean
$ rm .bash_hostory

退出 chroot ↓

$ sync
$ exit

拷贝 rootfs 到 SD 卡

$ sudo mkdir -p /mnt/sdcard
$ sudo mount /dev/mmcblk1p3 /mnt/sdcard
$ sudo cp -a /srv/chroot/riscv-chroot/* /mnt/sdcard/
$ sync
$ umount /mnt/sdcard

拔除 SD 卡之前一定要 sync

完成这一步之后这张 SD 卡应该就能被 VisionFive2 正常启动了。

打包备用

$ cd /srv/chroot/riscv-chroot
$ tar --numeric-owner -pzcvf ../riscv-chroot.tar.gz *

连接到 VisionFive2 的串口

其实用 HDMI 连显示器也一样啦,这不是手头没有。

另外一提有 RGPIO_0 和 RGPIO_1 的拨码开关,默认都拨在上面,没有必要动它。

这几个脚位和树莓派是一样的:

引脚号描述
6GND
8GPIO14 (UART TX)
10GPIO13 (UART RX)

我使用了串口转 USB ,用 minicom 打开串口↓

$ minicom -D /dev/ttyUSB0

默认配置即可,不出意外上电立即就有日志打印。

本地化

$ dpkg-reconfigure tzdata
$ dpkg-reconfigure locales

后面步骤就没必要说了捏。

youmu@youmu-vf2:~$ neofetch
       _,met$$$$$gg.
    ,g$$$$$$$$$$$$$$$P.       ---------------
  ,g$$P"     """Y$$.".        OS: Debian GNU/Linux bookworm/sid riscv64
 ,$$P'              `$$$.     Host: StarFive VisionFive V2
',$$P       ,ggs.     `$$b:   Kernel: 5.15.0-starfive-g7b7b4eddd8d5
`d$$'     ,$P"'   .    $$$    Uptime: 6 mins
 $$P      d$'     ,    $$P    Packages: 390 (dpkg)
 $$:      $$.   -    ,d$$'    Shell: bash 5.2.2
 $$;      Y$b._   _,d$P'      Terminal: /dev/ttyS0
 Y$$.    `.`"Y$$$$P"'         CPU: (4) @ 1.500GHz
 `$$b      "-.__              Memory: 97MiB / 3877MiB
youmu@youmu-vf2:~$
   `Y$$.
     `$$b.
       `Y$$b.
          `"Y$b._
              `"""

by SDUST weilinfox