What the Helper Script Does

At this point, hopefully you're good to go with a working system. You can safely skip this section, but it might be helpful to know the basics of what's changed on your system.

We won't go over adafruit-pi-externalroot-helper line by line, but let's hit the high points. (For more detail, there are extensive comments in the script itself.)

Here's what the script does:

Install Dependencies

apt-get install gdisk rsync parted

We'll need a handful of utilities:

  • gdisk is GPT fdisk, a tool for working with GUID Partition Tables.
  • rsync is a utility for fast file transfers. It's usually used to copy and synchronize collections of files over the network, but also works between filesystems. Here it's used to copy your existing filesystem from the SD card to the external drive.
  • parted is GNU Parted, another utility for working with partition tables. We'll use it to actually create a new partition on the external drive.

Create Target Partition & Filesystem

parted --script "${target_drive}" mklabel gpt
parted --script --align optimal "${target_drive}" mkpart primary ext4 0% 100%
mkfs -t ext4 -L rootfs "${target_partition}"

These commands create a new partition on our target drive (usually /dev/sda), using the entire drive, and then build a new ext4 filesystem on that partition.

Find Partition UUID and Partition Unique GUID

eval `blkid -o export "${target_partition}"`
export target_partition_uuid=$UUID
export partition_unique_guid=`echo 'i' | sudo gdisk /dev/sda | grep 'Partition unique GUID:' | awk '{print $4}'`

blkid -o export /dev/sda1 gives a list of attributes for that partition, including a UUID, which we'll use later in /etc/fstab to make sure that the root partition is mounted from the external drive.

We could just use /dev/sda1, but the drive isn't guaranteed to show up as that device if other drives are plugged in. The UUID should be unique to the root partition on the external drive.

echo 'i' | sudo gdisk /dev/sda | grep 'Partition unique GUID:' | awk '{print $4}' gives us a similar value which we can put in /boot/cmdline.txt to tell the kernel what partition to treat as root.

Copy Filesystem to External Drive

mount "${target_partition}" /mnt
rsync -ax / /mnt

Here we attach /dev/sda1 (or other target drive) to /mnt on the current filesystem, and use rsync to copy all the files across. The -a option means "archive", which should preserve file permissions, modification times, etc., and the -x option means "don't cross filesystem boundaries", so it'll skip /boot and /mnt.

Configure Pi to Boot With New Filesystem

cp /boot/cmdline.txt /boot/cmdline.txt.bak
sed -i "s|root=\/dev\/mmcblk0p2|root=PARTUUID=${partition_unique_guid} rootdelay=5|" /boot/cmdline.txt

sed -i '/mmcblk0p2/s/^/#/' /mnt/etc/fstab
echo "/dev/disk/by-uuid/${target_partition_uuid}    /   ext4    defaults,noatime  0       1" >> /mnt/etc/fstab

These commands tweak /boot/cmdline.txt to boot from the new root partition (identified by the GUID from gdisk) and the new partition's /etc/fstab to mount it as root (identified by the UUID from blkid) instead of the old root partition from the SD card.

If something goes wrong here, you can copy cmdline.txt.bak over cmdline.txt from another machine, and your Pi should boot like before.

Last updated on 2015-05-04 at 04.27.56 PM Published on 2015-04-13 at 12.15.17 PM