写在前面
开发环境是 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 的拨码开关,默认都拨在上面,没有必要动它。
这几个脚位和树莓派是一样的:
引脚号 | 描述 |
---|---|
6 | GND |
8 | GPIO14 (UART TX) |
10 | GPIO13 (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