Skip to content

1. Migrate SD card rootfs to SSD for RPI3

Ricky Zhang edited this page Aug 24, 2019 · 6 revisions

Motivation

I dd an official FreeBSD 12.0 image for Raspberry PI 3 to an SD card. Everything works except bluetooth and wifi.

To mitigate wearing on SD card, I migrated the whole rootfs from the SD card to an external SSD and kept the boot folder in SD card.

Method 1: SD card kernel boot + SSD ufs rootfs

Prepare SSD

gpart show
gpart add -t freebsd-ufs -l ssdrootfs -a 1M -s 420G da0
newfs -U /dev/da0p1

rsync from SD card to SSD

mkdir -p /mnt/USB
mount /dev/da0p1 /mnt/USB
rsync -aAXvr --progress --delete /* /mnt/USB \
    --exclude='/boot/*' \
    --exclude='/dev/*' \
    --exclude='/proc/*' \
    --exclude='/net/*' \
    --exclude='/tmp/*' \
    --exclude='/mnt/*' \
    --exclude='/media/*'

Modify /boot/loader.conf in SD card

/boot/loader.conf:
vfs.root.mountfrom="ufs:/dev/gpt/ssdrootfs"
kern.cam.boot_delay="20000"

Once boot from SSD, fix boot folder

NOTE: / refers to SSD rootfs

cd /mnt/USB
mkdir bootdir
ln -s bootdir/boot boot

Modify /etc/fstab in SSD

Original

root@router:~ # cat /mnt/USB/etc/fstab 
# Custom /etc/fstab for FreeBSD embedded images
/dev/ufs/rootfs   /       ufs     rw      1       1
/dev/msdosfs/MSDOSBOOT /boot/msdos msdosfs rw,noatime 0 0
tmpfs /tmp tmpfs rw,mode=1777,size=50m 0 0

New

root@router:~ # cat /mnt/USB/etc/fstab
# Custom /etc/fstab for FreeBSD embedded images
/dev/ufs/rootfs   /bootdir       ufs     rw      1       1
/dev/label/gpt/ssdrootfs   /       ufs     rw      1       1
/dev/msdosfs/MSDOSBOOT /boot/msdos msdosfs rw,noatime 0 0
tmpfs /tmp tmpfs rw,mode=1777,size=50m 0 0

Method 2: SD card kernel boot + SSD zfs rootfs

NOTE: It doesn't boot from rootfs. Don't try it!!!

Prepare SSD

root@router:~ # gpart show da0
=>       34  976773101  da0  GPT  (466G)
         34       2014       - free -  (1.0M)
       2048  880803840    1  freebsd-ufs  (420G)
  880805888   95967247       - free -  (46G)

# delete the existing ufs partition

root@router:~ # gpart delete -i 1 da0
da0p1 deleted

root@router:~ # gpart show da0
=>       34  976773101  da0  GPT  (466G)
         34  976773101       - free -  (466G)

# Partition with 420G is created and label /dev/gpt/ssd is created.
root@router:~ # gpart add -t freebsd-zfs -a 1M -l ssdzfs -s 420G da0
da0p1 added

root@router:~ # gpart show da0
=>       34  976773101  da0  GPT  (466G)
         34       2014       - free -  (1.0M)
       2048  880803840    1  freebsd-zfs  (420G)
  880805888   95967247       - free -  (46G)

Load zfs kernel

root@router:~ # kldload /boot/kernel/zfs.ko
root@router:~ # kldload /boot/kernel/opensolaris.ko
kldload: can't load /boot/kernel/opensolaris.ko: module already loaded or in kernel

Create zfs pool

zpool create tank /dev/gpt/ssd

Create data set

zfs create -o compression=off tank/rootfs
zfs create -o compression=off tank/home

# check zfs data set mount
root@router:~ # mount
/dev/ufs/rootfs on / (ufs, local, soft-updates)
devfs on /dev (devfs, local, multilabel)
/dev/msdosfs/MSDOSBOOT on /boot/msdos (msdosfs, local, noatime)
tmpfs on /tmp (tmpfs, local)
tank on /tank (zfs, local, nfsv4acls)
tank/home on /tank/home (zfs, local, nfsv4acls)
tank/rootfs on /tank/rootfs (zfs, local, nfsv4acls)

rsync from SD card to ZFS data set

# rsync rootfs
rsync -aAXvr --progress --delete /* /tank/rootfs \
    --exclude='/boot/*' \
    --exclude='/home/*' \
    --exclude='/dev/*' \
    --exclude='/proc/*' \
    --exclude='/net/*' \
    --exclude='/tmp/*' \
    --exclude='/mnt/*' \
    --exclude='/tank/*' \
    --exclude='/media/*'

# rsync home
rsync -aAXvr --progress --delete /home/* /tank/home 

Modify /boot/loader.conf in SD card

/boot/loader.conf:
geom_label_load="YES"
opensolaris_load="YES"
verbose_loading="YES"
zfs_load="YES"
vfs.root.mountfrom="zfs:tank/rootfs"
kern.cam.boot_delay="20000"

Fix boot folder

cd /tank/rootfs
mkdir bootdir
ln -s bootdir/boot boot

Modify /tank/rootfs/etc/fstab in SSD

root@router:~/script # cat /tank/etc/fstab 
# Custom /etc/fstab for FreeBSD embedded images
/dev/ufs/rootfs		/bootdir       	ufs     rw    			1 1
/dev/msdosfs/MSDOSBOOT 	/boot/msdos 	msdosfs rw,noatime 		0 0
tank/rootfs    		/ 		zfs 	rw,noatime 		0 0
tank/home 		/home 		zfs 	rw,noatime 		0 0
tmpfs 			/tmp 		tmpfs 	rw,mode=1777,size=50m 	0 0