上次用写了 Archlinux X86_64 运行 Archlinux RISC-V 64, 是通过 qemu 模拟运行的,还是不如硬件好玩。几个月前买了个 MQ PRO,不过一直放着吃灰了,这两天尝试给它安装配置了下系统。

简要介绍

本次目的主要是安装系统之后能进行交互。主要步骤如下:

  1. 下载镜像
  2. 镜像写入 SD 卡
  3. 配置分区
  4. 配置系统
  5. 配置网络
  6. 插入 MQ PRO 启动
  7. SSH 连接 MQ PRO

主机环境

主机 Archlinux,安装所需依赖。

# etcher 刷镜像到 SD 卡
yay -S --needed etcher-bin
# GParted 为了修改分区数据
yay -S --needed gparted
# 为了 chroot 进 SD 卡,修改配置
yay -S --needed arch-install-scripts qemu-user-static qemu-user-static-binfmt
# 重启 binfmt 服务
systemctl restart systemd-binfmt.service

下载系统镜像

登录 GitHub, 进入 https://github.com/sehraf/riscv-arch-image-builder/actions,进入最新的 并且构建成功的 workflow runs,比如我用的是 https://github.com/sehraf/riscv-arch-image-builder/actions/runs/3481472630。 在页面最下边有个 Artifacts,下载解压得到镜像。

unzip archlinux_riscv.img.tar.gz.zip
tar xvzf archlinux_riscv.img.tar.gz

得到镜像 archlinux_riscv.img

写入 SD 卡

打开 etcher,选择 Flash from file 并选择 SD 卡对应的设备。 如果 etcher 打不开,需要修改下启动命令:

 cat /usr/bin/etcher
#!/bin/bash

/opt/balenaEtcher/balena-etcher --disable-gpu-sandbox %U

修改 SD 卡分区

镜像写入 SD 卡之后,系统占用的分区很小,总共约 2G。不修改的话既不好安装软件,又造成了空间浪费。 打开 GParted,选择对应的设备。GParted 会提示修复分区,修复就行。修复完之后可以把空闲分区建立新的分区。 不过这边推荐直接将原本的 root 分区扩容。具体大小可以自行调整。因为我的 SD 卡是 8G 大小的,所以就全部 扩容给了 root 分区。

chroot 修改各种配置

chroot 步骤

# 挂载分区
sudo mount /dev/sda2 /mnt/
sudo mount /dev/sda1 /mnt/boot/
# chroot
sudo arch-chroot /mnt

首先运行 pacman -Syu 更新系统,如果不更新,后续安装软件很有可能会出问题。 我第一次更新系统的时候,猫过来扒拉了一下读卡器,文件损坏了。 第二次没有更新系统,直接安装软件,装了部分软件之后 pacman 就因为 openssl 相关依赖坏了。

安装必要的软件

pacman -S --needed base-devel vim wpa_supplicant openssh sudo python

配置网络

# /etc/systemd/network/25-wireless.network
[Match]
# Name=wlp2s0
Name=wl*
# Type=wlan

[Network]
DHCP=yes
IgnoreCarrierLoss=3s

生成无线网络密码配置

# 注意替换 SSID 为无线网的名字,password 无线网的密码
wpa_passphrase SSID password >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf

最终的配置如下

# Giving configuration update rights to wpa_cli
ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
update_config=1

# AP scanning
ap_scan=1

# ISO/IEC alpha2 country code in which the device is operating
country=CN

# network section generated by wpa_passphrase
# 注意替换 SSID 为无线网的名字,password 无线网的密码
network={
    ssid="SSID"
    #psk="password"
    psk=2f6a0beddf2f0588ee426b0c3a0e3d9a523bb07a05cb857f85d826da80fa75c4
}

开启相关的网络服务

systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service
systemctl enable [email protected]
systemctl enable sshd.service

配置无线自动重连

2022.12.01 更新 2022.12.01 再次更新,开始的脚本没有一直重试,所以并无法正常工作 2022.12.08 路由器重启,wpa_cli 不会执行 action 脚本,还是使用 systemd-timer 实现

家里路由器重启了一次,发现板子没有自动重连无线。以下为通过 wpa_cli action 自动重连的配置方法。

保存以下文件 /root/bin/reconnect_wifi.sh,然后执行 wpa_cli -B -a /root/bin/reconnect_wifi.sh 可以把命令加入开机启动

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
fi

SLEEP_SECS=10
LOG_FILE=/var/log/wpa_cli.log

case "$2" in
    CONNECTED)
        echo "WPA supplicant: connection established" >> $LOG_FILE;
        ;;
    DISCONNECTED)
        echo "WPA supplicant: connection lost" >> $LOG_FILE;
        while true; do
            sleep $SLEEP_SECS;
            echo "WPA supplicant: reconnecting..." >> $LOG_FILE;
            wpa_cli reconnect >> $LOG_FILE;
            sleep 1;
            wpa_cli status | grep 'wpa_state=COMPLETED' >> $LOG_FILE
            if [ $? -eq 0 ] ; then
                echo "WPA supplicant: connnect completed" >> $LOG_FILE;
                break
            fi
        done
        ;;
esac
# /etc/systemd/system/reconnect_wifi.service
[Unit]
Description=Check WIFI state and reconnect when DISCONNECTED

[Service]
Type=oneshot
ExecStart=/usr/bin/reconnect_wifi.sh
TimeoutStartSec=10
# /etc/systemd/system/reconnect_wifi.timer
[Unit]
Description=Check WIFI state and reconnect when DISCONNECTED

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

/usr/bin/reconnect_wifi.sh

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
fi

LOG_FILE=/var/log/wpa_cli.log
# make log file keep small
# MAXSIZE is 64K
MAXSIZE=65536
# Get file size
FILESIZE=$(stat -c%s "$LOG_FILE")
if (( FILESIZE > MAXSIZE )); then
    truncate -s 8K $LOG_FILE
fi

main() {
    wpa_cli status | grep 'wpa_state=COMPLETED'
    if [ $? -eq 0 ] ; then
        echo "WPA supplicant: connnect completed" >> $LOG_FILE;
    else
        date >> $LOG_FILE;
        echo "WPA supplicant: connection lost" >> $LOG_FILE;
        echo "WPA supplicant: reconnecting..." >> $LOG_FILE;
        wpa_cli reconnect >> $LOG_FILE;
    fi
}

main "$@"

配置用户

注意修改 root 密码

下边是添加普通用户:

# 添加 archie
useradd -m archie
# 加入权限组
gpasswd -a archie wheel
# 修改用户密码
passwd archie
# 修改 sudo 配置
# 把 wheel 行取消注释
env EIDTOR=vim visudo

sshd 的配置不再赘述,配置好之后可以 sshd -D -d 启动,然后另一个终端测试下登录。

测试没问题之后 sudo mount -R /mnt 取消挂载。然后插入 MQ PRO,插电等待约两分钟。 可以进路由器看看有没有设备有没有成功连接无线网。如果没问题,基本系统就可以用了,后续可以继续折腾了。

其他

启动之后如果有问题,可以把 SD 卡拔下来插到电脑上看日志。 chroot 方法如上所述。也可以加自己的调试脚本。下边是我自己写的调试服务。 systemctl enable mine-startup.service 配置开机启动。

如果你看到这里有任何问题可以从 https://i01.io 找到联系我的方式,欢迎交流。

# systemctl cat mine-startup.service
# /etc/systemd/system/mine-startup.service
[Unit]
Description=Run script at startup after network becomes reachable

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/bin/startup_script.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target

# cat /usr/bin/startup_script.sh
#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail
if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
fi

SCRIPT_NAME=$(basename -- "$0")
LOG_FILE="/var/log/startup.log"

z=0
for i in {1..5}; do
    sleep 1m
    date >> $LOG_FILE
    ip a >> $LOG_FILE
    curl -ivvv https://i01.io/ip 2>1 >> $LOG_FILE
    ((z++))
    wall $SCRIPT_NAME: finished minute ${z}
done
wall $SCRIPT_NAME: COMPLETELY FINISHED

弯路

联想笔记本坏了,因为疫情管控原因,一直没有出门修理。所以用的旧 Macbook。因为是 MacOS,所以导致了一些不必要的问题。 比如没办法用 GParted,用 etcher 刷了 SD 卡之后没办法查看修改分区和配置文件等等。 因为疫情管控原因,快递都停了,也没办法买 miniHDMI 线。所以刷了系统之后也不知道系统有没有成功启动。 在 Mac 上安装了 VirtualBox,并安装了 Arch Linux, 试图修改 SD 的分区和配置。各种问题没办法读取 USB 配置。 可能是 VirtualBox 7 的问题,网上搜的有人说 VirtualBox 6 没有问题,也没有尝试。 后来跟人抱怨的时候想起来还有台式机。。。

参考链接

  1. MQ PRO 产品页面
  2. https://github.com/sehraf/riscv-arch-image-builder
  3. Arch Linux RISC-V
  4. QEMU archlinux wiki