Wednesday, December 26, 2012

Moving Raspberry Pi Root Filesystem Out of SDcard

This post explains how to move / (root file system) out of Rasberry Pi SDcard in Raspbian. Maybe you're asking why would you do that? Well, because SDcard is slow and it's relatively easier to wear-out (i.e. unable to be written anymore) compared to other USB-attached storage, such as USB pen/flash drive or USB-HDD, unless you are using an industrial-grade SDcard which is expensive. For a deployment setup, using SDcard only is the way to go but for a development setup, you would want your / not in the SDcard.

Now, I'll show you how to move the / partition to a USB flash drive. First, copy the contents of your present / in the SDcard to the USB flash drive with dd, I assume that the USB flash drive is recognized as /dev/sda1 by the Raspberry Pi kernel. Anyway, ordinary cp command wouldn't work because it doesn't copy the partition structure.
pi@raspberrypi ~ $ dd if=/dev/mmcblk0p2 of=/dev/sda1 bs=512
Now, get yourself some coffee and work on something else or go to sleep because this would take hours if you have enlarged your SDcard / partition to say 8GB.

The second step is to change the parameters passed to the raspberry pi kernel on boot. The purpose is to change the / (root) partition from mmcblk0p2 to sda1. To do that, you have to edit /boot/cmdline.txt. You can do this step from windows because cmdline.txt is in the vfat partition in the beginning of the SDcard. This is how the parameters passed to the kernel look like after the change (I highlighted the change in italic):
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline rootwait
This is not enough though, you have to change /etc/fstab in the Raspberry Pi (USB flash drive) once the system booted. Remember that you have to plug the USB flash drive after you changed the kernel boot parameter! Because raspberry pi kernel would think that the / (root filesystem) is now in /dev/sda1. This is how the modified /etc/fstab looks like:
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults,ro       0       2
#/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
/dev/sda1       /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, so no using swapon|off from here on, use  dphys-swapfile swap[on|off]  for that
As you can see, I have commented the /dev/mmcblk0p2 root filesystem which corresponds to the second partition in the SDcard. After this change, you can reboot the system and be sure that the / will not be on the SDCard anymore.
Anyway, if you pay attention to the /etc/fstab entries above, you would notice that I mounted /boot in read-only mode. This is to prevent the kernel from writing into the SDcard. In a deployment scenario, it's better to make the entire SDcard mounted in read-only mode, unless you have very specific need to write into one of the SDcard partition.
Post a Comment


NeaGix said...

it's much more efficient that you create a single partition (boot + root) on the destination device and use rsync to synchronize the SD with it. That will not take hours (spent copying empty space, by the way)

Darmawan Salihun said...

Interesting.. thanks for the hint.

Andrew said...

You can also just not resize the SD card and then just resize the USB drive after you move the root, with resize2fs. Thanks for the lil tutorial, helped me out.