Raspberry Pi 5 安装 Arch Linux
2024-02-21 22:05:08

最近买的 Pimoroni 的 Nvme SSD 板到了, 就开始往上装 Arch
因为我没有 Micro HDMI 的线和读写 SSD 的工具, 就打算和正常装系统一样用个 usb boot 进去里面装,同时也得一直 Headless

0. 准备

  • Raspberry Pi 5
  • USB
  • 网线
  • PC
  • SSD

1. 刷 USB Boot

sudo pacman -S rpi-imager 下载 rpi-imager 然后往 USB 里刷一个 Raspberry OS 然后配置好 SSH 密码

2. USB Boot 准备

  1. 把 USB 插到 Pi 5 上
  2. 把网线从 Pi 上连到 PC, 然后进设置把类型改成 share with other computer share with other computer option
  3. ip a 拿到 PC 有线的 ip 比如 10.42.0.1, 然后用 nmap -sn 10.42.0.0/24(没有 nmap 就装) 扫 Pi 的 ip (比如我这里是 10.42.0.83)
    ip a
    nmap
  4. ssh [email protected] 和前面设的密码连接
  5. sudo apt-get update && sudo apt-get upgrade 更新一下系统
    如果通过网线出不了网可能是 dhcpcd, iptable 之类的问题
  6. sudo rpi-eeprom-config -e 里改 BOOT_ORDER, 比如 BOOT_ORDER=0xf64 就是先尝试加载 USB (4) 然后 nvme (6) 然后重复 (f). 参考raspberrypi.com/documentation/computers/raspberry-pi.html#BOOT_ORDER
  7. sudo rpi-eeprom-update -a 更新一下固件

3. 配置 nvme

参考 pimoroni, 基本除了更新 pi 的固件不需要配置, 如果 lsblk 看不到 SSD 可能是要重启

4. 安装 Arch

  1. 进 USB boot 的 SSH
  2. 分盘, 我一般用 cfdisk 分(比如 sudo cfdisk /dev/nvme0n1), 最少分两个盘, 一个 >=300Mb 的 boot 和一个主盘’
  3. sudo apt install libarchive-tools 来安装 bsdtar
  4. root 运行以下脚本(建议写到一个脚本文件里然后sudo), 脚本来自 kiljan.org/2023/11/24/arch-linux-arm-on-a-raspberry-pi-5-model-b
    执行前要去找新的下载链接(见注释)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #!/bin/bash
    # SSD 的路径
    export SDDEV=/dev/nvme0n1
    export SDPARTBOOT=/dev/nvme0n1p1
    export SDPARTROOT=/dev/nvme0n1p2
    export SDMOUNT=/mnt/sd
    export DOWNLOADDIR=/tmp/pi
    export DISTURL="http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-aarch64-latest.tar.gz"

    mkdir -p $DOWNLOADDIR
    (
    cd $DOWNLOADDIR && \
    curl -JLO $DISTURL
    )

    # 已经分过盘了
    #sfdisk --quiet --wipe always $SDDEV << EOF
    #,256M,0c,
    #,,,
    #EOF

    mkfs.vfat -F 32 $SDPARTBOOT
    mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -F $SDPARTROOT

    mkdir -p $SDMOUNT
    mount $SDPARTROOT $SDMOUNT
    mkdir -p ${SDMOUNT}/boot/firmware
    mount $SDPARTBOOT ${SDMOUNT}/boot/firmware

    bsdtar -xpf ${DOWNLOADDIR}/ArchLinuxARM-rpi-aarch64-latest.tar.gz -C $SDMOUNT

    rm -rf ${SDMOUNT}/boot/*

    mkdir -p ${DOWNLOADDIR}/linux-rpi
    pushd ${DOWNLOADDIR}/linux-rpi
    # 这里需要自己去找链接, 不然可能 404
    # 去 https://archlinuxarm.org/packages/aarch64/linux-rpi 然后复制下载链接
    curl -JLO http://mirror.archlinuxarm.org/aarch64/core/linux-rpi-6.6.16-1-aarch64.pkg.tar.xz
    tar xf *
    cp -rf boot/* ${SDMOUNT}/boot/firmware
    popd

    sync
    umount -R $SDMOUNT
    这里是 /boot/firmware 而不是 /boot 参考 raspberrypi.com/documentation/computers/configuration.html#the-boot-folder.
  5. 挂载 SSD (可以写成脚本文件)
    1
    2
    3
    #!/bin/bash
    mount /dev/nvme0n1p2 /mnt/sd
    mount /dev/nvme0n1p1 /mnt/sd/boot/firmware
  6. 编辑 sudo vim /mnt/sd/etc/fstab, 改成你的盘
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # Static information about the filesystems.
    # See fstab(5) for details.

    # <file system> <dir> <type> <options> <dump> <pass>
    # <pass> is the order of loading parition
    # main partition
    /dev/nvme0n1p2 / ext4 defaults 0 1
    # boot partition
    /dev/nvme0n1p1 /boot/firmware vfat defaults 0 2
  7. 编辑 sudo vim /mnt/sd/boot/firmware/cmdline.txt
    1
    2
    3
    # root=/dev/nvme0n1p2 rootfstype=ext4 rw rootwait console=serial0,115200 console=tty1 fsck.repair=yes
    # root=UUID=0000-0000 rootfstype=ext4 rw rootwait console=serial0,115200 console=tty1 fsck.repair=yes
    root=PARTUUID=00000000-0000-0000-0000-000000000000 rootfstype=ext4 rw rootwait console=serial0,115200 console=tty1 fsck.repair=yes
    我这里用的是盘的 PARTUUID, 理论上用路径或UUID应该也可以, 通过 ls /dev/disk/by-partuuid -al, ls /dev/disk/by-uuid -allsblk 可以拿到
  8. 关机, 拔掉 USB, 重启

5. 配置 Arch

  • 滚下系统
  • [可选] 加 SSH ~/.ssh/authorized_keys
  • 同步下时间 ntp
  • 设置 locale
  • [可选] 安装 zsh omz
  • 安装 iwd 来连接无线网
    • iwctl 然后 station wlan0 connect <UID> 来连接
    • sudo systemctl enable --now iwd 开机启动系统服务
    • 编辑 sudo vim /etc/iwd/main.conf, 加入
      1
      2
      3
      4
      5
      6
      [Settings]
      AutoConnect=true
      [General]
      EnableNetworkConfiguration=true
      [Network]
      EnableIPv6=true
      来让 wifi 自动连接, 使用内置 dhcphipv6
  • [可选?] 安装 dhcph
    • sudo systemctl enable --now dhcph
    • [可选?] 在 /etc/dhcpcd.conf 禁用 ipv6
  • 新建用户, 删除 alarm
  • hostname (默认是 alarm)
  • [可选] 安装 linux-rpi-16k
    • 如果安装后一直 boot 进旧的 也就是 linux-rpi 内核, 可以试着用 /boot/kernel8.img 覆盖 /boot/firmware/kernel8.img
  • [可选] Arch 下的 sudo pacman -S rpi5-eeprom 来更新固件
  • [可选] 如果要修复 pacman 里生成 image 的
    1
    2
    ==> WARNING: errors were encountered during the build. The image may not be complete.
    error: command failed to execute correctly
    可以编辑 /etc/mkinitcpio.confHOOKS 那一行, 去掉 kms
    1
    2
    # removed kms
    HOOKS=(base udev autodetect modconf keyboard keymap consolefont block filesystems fsck)
    参考 archlinuxarm

Troubleshooting

如果遇到什么奇怪的内核问题, 比如安装了 16k page 的新内核但是一直在加载旧内核(表现为 uname -a 里和 lsmod 为空之类), 或者 pacman -Syyu 更新内核后有一些问题, 可能是因为内核的 PKGBUILD 里面装到 /boot/kernel8.img 去了(因为我看不到 Arch Linux ARM 的 PKGBUILD 文件所以不能确认). 可以试一下 sudo cp /boot/kernel8.img /boot/firmware/kernel8.img 来覆盖看看能不能修.

6. [可选] Cloudflare 公网 SSH

因为 cloudflare 提供 tunnel, 我们可以用 tunnel 来做 Pi 的公网 SSH (以及其他要公网的服务, 相当于内网穿透)
0. 进 pi 的 arch 的 SSH

  1. 接下来可以用 docker 的 cloudflared 或者手动编译 (因为 issue#1151 提到在 2024.1.0 后要自己编译 go 标准库, 不然开不了通道), 我这里选的是手动编译
  2. 通过
    1
    2
    3
    git clone https://github.com/cloudflare/go.git
    cd go/src
    ./make.bash
    编译 cloudflarego 标准库
  3. go/bin/ 加到 PATH
  4. 通过
    1
    2
    3
    git clone https://github.com/cloudflare/cloudflared.git
    cd cloudflared
    make cloudflared
    编译 cloudflared
  5. cloudflared/ 加到 PATH
  6. cloudflare 网页上创建一个 tunneltunnel然后在里面创建协议为 SSHpublic hostname
  7. 复制 cloudflared 网页上的 tunnel 配置, 比如
    1
    sudo cloudflared service install <TOKEN>
  8. sudo systemctl enable --now cloudflared
  9. 然后在 pc 上安装 sudo pacman -S cloudflared
  10. .ssh/config 里写 cloudflaredProxyCommandcloudflared access ssh --hostname %h, 参考 developers.cloudflare.com/cloudflare-one/connections/connect-networks/use-cases/ssh
- 新年快乐 :) -