PiKVM 是基于树莓派实现的IP KVM工具,它能够把开发板模拟成键盘、鼠标、移动硬盘等,通过USB接入到目标主机,并且读取主机的视频输出,让运维人员可以通过远程Web界面对目标服务器进行管理,让家用电脑也可以实现类似BMC的带外管理功能。
但PiKVM这个工具在树莓派上的实现是直接做了一个基于Arch Linux的镜像,用户拿到可以直接烧到树莓派里用。我为了支持国产因为贫穷,决定用立创的泰山派来装这个东西。
注意本文不是保姆级教程,也不提供一个完善的解决方案,只是记录了我在泰山派上装PiKVM的过程,仅供参考。
硬件准备
主要硬件是一块泰山派开发板,约200块钱,买2G+16G存储的版本即可。
然后是HDMI采集卡,用于捕获服务器的视频流,这个正好以前玩直播的时候搞过一个正在吃灰,拿出来废物利用一下。现在HDMI采集卡也不贵,已经卷到几十块钱就能买到了。
最后是一根自己DIY的Y型USB线(USBC Y-Splitter cable),用于给开发板供电(带外管理当然得有自己的独立电源)以及把自己模拟成外设连接到主机用。PiKVM官方给的图在下面,线的颜色和实际的颜色应该是一致的。
要点:
- 接到服务器端的Type-A端VCC要断掉,不要接到电源,据说会烧
- 接USB电源的一端只保留地线和供电线,仅作供电用
- 三个接头的GND地线要相连,保证地的电位一致
- D- 和 D+ 是正常用来传输USB数据的,用于在我们这里就是用于USB外设模拟
总之找两根吃灰的四芯USB线剪断再焊接一下就成,注意做好绝缘。
至于PiKVM还可以通过GPIO接继电器连电脑开关的这种操作我就懒得搞了,我选择用小米插座远程断电,用Wake on LAN远程唤醒。
整体的接线方式可以参考PiKVM的文档。
在泰山派这边,由于板子比较小,只有两个USB接口,所以接线方式是Type-C口用DIY的线接主机模拟USB外设和接外置电源,Type-A口接HDMI采集卡采集视频输出。
系统准备
开发板自带的是个Android系统,我们装PiKVM其实是需要22.04装起来比较顺畅,因为PiKVM需要Python 3.10,然而泰山派官方最高只提供了20.04的固件,我又太菜懒没整明白如何直接构建一个22.04的固件出来,所以采取曲线救国的方式进行:先刷20.04,然后自己升级到22.04。
下载ubuntu镜像烧录 https://lceda001.feishu.cn/wiki/IJtRwVu5kiylHykl3RJcQ8ANncY
启动后先配好WiFi,村通网,记得先给开发板插好wifi天线。
默认有一堆包的版本都被hold了,需要全部unhold:
sudo apt-mark unhold $(apt-mark showhold)
把讨厌的自动更新关了,全改0:
sudo vim /etc/apt/apt.conf.d/20auto-upgrades
装一个ssh server用ssh连进来调试起来就比较方便了:
sudo apt update
sudo apt install -y openssh-server
然后我们会发现,这玩意的磁盘也很奇葩,/oem和/userdata的分区分走了一大部分空间,需要把他们的分区删掉,容量合并到/路径的分区中,这样才够我们完成22.04的升级。
sudo umount /oem
sudo umount /userdata
# 删掉上面两个挂载点
sudo vim /etc/fstab
# 删掉最后两个,然后resize root这个分区把剩余空间都加进来
sudo cfdisk /dev/mmcblk0
# 最后扩容文件系统
sudo resize2fs /dev/mmcblk0p6
之后就是正常的发行版升级流程了,升级到ubuntu22.04
sudo apt upgrade
sudo apt install ubuntu-release-upgrader-core
sudo do-release-upgrade
KVMD安装
我们需要通过jacobbar/fruity-pikvm这个仓库来安装kvmd,它是打了一个deb包来进行kvmd的安装,从而支持其他开发板。我这里只借助它来部署下systemd service启动脚本之类的。
sudo apt install -y git
git clone https://github.com/jacobbar/fruity-pikvm.git
cd fruity-pikvm
sudo su
./install.sh
kvmd日志可能会报kvmd module not found
我们也不惯他毛病,不用它deb包里给的kvmd了,直接装个新的,这里用了我参考fruity-pikvm里的patch脚本的fork,可以支持大容量存储
sudo apt install -y python3-pip
git clone https://github.com/Windfarer/kvmd.git --branch tspi
cd kvmd
sudo pip install .
# 顺便装下它的依赖
sudo pip install async_lru gpiod
# 因为我们更新了版本,所以还要更新kvmd的web页面静态资源
sudo mv /usr/share/kvmd/web/ /usr/share/kvmd/web-bak
sudo cp -r web /usr/share/kvmd/
然后重启后会看到kvmd-otg报错:
OSError: [Errno 12] Cannot allocate memory: '/sys/kernel/config/usb_gadget/kvmd'
因为usb_gadget下只能存在一个目录,观察下这个目录下已经有一个rockchip的目录了,当前默认在usb这边开了个adb,需要关掉它,给kvmd让位:
mv /etc/init.d/.usb_config /etc/init.d/.usb_config.bak
修改设备树,编译并烧录Kernel
如果不改设备树,可能会在kvmd-otg的日志中看到这样的报错:
FileNotFoundError: [Errno 2] No such file or directory: '/sys/kernel/config/usb_gadget/kvmd/functions/hid.usb0'
为了能正常模拟成键鼠,我们不可避免地要改内核参数编译kernel了,所以还是要准备下编译环境。
当然要装啥编译工具请自己参考【立创·泰山派RK3566】开发板下面的各种文档进行安装,毕竟我们Arch Linux用户家里啥没有啊。
在 第05章.【立创·泰山派RK3566】系统SDK 下载 tspi_linux_sdk_repo_20240131.tar.gz 并解压。
解压完你会发现毛都没有,原来都解压到.repo
目录下了,还需要额外的命令把他的仓库都同步回来。
.repo/repo/repo sync -l -j16
然后不一会就出现了一大堆目录。
修改设备树,重新编译内核(第一次编译有一些电压的东西要选,参考【Linux】系统SDK编译)
在sdk的kernel/arch/arm64/boot/dts/rockchip/tspi-rk3566-core-v10.dtsi
路径里找到这个usbdrd_dwc3
,将它的dr_mode
改为peripheral
,即外围设备。
&usbdrd_dwc3 {
dr_mode = "peripheral";
extcon = <&usb2phy0>;
status = "okay";
};
配置defconfig,在kernel/arch/arm64/configs/rockchip_linux_defconfig
这个文件中追加如下参数
CONFIG_USB_CONFIGFS_F_HID=y
CONFIG_TUN=y
# 下面这个里面应该有,确认一下是否为y
CONFIG_USB_CONFIGFS_MASS_STORAGE=y
其中第一行是用来启用键鼠模拟的,第二行是为了开启tun设备,这个是为了tailscale的虚拟局域网准备的,这里一次都改完,避免重复折腾。
编译内核
./build.sh kernel
编译完的产物应该在rockdev/boot.img
然后把它刷进去,需要先把开发板切换到loader升级模式,参考【下载】镜像烧入
注意使用di命令只刷boot
sudo ./upgrade_tool di -b boot.img
刷完就可以把各种线连上试试了,访问 https://开发板ip地址
应该就能看到PiKVM的管理页面,默认帐号密码都是admin
TailScale
这年头谁还有公网IP啊,全靠tailscale苟着,虚拟局域网凑合用用也可以了。
由于kernel版本有点低,想用tailscale需要切换一下iptables
update-alternatives --set iptables /usr/sbin/iptables-legacy
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
update-alternatives --set arptables /usr/sbin/arptables-legacy
update-alternatives --set ebtables /usr/sbin/ebtables-legacy
然后安装tailscale
sudo apt install -y curl
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
大容量存储
这个功能用于将开发板模拟成USB存储设备,用于服务器的开机引导装系统等操作
插一张存储卡之后进行下面的操作
# 确认存储卡的分区
sudo fdisk -l
# 格成ext4
sudo mkfs -t ext4 /dev/mmcblk1p1
# 修改挂载
sudo vim /etc/fstab
## 加入下面的内容
/dev/mmcblk1p1 /var/lib/kvmd/msd ext4 nodev,nofail,nosuid,noexec,ro,errors=remount-ro,data=journal,X-kvmd.otgmsd-root=/var/lib/kvmd/msd,X-kvmd.otgmsd-user=kvmd 0 0
# 确认fstab是否能用,有报错千万别重启,修起来很麻烦
sudo mount -a
sudo vim /etc/kvmd/override.yaml
# 加入下面内容并保存
kvmd:
msd:
type: otg
重启开发板,再登录PiKVM的页面,应该就能看到Drive功能了。
网络唤醒(Wake on LAN)
需要先在目标服务器的BIOS进行相应设置,在目标服务器的系统内看一下网卡的mac地址,然后给它开启wake on lan功能。
创建/etc/systemd/system/wol.service
文件,加入下面内容,需要把其中的网卡名称改成服务器上的实际设备名称
[Unit]
Description=Enable Wake On Lan
[Service]
Type=oneshot
ExecStart = /usr/sbin/ethtool --change enp3s0 wol g
[Install]
WantedBy=basic.target
然后设置自动启动
sudo systemctl daemon-reload
sudo systemctl enable wol.service
在系统中通过如下命令可以看到是否开启了wol,如果Wake-on: g
则是已经开启:
sudo ethtool <网卡名称>
在开发板这边,修改/etc/kvmd/override.yaml
增加wol配置项,里面配上目标服务器的mac地址:
kvmd:
# other configurations
wol:
mac: ff:ff:ff:ff:ff:ff
配完重启开发板,之后在Web界面右上角system菜单中看到WoL。
错误排查
上面的过程中可以通过查看kvmd的服务状态和日志检查具体的错误信息
sudo systemctl status kvmd
# 这个kvmd-otg是启动时一次性运行的,所以它如果无报错停止了是正常的
sudo systemctl status kvmd-otg
sudo journalctl -u kvmd
sudo journalctl -u kvmd-otg