準備工作:
- 耐心
- 一杯咖啡
- 一塊板子和一條串口調試線,至少16G的任何品牌的 sdcard
- 能熟練操作的一個 Linux 發行版(推薦 Archlinux 或者 Ubuntu)
- 大致了解如何利用 qemu 和 binfmt 創建 RISC-V 模擬運行環境(推薦閱讀)
- 大致了解如何創建塊設備(推薦參考的一篇文章:losetup創建塊設備,或者利用 zfs 創建塊設備,我更習慣后者,后面的內容會以 zfs 文件系統為例,但實際操作中,僅僅是創建塊設備不同,掛載無異)
- 大致了解如何創建一個 RISC-V 交叉編譯環境(推薦閱讀)
- 大致了解如何使用簡單的 systemd-nspawn 容器(推薦閱讀)或者 chroot(推薦閱讀)
- 大致了解 StarFive VisionFive V1 的啟動流程(推薦閱讀,不想閱讀的朋友等等我的視頻)
- 覺得以上準備好煩,就是想白嫖的朋友只有等我的視頻連載吧
第一部分:編譯、打包內核,創建 deb 源:
創建一個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
上面的內容我來解釋一下:
- Origin 如果你是 Debian,就寫 Debian,如果是 Ubuntu ,就寫 Ubuntu
- Suite 寫成你的發行版的代號
- Label 類似 Origin
- Codename 就是發行版代號
- Components 這個是組件,因為我們只是滿足小范圍的朋友使用,main 就夠了,如果是嚴格的維護,最好詳細分類
- 描述部分大家自由發揮
- SignWith 這里是簽名,還記得你的那8位密鑰嗎?
下面導出我們的公鑰到源目錄:
gpg --export --armor 33372332 > /var/www/html/ubuntu-impish/gpg-public.key
#再次強調那個8位密鑰
上圖就是創建后的大致樣子。
下面就可以來發布或者撤銷你創建好的內核 deb 包了:
reprepro -b /var/www/html/ubuntu-impish -C main includedeb impish /<你之前編譯并打包好的 deb目錄>/*.deb
#這是發布你的 deb 包,這時候會彈出一個 TUI ,你在里面輸入密碼(gpg 創建密鑰對時輸入的密碼)
reprepro -b /var/www/html/ubuntu-impish -C main remove impish
#從倉庫移除或者撤銷 deb 包
如果一切順利,你的私有 deb 倉庫就創建好了。好好維護吧~
第一部分小節:
- 內核編譯打包推薦交叉編譯,速度快;
- 記得 dtb 要復制出來,方便最后處理;
- 構建出來的 deb 包強烈推薦使用傳統的架設源服務器管理
第二部分:創建塊設備,分區,創建 RISC-V 的 Debian base system
現在無論任何一個發行版,安裝 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
#對該塊設備進行分區,分區的樣子類似下圖:
格式化上面的三個分區:
- 注意第一個分區是空分區;
- 第二個分區,格式化成 vfat ,不用取 label 名字;
-
第三個分區,格式化成 ext4,label 取名字叫做:
_/boot
; -
第四個分區,格式化成 ext4,label 取名字叫做:
_/
;
在 /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/
解釋一下:
- –arch=riscv64 這里強調了架構,是 riscv64 的;
-
–keyring 這里需要大家去單獨下載一個 deb 包,我已經不記得 debian 和 ubuntu 的源里是否包含,不包含可以下載這個包,下載后解壓 deb 提取
debian-ports-archive-keyring.gpg
這個文件放到我上面這個目錄下; -
–include 在 base system 保重,添加特定的包,
de
bian-ports-archive-keyring 包是密鑰包,添加一下避免后續萬一缺少密鑰什么麻煩 - 目前 RISC-V 架構并不在穩定版本 Debian 的支持中,比方說現在的 Debian 穩定版是 Debian 11,它是不支持 RISC-V 的,所以我們只能用不穩定版本 Sid/Unstable,如果你在某些網站看到 RISC-V 是穩定分支,那是宣傳,并不是真實情況。
- /mnt/Starfive 是目錄,現在已經掛載好塊設備了
- https://deb.debian.org/debian-ports/ 是下載 deb 包的地址(這是官方源,建議不要用鏡像,偶爾因為同步問題,會出現文件校驗不匹配)
根據各位的網速,完成 base system 的部署。
第二部分小節:
- 用你們習慣的方法創建塊設備;
- 習慣去備份,避免重復勞動,節約時間;
- 掌握 debootstrap 的命令,可以看看 help 的輸出,多嘗試總不會有錯。
第三部分:完善基礎系統,準備 /boot 目錄必要文件,為開發板最后啟動做準備
Debian/Ubuntu 創建 RISC-V 模擬環境
#以下內容均在 root 權限下完成
apt install qemu-user-static binfmt-support -y
#安裝 qemu binfmt 創建模擬環境
Archlinux 或者其它發行版創建 RISC-V 模擬環境
大家參考這段 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 上,這里注意確定你的塊設備,別寫錯了
第三部分小結:
- 根據你做的鏡像發行版不同,debian 和 ubuntu 導入你內核私有源的公鑰會略有不同,根據遇到的情況查閱 Google
- 按部就班,多檢查細節
評論
查看更多