
如何将树莓Pi系统拷贝至硬盘中运行
延
"存在即反抗。"
前情提要:前些天想搭建一个简易NAS存一些文件、图片、音乐、电影,也正好把吃灰好久的树莓派和一块4TB HDD用起来。但因为TF卡频繁的读写会导致TF卡很快挂掉,我这张又是128GB的闪迪金卡,所以很舍不得把它用来当树莓派的系统。尽管我会关掉swap和日志写入,但我还是希望更保险一点——通过USB外置硬盘来运行整个Raspi OS,空间又大又安全 ✔️。
设备: Raspberry Pi 4 Model B (with 4GiB RAM)
系统: Raspberry Pi OS Lite (64 bit) based on Debian 13 Trixie
硬盘: 西数红盘 4TiB
PS: 尽管是个较为复杂的工作,但全命令行是可以实现的,因此实际并不需要显示器连接或远程桌面,因此为了最小化和纯净的体验,Lite系统就足以支撑起简单的samba甚至OpenMediaVault配置了,如果选择了桌面环境反而会有些臃肿。
Step 0: 前期准备
使用 CAT 5e 以上的网线连接到路由器或交换机,保证树莓派跑满千兆有线网络,不要使用WLAN进行这类存储设备的配置,会非常不稳定。
Step 1: 写入系统到TF卡并进行初始配置
将系统通过Raspberry Pi Imager写入到TF卡并启动,这是不可避免的。也许你希望直接把系统写入到硬盘并启动了事,但这在大容量存储设备上不可行。 Raspberry Pi Imager会自动将你的硬盘设置为MBR,这会导致你驱动器上大于2TiB的部分不被支持,被浪费掉。 同时强烈建议不管硬盘大小都使用更为先进的GPT,而不是老旧的MBR。
在写入TF卡时要在Imager中进行的配置:
- 账户与密码
- 时区与键盘
- ssh
- WLAN留空 (我们已经使用了有线连接,没有必要再配置无线网连接。)
待系统启动后,通过路由器的管理面板找到raspi的IP地址,并将其与树莓派有线网卡的MAC地址绑定,使其IP不再变动,这样方便后续的管理与使用。
最后更新一下系统:
sudo apt update
sudo apt upgrade还可以安装一下自己想要的软件,比如我安装了更为习惯的vim并删除了nano,samba等服务可以后期再装,否则稍后拷贝系统会需要更长时间。
Step 2: 初始化HDD并拷贝系统
⚠️这一步会清空你的磁盘,请做好备份⚠️
首先我们需要将整个磁盘转为GPT格式并分区,先检查磁盘的位置:
lsblk假设磁盘位于/dev/sda,使用parted来修改分区表并创建分区:
parted /dev/sda在parted中运行:
mklabel gpt # 将整个磁盘转化为GPT分区表
yes # 确认
mkpart primary fat32 1MiB 512MiB # 创建一个512MiB大小的EFI分区,用于存放引导文件
set 1 boot on # 使EFI分区被标记为可引导启动
mkpart primary ext4 512MiB 100% # 创建主分区,从512MiB的位置开始直到填满100%的磁盘空间
quit # 退出parted
这一步完成后在/dev/sda下会分别存在/dev/sda1和/dev/sda2两个分区,分别是EFI和主分区,我们接下来格式化这两个分区:
sudo mkfs.vfat -F32 /dev/sda1
sudo mkfs.ext4 /dev/sda2之后开始拷贝我们的系统到HDD中并确保它可以被引导启动
(就在这一步我被AI大人坑了一下午!!!)
首先分别把当前TF卡的两个分区和HDD的两个分区挂载到两个位置,我选择把当前系统挂载到/mnt/src,HDD挂载到/mnt/dst,在这之前可以再用lsblk看一下TF卡和HDD的位置,我的分别是/dev/mmcblk0和/dev/sda:
# TF 卡
sudo mount --mkdir /dev/mmcblk0p2 /mnt/src
sudo mount --mkdir /dev/mmcblk0p1 /mnt/src/boot/firmware
# HDD
sudo mount --mkdir /dev/sda2 /mnt/dst
sudo mount --mkdir /dev/sda1 /mnt/dst/boot/firmwareAI没有提到的是:
⚠️在Debian 12 Bookworm的Raspi OS之后,所有引导文件都被放在了/boot/firmware中,所以挂载时要格外注意这一点。⚠️
我们不用cp或者dd来拷贝系统,而是用rsync这个工具,并将一些没有必要的目录排除在外不拷贝:
sudo rsync -aAXHv \
--exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
/mnt/src/ /mnt/dst/Step 3: 修改新系统的fstab等
在/mnt/dst/etc/fstab(也就是新系统的/etc/fstab)文件中存放了“自动挂载”相关的信息,它告诉系统哪些分区在开机时自动挂载到何处。如果这里配置有误,系统就找不到正确的分区从而无法启动。由于我们刚才拷贝的内容来自原系统,所以这里面的信息还是指向了原来的TF卡,因此我们要把它改成HDD的分区们。
这里补充一个关于UUID的知识,UUID是一种通用唯一身份识别符,在这里用来给我们的存储设备和它们的分区标记唯一身份信息。一个磁盘或分区的UUID在创建时就已经固定,不会变动,而系统内的路径比如/dev/sda有可能会改变,因此我们在fstab中使用UUID和磁盘分区的PARTUUID来指代它们,而不是/dev/sda这样的路径。
使用blkid <设备>来查看指定设备的UUID,如:
blkid /dev/sda1
blkid /dev/sda2这样就分别拥有了我们EFI分区和主分区的PARTUUID。
AI在这里再次坑了我:
⚠️一定找后面的PARTUUID=,而不是前面的UUID=,Raspi OS在fstab中使用的是PARTUUID=xxxx-xxxx⚠️
将它们复制到剪贴板备用,接下来:
sudo vim /mnt/dst/etc/fstab将其中/boot/firmware和/前面的PARTUUID=xxxx-xxxx分别改为刚刚获取到的sda1和sda2的PARTUUID。
最后我们修改一下/mnt/dst/boot/firmware/cmdline.txt(在Raspi OS,cmdline.txt的位置也被放进了/boot/firmware)
sudo vim /mnt/dst/boot/firmware/cmdline.txt将其中root=PARTUUID=xxxx-xxxx的PARTUUID该为我们主分区sda2的PARTUUID并保存。
最后更改一下系统引导顺序,把USB设置成第一位(其实不改也可以,到时候拔掉TF卡系统找不到TF卡会自动找下一级USB启动):
sudo raspi-configAdvanced Options - Boot Order - NVMe USB Boot
保存后umount刚刚的挂载防止使用中的情况:
sudo umount -R /mnt现在可以关闭电源,拔下TF卡并重新上电了!
至此,我们的树莓派系统成功跑在了HDD上(或者你有SSD的话性能会更好),之后的Samba或者Open Media Vault以及性能优化全看你的选择~
2025-12-18_15:41 by 晴れ空☀️
后记
我最后选择了samba(公网配置OpenVPN)的方案,于是在samba的配置这里又踩了个坑。
如果你的手机是iOS,首先要在/etc/samba/smb.conf中[global]模块下面加一条
vfs objects = fruit streams_xattr
这对iOS的文件App至关重要,如果不加上它会导致iOS系统对你分享的目录只读。T_T
Last Edited: 2026-03-31_01:20 by 晴れ空☀️