树莓派 通过USB从U盘或移动硬盘启动

起因是多年来Raspberry 2B 已经用坏我3张TF卡了,不能再继续这样了。

制作系统镜像

准备一张容量不少于4GTF卡,准备好系统镜像并写入TF卡,这里我用的电脑系统是 Debian:

# 解压xz格式的系统镜像 我下的是不带UI的lite版本
unxz xxx.img.xz
# 写入到TF卡, /dev/sdc 为TF卡的设备路径
sudo dd if=xxx.img of=/dev/sdc bs=1M
# 默认开启SSH,无须再接显示器和键盘进行配置
# dd 写入镜像到TF卡后,会创建两个分区分别为boot和rootfs,挂载第一个boot分区
mkdir tmp && sudo mount /dev/sdc1 tmp
# 在其中创建ssh文件后,树梅派在启动后发现存在该文件会自动开启SSH服务
sudo touch tmp/ssh && sudo umount /dev/sdc1

按照如上类似的步骤同样写入U盘或移动硬盘.

需要注意,为保证供电正常, 移动硬盘可以选择独立供电的硬盘盒子或者独立供电的SATA硬盘转接线。若直接用树莓派的USB给移动硬盘供电是不够妥的,因为USB 2的标准供电只能保证500mA,硬盘启动时的瞬时功率要远高于启动后稳态时的平均功率.


USB启动与扩容

参考官方的教程 对我的2代并不生效,于是换个思路,将boot分区内cmdline.txt文件的root的分区PARTUUID改为USB存储设备的rootfs分区的PARTUUID,这样即可通过TF卡引导USB存储设备启动。
先制作一个与TF卡上相同分区格式的(可以烧录相同系统,也可以其他系统)的USB存储设备,接入树莓派后启动,使用blkid命令查看各个分区的UUIDPARTUUID,然后将USB存储设备的root分区PARTUUID填入TF卡上boot分区的cmdline.txt内,自此TF只有boot阶段的作用,因为kernel的加载和运行已经是在指定的USB存储设备上。

正常启动后使用raspi-config命令选择Advanced Options中的Expand Filesystem即可完成扩容,这里扩容是将剩余的空间利用起来。如果用的是TF卡,它没有坏块管理功能,一年半载旧会产生坏块,若想要保证TF卡能使用长久,只能减少TF的擦写次数。

所以现在我要让TF卡只做boot阶段的引导工作,我在上一阶段制作了一个烧写了同样系统的USB存储设备–移动硬盘。

这是日立2014年的2.5寸机械硬盘, 容量320G, 多年的使用即便小心翼翼也已经有了不少物理坏道,按理应该丢弃了,但感觉扔了可惜,于是花二十多块加了个USB转SATA线当移动硬盘接树莓派上重复利用。

不过由于存在坏道不能直接使用树莓派自带的扩容方式,为了绕开坏道所在的扇区就在分区上花了点时间:

我想将烧录完系统的移动硬盘的rootfs分区扩容到指定大小,并再挂载硬盘其他盘道完善的分区。

假设此硬盘挂载设备路径为/dev/sda,则执行fdisk指令进入它的交互模式: sudo fdisk /dev/sda

# 进入fdisk操作模式,输入p打印该设备的分区信息
p

#> Device     Boot     Start       End  Sectors  Size Id Type
#> /dev/sda1            8192    532479   524288  256M  c W95 FAT32 (LBA)
#> /dev/sda2          532480   3661823  3129344  1.5G 83 Linux

# 这里sda1是boot,sda2是rootfs
# 因为要对rootfs扩容,所以首先删除该分区,在再该分区的原起始块上创建新分区,创建后只要不格式化,原有数据是依旧存在的, 不用担心 ^_^
d
# 分区号为2
2
# 新建
n
# 输入原起始块,即上面的Start列
532480
# 输入该分区的期望大小,我的在百分之一后即3GB之后就存在坏道,因此保险起见可以固定在2.6G
+2.6G
# 可能会提示已存在ext4分区的签名,不用移除,保留原来的; 然后输入 w 保存更改并退出. 
# 我这机械盘中间部分和尾部还存在超过100G正常能用的盘道,就再创建了两个分区,这里不单独列出了

然后应用新的rootfs分区大小:

sudo partprobe
sudo e2fsck -f /dev/sda2
sudo resize2fs /dev/sda2

此时用fdisk -l查看,扩容的分区与新建的分区已生效了。 接入树莓派,修改TF卡上bootcmdline.txt文件的root的分区PARTUUID为移动硬盘rootfs分区的PARTUUID,重启即可。