约 1600 字

折腾一下赶在 12G 内存涨价前入手的 orangepi 4pro

安装系统到固态硬盘 nvme

我尝试了官方的安装方法,并没有成功,总是启动后黑屏,由于没有串口转usb线,也不知道是什么问题。于是尝试了曲线救国方案——通过TF卡去启动固态内的系统。

  1. TF卡中安装系统

  2. 修改TF卡引导文件:/boot/boot.cmd,参考:https://github.com/YYH2913/orangepi_4pro_related

      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
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    
    # DO NOT EDIT THIS FILE
    #
    # Please edit /boot/orangepiEnv.txt to set supported parameters
    #
    
    setenv load_addr "0x43100000"
    setenv overlay_error "false"
    # default values
    setenv verbosity "1"
    setenv console "both"
    setenv bootlogo "false"
    setenv rootfstype "ext4"
    setenv docker_optimizations "on"
    setenv earlycon "on"
    
    echo "Boot script loaded from ${devtype} ${devnum}"
    
    # 读取 orangepiEnv.txt(保持原厂逻辑)
    if test -e ${devtype} ${devnum} ${prefix}orangepiEnv.txt; then
            load ${devtype} ${devnum} ${load_addr} ${prefix}orangepiEnv.txt || \
            ext4load ${devtype} ${devnum} ${load_addr} ${prefix}orangepiEnv.txt
            env import -t ${load_addr} ${filesize}
    fi
    
    # —— 兼容增强开始 ———————————————————————————————————————————————
    
    # 若 prefix 未设,给默认值(部分固件会漏)
    if test -z "${prefix}"; then setenv prefix "/boot/"; fi
    
    # 给 NVMe/PCIe 一点就绪时间(温启动更稳)
    sleep 0.5
    
    # 规范出 “带分区号” 的设备标识:devpart
    # 先试用现有 ${devnum}(如果本就含 :分区会成功),否则自动回退到 ":1"
    setenv devpart ${devnum}
    if part uuid ${devtype} ${devpart} __tmpuuid; then
            true
    else
            setenv devpart "${devnum}:1"
    fi
    echo "Using ${devtype} ${devpart} (prefix=${prefix})"
    
    # 如果从 NVMe 启动,则用 PARTUUID 覆盖/填充 rootdev(保留厂商后续拼接)
    if test "${devtype}" = "nvme"; then
            if part uuid ${devtype} ${devpart} rootuuid; then
                    setenv rootdev "PARTUUID=${rootuuid}"
                    echo "rootdev=${rootdev}"
            fi
    fi
    
    # —— 兼容增强结束 ———————————————————————————————————————————————
    
    # 控制台参数(保持原厂逻辑)
    if test "${logo}" = "disabled"; then setenv logo "logo.nologo"; fi
    if test "${console}" = "display" || test "${console}" = "both"; then setenv consoleargs "console=tty1"; fi
    if test "${console}" = "serial"  || test "${console}" = "both"; then setenv consoleargs "console=ttyS0,115200 ${consoleargs}"; fi
    if test "${earlycon}" = "on"; then setenv consoleargs "earlyprintk=sunxi-uart,0x02500000 initcall_debug=0 ${consoleargs}"; fi
    if test "${bootlogo}" = "true"; then
            setenv consoleargs "splash plymouth.ignore-serial-consoles ${consoleargs}";
    else
            setenv consoleargs "splash=verbose ${consoleargs}"
    fi
    
    # 生成 bootargs(保留原项 + 稳定性参数)
    setenv bootargs "root=${rootdev} rootwait rootdelay=5 rootfstype=${rootfstype} ${consoleargs} consoleblank=0 loglevel=${verbosity} clk_ignore_unused swiotlb=65536 usb-storage.quirks=${usbstoragequirks} ${extraargs} ${extraboardargs} nvme_core.default_ps_max_latency_us=0"
    if test "${docker_optimizations}" = "on"; then
            setenv bootargs "${bootargs} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1"
    fi
    
    # 尝试加载 uInitrd(存在则用,不存在则降级)
    if load ${devtype} ${devpart} ${ramdisk_addr_r} ${prefix}uInitrd || \
    ext4load ${devtype} ${devpart} ${ramdisk_addr_r} ${prefix}uInitrd; then
            setenv haveinitrd "1"
    else
            setenv haveinitrd "0"
    fi
    
    # 加载内核(增加 ext4load 兜底)
    load    ${devtype} ${devpart} ${kernel_addr_r} ${prefix}uImage || \
    ext4load ${devtype} ${devpart} ${kernel_addr_r} ${prefix}uImage
    
    # 加载 DTB(增加 ext4load 兜底;保持厂商路径规则)
    load    ${devtype} ${devpart} ${fdt_addr_r} ${prefix}dtb/${fdtfile} || \
    ext4load ${devtype} ${devpart} ${fdt_addr_r} ${prefix}dtb/${fdtfile}
    
    # 预留 FDT 空间并把 bootargs 写入 /chosen(防止 FDT_ERR_NOSPACE)
    fdt addr ${fdt_addr_r}
    fdt resize 65536
    fdt mkdir /chosen
    fdt set /chosen bootargs "${bootargs}"
    
    # 叠加 overlays(保持原厂逻辑)
    for overlay_file in ${overlays}; do
            if load ${devtype} ${devpart} ${load_addr} ${prefix}dtb/allwinner/overlay/${overlay_prefix}-${overlay_file}.dtbo || \
            ext4load ${devtype} ${devpart} ${load_addr} ${prefix}dtb/allwinner/overlay/${overlay_prefix}-${overlay_file}.dtbo; then
                    echo "Applying kernel provided DT overlay ${overlay_prefix}-${overlay_file}.dtbo"
                    fdt apply ${load_addr} || setenv overlay_error "true"
            fi
    done
    for overlay_file in ${user_overlays}; do
            if load ${devtype} ${devpart} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo || \
            ext4load ${devtype} ${devpart} ${load_addr} ${prefix}overlay-user/${overlay_file}.dtbo; then
                    echo "Applying user provided DT overlay ${overlay_file}.dtbo"
                    fdt apply ${load_addr} || setenv overlay_error "true"
            fi
    done
    
    # 依据是否有 initrd 启动(兼容厂商原语义)
    if test "${haveinitrd}" = "1"; then
            echo "Booting with uInitrd"
            bootm ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
    else
            echo "uInitrd not found; booting without initrd"
            bootm ${kernel_addr_r} - ${fdt_addr_r}
    fi
    
    # Recompile with:
    # mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
    
  3. 将固态硬盘的 PARTUUID 填入上面的 boot.cmd 中

    1
    2
    3
    
    sudo blkid
    #复制固态硬盘(nvme0n1)的PARTUUID
    sudo nano /boot/boot.cmd
    
    1
    2
    3
    4
    5
    
    # 修改原本的这行
    # setenv bootargs "root=${rootdev} rootwait ... ${extraargs}"
    
    # 改为实际的 PARTUUID,注意还要加 rw
    setenv bootargs "root=PARTUUID=你的-NVMe-PARTUUID-字符 rw rootwait rootdelay=10 console=ttyS0,115200 console=tty1 nvme_core.default_ps_max_latency_us=0"
    
  4. 编译 boot.cmd:

    1
    
    sudo mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
    
  5. (这步及之后都是官方手册的做法)如果是 Debian Bullseye(据官方说这是唯一有gpu驱动的系统),运行如下命令:

    1
    2
    3
    
    sudo service lightdm stop
    # 然后按 Ctrl+Alt+F3 进入命令行
    sudo rmmod pvsrvkm
    
  6. 将固态硬盘插入 Orangepi 4pro

  7. 给 NVME 创建分区:

    1
    
    sudo parted --script /dev/nvme0n1 mklabel gpt mkpart primary ext4 65536s 100%
    
  8. 运行 sudo nand-sata-install,选择 4-boot from SPI,然后后面无脑回车就行。

后面不要将 TF 卡拔出来,重启后就能从 NVME 的系统启动。我们验证一下:运行 sudo lsblk,如果 / 挂载到了 nvme0n1p1,就说明启动的是 NVME 的系统。

更新源

默认是华为云,但是有一个 backports 源失效了,将其注释,并替换为官方存档源:

1
2
# /etc/opt/source.list
deb http://archive.debian.org/debian/ bullseye-backports main contrib non-free

然后更新源

1
sudo apt update

然后注意不要执行 sudo apt upgrade,执行后就启动不了了,我也不知道为啥。

Comments