准备工作:
创建一个StarFive VisionFive V1 的 RISC-V 内核尤为重要,截止本文完稿,主线内核 5.16 还没有对 StarFive VisionFive V1 的 dts 和 deconfig 提供支持,预计 5.17 能进入主线了, 所以目前我们需要使用 5.17 的发布候选版本,就是 RC 版本进行编译和构建。完整流程如下:
#Debian 或者 Ubuntu
#Debian 安装依赖:
apt install libncurses-dev libssl-dev bc flex bison gcc-riscv64-linux-gnu build-essential ccache cpio fakeroot flex git kmod libelf-dev libncurses5-dev libssl-dev lz4 qtbase5-dev rsync schedtool wget zstd pahole dwarves -y
#Ubuntu 安装依赖:
apt install libncurses-dev libssl-dev bc flex bison gcc-riscv64-linux-gnu build-essential ccache cpio fakeroot flex git kmod libelf-dev libncurses5-dev libssl-dev lz4 qtbase5-dev rsync schedtool wget zstd dwarves -y
#下载源码:
#可以从这个地址下载内核,但是不要从 releases 下载。大家最好下载最新的 commits,在这里#我提供一个下载地址:https://github.com/starfive-tech/linux
mkdir -p linux-build
#创建编译目录
cd linux-build
#进入目录
wget https://github.com/starfive-tech/linux/archive/54fad564dc7a117704e99248c3984f907e1867d5.tar.gz
#下载特定 commits 的内核源码,大家根据你当天最新 commits 下载。
tar -xpvf 54fad564dc7a117704e99248c3984f907e1867d5.tar.gz
#解压源码
mv linux-54fad564dc7a117704e99248c3984f907e1867d5 linux-5.17.0-rc5
#给解压出来的源码目录改一个简单的名字
cd linux-5.17.0-rc5
#进入该目录
cp arch/riscv/configs/starfive_jh7100_fedora_defconfig .config
#复制内核配置文件到内核源码根目录下,并取名为 .config
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig
#利用交叉编译工具链具体再配置内核
make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -jX bindeb-pkg LOCALVERSION=-starfive-xxx
#-jX 有多少线程都可以利用上,最后那里是去个你喜欢的名字
#等待编译完成。完成后会在上一层目录生成4个deb文件,类似下图:
这4个 deb 文件中,其实我们只需要3个就足够了,一个是 linux-headers ,一个是 linux-image 。我们现在知道这三个文件放在你的家目录的 linux-build 目录下。下面我们看看如何用 Arch 构建:
Archlinux 或者其他发行版,可以用类似的方法。
下面谈到一些小的技巧,关于文件系统的:
1. 假设你使用 btrfs 文件系统,在 /mnt/ 目录下可以创建一个子卷,在子卷下编译,后续还能打个快照,做做备份;
2. 假设你使用 zfs 文件系统,建议使用 zvol 块设备,格式化成 ext4 文件系统,挂载到 /mnt/xxx/ 目录下,构建和打包。原因也同样是方便备份和做克隆,抑或是快速部署。
备份的理由是因为我前前后后用过三个版本的 Debian Sid/unstable 的 gcc 交叉编译工具链构建,第一次成功,过了一周编译失败了,因为 gcc 更新后引入了一个 bug ,需要打补丁,这个时候如果我有上一个版本的备份就直接 rollback 去构建和打包,就不影响后面的操作了。所以,养成备份和克隆的习惯很重要。下面我们假设你在 Archlinux 或者其他的发行版上已经在 /mnt/xxx/ 目录下有子卷或者块设备了,直接开始~
#以下操作默认在 root 权限进行
pacman -S yay #安装我喜欢的 yay
pacman -S paru #安装你们喜欢的 paru
#以上操作二选一
yay -S debootstrap debian-archive-keyring ubuntu-keyring
#安装 debian 系一些重要工具,debootstrap 可以将各种架构的 base system 安装到指定目录,后面的 keyring 目的是提供密钥,用于验证 deb 包是否被篡改。
debootstrap unstable /mnt/xxx https://mirror.sjtu.edu.cn/debian/
#从上海交大 debian 镜像源下载最新的 debian sid base system 并且安装到 /mnt/xxx 目录
debootstrap impish /mnt/xxx https://mirror.sjtu.edu.cn/ubuntu/
#从上海交大 ubuntu 镜像源下载最新的 ubuntu 21.10 base system 并且安装到 /mnt/xxx 目录
systemd-nspawn -D /mnt/xxx/ -M kernel --bind-ro=/etc/resolv.conf
#利用 systemd-nspawn 创建 名为 kernel 的 debian/ubuntu x86_64 base system 容器
#后续的操作可以参考上面 Debian 和 Ubuntu 的操作。完成之后,你需要记住打包好的 deb 包所在的位置,你可能需要使用 root 权限去将这些 deb 复制到你方便操作的目录下等待下一步操作。
完成内核编译打包,不要高兴太早。
完成内核编译打包,不要高兴太早。
注意在内核源码目录下把 StarFive VisionFive V1 的 dtb 文件复制出来到你记得的目录。这个 dtb 所在的目录是 <内核源码>/arch/riscv/boot/dts/starfive/
下。大家一定记住。
下面继续,针对安装内核 deb 有两种操作方法,我更推荐第二种。第一种简单,但是不清真,就是后续将编译打包好的 riscv 内核复制到将来的系统中,直接安装,命令是:dpkg -i xxx.deb
;第二种方法,我更愿意叫它是 Debian/Ubuntu 安装软件的“原教旨主义”,就是通过架设我们的私有的 RISC-V deb 源,这样的好处是,可以让你身边有需求的朋友,完全按照 Debian/Ubuntu 系的传统,安装你做好的内核,并且能够维护这个内核版本,以方便他们后续更新使用。我们来谈架设 Deb 源。
如果是公司内部,可以选择在 NAS 上创建一个 Ubuntu 的虚拟机,然后将网络映射到你们公司局域网中,让所有人都能正常访问;
如果是像我这种,我选择XX云,建立一个 Ubuntu 的 VPS 作为 deb 源服务器。好的,现在假设 VPS 或者你的虚拟机已经创建好了。开始在 VPS 上操作吧。
apt install reprepro --yes
#安装 reprepro ,deb 发布器
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
hwclock --systohc
apt install ntpdate
ntpdate -s time.nist.gov
#以上操作的目的是将 VPS 或者虚拟机的时间同步到标准北京时间,防止时间不匹配,无法安装和更新软件
gpg --gen-key
#生成你的密钥,后续 deb 包都会用这个私钥签名,其他机器需要下载你的公钥,用于验证
上图就是生成的密钥,用 gpg -
-list-keys 可以显示出来。注意那一长串字符:706CE3DD… ,记下最后8位:33372332,它们有重要作用,别问我怎么知道的,哈哈哈哈~
apt install apache2 -y
#安装一个你会操作的 web 服务器,我比较习惯 apache
下面去 web 服务器目录下创建目录:
mkdir -p /var/www/html/ubuntu-impish
cd /var/www/html/ubuntu-impish
mkdir -p conf db dists pool
touch conf/distributions
#distributions 描述性文件
touch conf/options
#options 描述仓库的一些选项
#注意 ubuntu-impish 这个是名字,大家喜欢什么名字可以随便一点,根据你们的需要自由处理。
下面来配置 distributions :
Origin: ubuntu
Suite: impish
Label: ubuntu
Codename: impish
Architectures: riscv64
Components: main
Description: Apt repository for StarFive VisionFive V1
SignWith: 33372332
上面的内容我来解释一下:
下面导出我们的公钥到源目录:
上图就是创建后的大致样子。
下面就可以来发布或者撤销你创建好的内核 deb 包了:
如果一切顺利,你的私有 deb 仓库就创建好了。好好维护吧~
现在无论任何一个发行版,安装 zfs 的树外内核模块都非常方便了,下面以我自己的习惯来创建块设备。如果各位不会使用 zfs 文件系统,也没关系,利用 losetup 创建 .img 文件,作为块设备也是一样的。虽然 zfs 更加“科学”,笑死笑死~
#一下内容均在 root 权限下操作:
zfs create -V 10G root/Container/starfive-lxde
#在 root/Container/ 池下,创建一个名字叫做 starfive-lxde 块设备,大小是10G(10G 对于 Debian/Ubuntu 都够了,但是对于 Gentoo 是不够的,Gentoo 需要120G)
cfdisk -z /dev/zvol/root/Container/starfive-lxde
#对该块设备进行分区,分区的样子类似下图:
格式化上面的三个分区:
_/boot
;_/
;在 /mnt 目录下创建一个目录,我这里就叫做:Starfive,即 /mnt/Starfive
开始一些列操作来挂载块设备到目录到 /mnt/Starfive ;
mount -t ext4 /dev/zvol/root/Container/starfive-lxde-part4 /mnt/Starfive
mkdir -p /mnt/Starfive/boot
mount -t ext4 /dev/zvol/root/Container/starfive-lxde-part3 /mnt/Starfive/boot
mkdir -p /mnt/Starfive/boot/efi
mount -t vfat /dev/zvol/root/Container/starfive-lxde-part2 /mnt/Starfive/boot/efi
挂载完成后,可一运行 lsblk 查看下,结构类似下图:
利用 debootstrap 安装 RISC-V 的 Debian base system 到 /mnt/Starfive 下:
debootstrap --arch=riscv64 --keyring /usr/share/keyrings/debian-ports-archive-keyring.gpg --include=debian-ports-archive-keyring unstable /mnt/Starfive https://deb.debian.org/debian-ports/
解释一下:
debian-ports-archive-keyring.gpg
这个文件放到我上面这个目录下;de
bian-ports-archive-keyring 包是密钥包,添加一下避免后续万一缺少密钥什么麻烦根据各位的网速,完成 base system 的部署。
#以下内容均在 root 权限下完成
apt install qemu-user-static binfmt-support -y
#安装 qemu binfmt 创建模拟环境
大家参考这段 Archlinux wiki 就可以了,我就不班门弄斧了。
随后我们就可以直接用 systemd-nspawn 进入容器开始后续的操作。
#一下内容均在 root 权限下完成
systemd-nspawn -D /mnt/Starfive -M starfive --bind-ro=/etc/resolv.conf
#启动名字为 starfive ,根目录在 /mnt/Starfive 的 Debian RISC-V 容器。
apt update; apt dist-upgrade -y
#更新系统
apt install curl gnupg2 gnupg vim nano initramfs-tools -y
#安装必要的工具,编辑器,为后续生成 initramfs 镜像做准备。
curl -s http://<内核私有源的地址>/xxx/gpg-public.key | apt-key add -
#添加内核私有源的公钥到 apt-key 中,我记得 ubuntu 和 debian 这里略有不同,大家根据不同发行版再搜索下方法。
deb http://<内核私有源的地址>/xxx unstable main
#添加私有源的地址到 /etc/apt/sources.list 中
apt update; apt install <你私有源中内核的名字,切记 linux-headers linux-image 都安装>
#刷源,安装私有源内核
这个时候你的 /boot 目录下应该是这样的:
大家可以从这里下载最早创建的 Fedora 镜像中的启动必要的文件,你可能会问,为什么 Debian/Ubuntu 下不能根据自己的发行版创建?其实原因是开发板的 uboot 读取的配置文件和目前 .efi 文件所决定的,我们按部就班就可以了。
下面我们就需要将 Fedora 原始镜像中文件复制到 Debian/Ubuntu 的 /boot 目录下,做适当修改就可以了。
将 boot 文件夹(从上面下载的压缩包解压出来以后,你会看到)复制到Debian/Ubuntu boot目录下。
那么目前 Debian/Ubuntu 的 /boot 目录下就还有一个 boot 文件夹,里面有一个叫做 uEnv.txt 的文件,大家可以用常用的编辑器打开,将 Fedora 修改成 Debian 。类似下面两张图所示:
完成后我们来复制 EFI 文件夹(压缩包里可以见到),将这个 EFI 文件夹完整复制到 Debian/Ubuntu 的 /boot/efi/ 目录下,你可将 EFI 文件夹里的 fedora 删掉,当然保留也可以,作为一个备份。
将编译内核那个部分生成的 dtb 复制到你的 Debian/Ubuntu 的 /boot/ 目录下。
将压缩包中的 extlinux 目录还有 grub.cfg 也复制到 Debian/Ubuntu 的 /boot 目录下,用编辑器对 extlinux 里面的配置文件和 grub.cfg 进行修改,修改的内容包括 kernel 对应的 vmlinuz 文件名,fdt 对应的 dtb 文件,initd 对应的 initramfs 镜像,UUID值,你可以重新打开一个终端 sudo lsblk 查看根目录的 UUID,复制后、粘贴过去。最后样子大概是这样的:
最后别忘了 ls -l 看看 /boot 目录,再 tree 检查一下(没有 tree 就 apt 安装一下)。
感觉大功告成了,别忘了最后的收尾:
passwd root
#为 root 创建一个密码
sync
#同步文件系统,写入缓存
exit
#退出容器
umount /dev/zvol/root/Container/starfive-lxde-*
#卸载挂载的块设备
dd if=/dev/zvol/root/Container/starfive-lxde of=/dev/<你的sdcard> status=progress bs=1M
#将做好的块设备烧到你的 sdcard 上,这里注意确定你的块设备,别写错了