Move Raspberry Pi Root File System (rootfs) From SD Card To Usb / HDD

So it is a well known fact now that SD cards have a limited life with their read/writes. This poses a problem for the raspberry pi as the root file system is all sat on an SD. If you have ever been met with corruption issues or crashes you more than likely end up having to reflash a new image to the SD card which can result in you losing all of your set up. To get around this there have been a number of posts on the forums regarding moving the root folders out of the SD card and purely using a USB flash drive or HDD.

There are a few benefits to doing this such as increased access/write speeds, being able to use much smaller SD cards (cheaper) and being able to reduce the chance of corruption of your files.

It has to be said not all the files can be moved, I have mentioned root files but the SD card has to keep the boot information. This allows the pi to mount the external drives. So.. with all of the above being said lets get down to a typical set up.

So I start off by plugging in a usb flash drive to my pi USB hub that was laying around. Its just a run of the mill 7GB data traveler 3G. Im unsure on the exact speeds initially but at the end of this post there are some benchmark results.

Once you have the drive plugged in you want to see where the root file system is currently sat. You should have one part of the SD card called /.

From the below code you can see the root directory is sat under rootfs and /dev/root. This could also be /dev/mmcblk0p2 for some people.

pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          3.7G  2.0G  1.5G  58% /
/dev/root       3.7G  2.0G  1.5G  58% /
devtmpfs        227M     0  227M   0% /dev
tmpfs            48M  264K   47M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            94M     0   94M   0% /run/shm
/dev/mmcblk0p1   56M   19M   38M  34% /boot
/dev/sdb1       298G   38G  260G  13% /media/usbhdd
/dev/sda1       7.2G  145M  6.7G   3% /media/usbstick

You can also see from the above the usb drive is sat at /dev/sda1 I have used this in the past briefly when messing around with mounting hence why it is mounted on /media/usbstick. If yours is not mounted anywhere specifically do not worry.

To get the file system moved I first need to unmount the drive if it is mounted.

pi@raspberrypi ~ $ sudo umount /dev/sda1

Now the usb drive is actually formatted in fat as it is an old one im using. For this to work all nice and dandy with linux it is best to reformat the drive using the following command. But we also first need to ensure that there is one partition on the drive which we will later expand out once the copying of the root is completed.

Type the following to bring up the partition information.

pi@raspberrypi ~ $ sudo fdisk /dev/sda1

You will then need to ensure there are no partitions on the drive so press d and hit enter. Keep doing this until no partitions are present.

Now that we have a clean card we can create a single new partition by pressing n and then hitting p for primary partition then enter and enter again to take the default allocation values. Finally press w which will write all of the changes to the card.

We now have a card with a single fresh partition. The next step is to convert the fat system to a nice friendly linux ext4 format.

To do that we will re-format the drive as shown below.

pi@raspberrypi ~ $ sudo mkfs.ext4 /dev/sda1

It is at this point that we should check that the file system is all set up correctly by running the following.

pi@raspberrypi ~ $ sudo e2fsck /dev/sda1

The output for me was not so perfect but luckily the system offers all the assistance to get everything working correctly.

e2fsck 1.42.5 (29-Jul-2012)
Superblock needs_recovery flag is clear, but journal has data.
Run journal anyway? yes
/dev/sda1: recovering journal
Clearing orphaned inode 1281 (uid=107, gid=110, mode=0100600, size=0)
Clearing orphaned inode 1275 (uid=107, gid=110, mode=0100600, size=0)
Clearing orphaned inode 1267 (uid=107, gid=110, mode=0100600, size=0)
Clearing orphaned inode 1266 (uid=107, gid=110, mode=0100600, size=0)
Clearing orphaned inode 1254 (uid=107, gid=110, mode=0100600, size=0)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong (423611, counted=423580).
Fix? yes
Free inodes count wrong (159160, counted=159154).
Fix? yes

/dev/sda1: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sda1: 86606/245760 files (0.2% non-contiguous), 537188/960768 blocks
pi@raspberrypi ~ $ sudo e2fsck /dev/sda1
e2fsck 1.42.5 (29-Jul-2012)
/dev/sda1: clean, 86606/245760 files, 537188/960768 blocks

As you can see at the end there I do a check once more just to be sure everything reports back clean. If your card was alright to start out with it would have just reported clean at the beginning.

What I will do now is mount the drive and see how everything looks.

pi@raspberrypi ~ $ sudo mount /dev/sda1 /media/usbstick
pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          3.7G  2.0G  1.5G  58% /
/dev/root       3.7G  2.0G  1.5G  58% /
devtmpfs        227M     0  227M   0% /dev
tmpfs            48M  264K   47M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            94M     0   94M   0% /run/shm
/dev/mmcblk0p1   56M   19M   38M  34% /boot
/dev/sdb1       298G   38G  260G  13% /media/usbhdd
/dev/sda1       3.7G  2.0G  1.5G  58% /media/usbstick

If you have not made the directory /media/usbstick then you will get an error saying the mount point does not exist. Just simply use the mkdir command to create the directory and then run the mount command again.

As you can see our sda1 drive is now showing 3.7G size when it is a 7.0GB stick this is because we used the default partition values.

We can now begin copying over our root file system over to the card by carrying out the following command.

pi@raspberrypi ~ $ sudo dd if=/dev/root of=/dev/sda1 bs=4M

This will take a while.. so be warned. It has taken me up to an hour for this command to complete so don’t go turning off your pi midway through!

We can now expand the partition to fill the full 7GB as shown below. I have added the -p flag to the command which will give updates on how far through the command has got during execution.

pi@raspberrypi ~ $ sudo resize2fs -p /dev/sda1
resize2fs 1.42.5 (29-Jul-2012)
Filesystem at /dev/sda1 is mounted on /media/usbstick; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/sda1 is now 1891455 blocks long.

This produces…

pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          3.7G  2.0G  1.5G  58% /
/dev/root       3.7G  2.0G  1.5G  58% /
devtmpfs        227M     0  227M   0% /dev
tmpfs            48M  264K   47M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            94M     0   94M   0% /run/shm
/dev/mmcblk0p1   56M   19M   38M  34% /boot
/dev/sdb1       298G   38G  260G  13% /media/usbhdd
/dev/sda1       7.2G  2.0G  4.9G  30% /media/usbstick

We can now start working on our fstab to ensure that the usb drive is mounted as root!

pi@raspberrypi ~ $ sudo nano /media/usbstick/etc/fstab

Change your settings to show the following.

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/sda1       /               ext4    defaults,noatime  0       1

As you can see /dev/sda1 is now / (root). You can comment out the line that shows your sd card as / (root).

Our final step is to edit the boot cmdline.txt file. This is where we will tell the pi where to go looking for our root and where the fstab file exists etc.

pi@raspberrypi ~ $ sudo nano /boot/cmdline.txt

You want your configuration to look as follows.

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline rootwait

The final step… reboot!

pi@raspberrypi ~ $ sudo reboot

Broadcast message from root@raspberrypi (pts/0):
The system is going down for reboot NOW!

Hopefully your system has booted correctly! if you want you can now remove the root file system on the sd card and even lock the card completely so that it no longer gets written to.

As promised I said I would post some benchmarks, which were quite surprising considering I had read that one of the major benefits to moving was the increase in read/write speed. As you can see I can not say the same! To be honest though as with most of the pi projects it all comes down to the quality of the components you use.

Speed tests:
USB

/dev/sda:
 Timing cached reads:   258 MB in  2.00 seconds = 128.85 MB/sec
 Timing buffered disk reads:  24 MB in  3.08 seconds =   7.79 MB/sec

SD

/dev/mmcblk0p1:
 Timing cached reads:   332 MB in  2.01 seconds = 165.36 MB/sec
 Timing buffered disk reads:  56 MB in  2.89 seconds =  19.40 MB/sec

HDD

/dev/sdb1:
 Timing cached reads:   296 MB in  2.01 seconds = 147.56 MB/sec
 Timing buffered disk reads:  80 MB in  3.02 seconds =  26.48 MB/sec

I am not too bothered about the slower speed I can at least now live with the fact I should see much less corruption!

You may also like...

  • andreas

    I think this line:
    pi@raspberrypi ~ $ sudo dd if=/dev/rootfs of=/dev/sda1 bs=4M

    should be
    pi@raspberrypi ~ $ sudo dd if=/dev/root of=/dev/sda1 bs=4M

    Thanks

    • MrMobberley

      Thanks for spotting the error.ive updated the article now :)

  • aa

    amazingly helpful thank you

  • Nigel Walton

    Really good piece. I’ve got a few points and some questions if I may? The first thing that I learnt is that on my setup the /dev/sda1 didnt appear as your screen shots. I never saw the name but was able to do the things that you suggest in the article (making it very good). I too suffer from corruption as users have a nasty habit of pulling the power cable out at bad times and therefore this is why I “feel” that I need to do something to help stop it. I hope I’m taking the right approach. My final thought is: SDcard to book up (so will be a 2gb, just to get you going, then first partition on USB stick will be the OS and other programs, and a 2nd partiton on the USB will be for data which is written to often and “probably” what is causing the original solution to kill the root as everything was in a single partition previously on the SD card. HELP! the issue I have got is that I’m struggling to understand how to create a 2nd partition on the USB stick!

    Can you please help! The stick is 16gb and following your instructions I got to the following (when mounted). First thing is I need to make the root (which is called /media/usbstick here as I have currently reversed the changes in the cmdline.txt file to see if it helped). I need to expand this to 8Mb. The remaining 8Gb I’d like as a 2nd partition for data only, so if this gets corrupted there (and this is the next question) then be away of using the good root parition to start the RPI and then do some cleaning on the data partition? Sounds to me like a plan but as you can see below I cant create a 2nd partition (and / or expand the first partition). PLEASE HELP ME :)

    pi@raspberrypi:/$ df -h
    Filesystem Size Used Avail Use% Mounted on
    rootfs 1.9G 1.4G 330M 82% /
    /dev/root 1.9G 1.4G 330M 82% /
    devtmpfs 212M 0 212M 0% /dev
    tmpfs 44M 224K 44M 1% /run
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 88M 0 88M 0% /run/shm
    /dev/mmcblk0p1 56M 19M 38M 34% /boot
    /dev/sda1 1.9G 1.4G 330M 82% /media/usbstick
    pi@raspberrypi:/$ sudo parted /dev/sda1
    GNU Parted 2.3
    Using /dev/sda1
    Welcome to GNU Parted! Type ‘help’ to view a list of commands.
    (parted) unit chs
    (parted) print
    Model: Unknown (unknown)
    Disk /dev/sda1: 1960,15,36
    Sector size (logical/physical): 512B/512B
    BIOS cylinder,head,sector geometry: 1960,255,63. Each cylinder is 8225kB.
    Partition Table: loop

    Number Start End File system Flags
    1 0,0,0 1960,15,36 ext4

  • Pingback: Reducing power consumption and boot time | Raspberry Robot

  • Steve

    I followed your instruktions and it worked like a charm. And same as you, I have lower speed on the sda1 now since the HDD seems to be less performant than the sd card. So I want to say a huge thanks to you!

    Regards,
    Steve

  • Bob Bond

    Very cool, thanks for posting. Tutorial worked great.

  • john

    help the exterial hdd is 250 gbs and the resize has taken 2 days!!! should i let it keep running or how should i kill it??

  • Richard Laniel

    Hi, this article is about 3 months old. How about corruption? Is it less frequent? Nonexistent? About the same? I would like to know about it. Thank you.

    • MrMobberley

      Ive had 0 corruption so far using usb which is actually hosting this blog so safe to say it all seems ok

  • Fabian

    Nice tutorial. Except I guess it was written for raspbian. With archlinux one has to do a few slightly different steps.
    I am not a linux expert (just enough knowledge to get myself in trouble :-)). Seems that with archlinux for the raspberry the kernel is responsible for mounting the root filesystem. There is no entry in fstab for “/” and there is no /root in the /dev directory.

    So dd if=/dev/root of=/dev/sda1 failed. I used dd if=/dev/mmcblk0p2 of=/dev/sda1 instead and omited editing the fstab. Works now for me.

    • MrMobberley

      Correct, this was used in raspbian and the other debian variations

  • Pingback: Moving the root file system of Raspberry Pi to external USB drive | Martin's corner on the web

  • Pingback: Tuto | Pearltrees

  • zz

    Thanks for the tutorial. What cmd did you run to produce the read/write test info?

    • Jack Longley

      hdparm -t /dev/sda1

  • sergio

    Hi, any help with this situation?
    1) I couldnt have the usb label to be “usbstick” as you. I managed to get it but then it complained so I restarted again.
    2) then when copying over I get this error. It stopped after around 15min instead of an hour like yours.
    (my usb drive is 4Gb)

    pi@raspberrypi ~ $ df -h
    Filesystem Size Used Avail Use% Mounted on
    rootfs 7.3G 1.9G 5.1G 28% /
    /dev/root 7.3G 1.9G 5.1G 28% /
    devtmpfs 212M 0 212M 0% /dev
    tmpfs 44M 256K 44M 1% /run
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 88M 0 88M 0% /run/shm
    /dev/mmcblk0p1 56M 19M 38M 33% /boot
    /dev/sda1 3.9G 72M 3.6G 2% /media/c829f58e-c71b-4dab-850c-e69ea36f2ecf
    pi@raspberrypi ~ $ sudo dd if=/dev/root of=/dev/sda1 bs=4M
    dd: writing `/dev/sda1′: No space left on device
    999+0 records in
    998+0 records out
    4187811840 bytes (4.2 GB) copied, 769.612 s, 5.4 MB/s
    pi@raspberrypi ~ $

    Thank you very much for your help

    • Jeff Chaves

      Your sdcard is bigger than your usb drive “/dev/root 7.3G 1.9G 5.1G 28% /” you cant fit 7GB into a 4GB drive, you will need a bigger usb drive or install raspbian and copy the root partition BEFORE you resize it. That way it might work if the stock partition is smaller than 4GB. Good Luck!

    • Hugo

      the size of your rootfs is 7.3G and your sda1 size is 4.2G, so the dd command can not be completed.
      That is the meaning of this line:
      dd: writing `/dev/sda1′: No space left on device
      and this one:
      4187811840 bytes (4.2 GB) copied, 769.612 s, 5.4 MB/s

  • Tomi

    Hi

    Please help. I am trying to get 70gb usb hdd to work.
    After
    sudo dd if=/dev/root of=/dev/sda1 bs=4M
    930+1 records in
    930+1 records out
    3902275584 bytes (3.9 GB) copied, 272.029 s, 14.3 MB/s

    There is only:
    pi@raspberrypi /media/usbhdd $ ls
    Opcode.so

    ?
    sudo resize2fs /dev/sda1 gets over night and does not help

    sudo nano /media/usbhdd/etc/fstab opens blank sheet

    Thanks alot.

    • Jefferson Chaves

      Did you mount your HDD? “sudo mount /dev/sda1 /media/usbhdd”

      • Tomi

        Yes I did.

        I got it working like this:
        sudo dd if=/dev/root of=/dev/sda1
        sudo e2fsck /dev/sda1

        it fixed some errors and now ok.

  • Giovani

    is it normal that resize2fs takes so long to complete (I have it running now for over 36 hours !!!) ????

    • MrMobberley

      No! I would give it all a restart it might have crashed after that long

      • Giovani

        you were right! after a restart it worked with a sudo e2fsck /dev/sda1 and resize2fs again. no longer than 2 minutes. thanks!

  • yad

    6 month…How about corruption?

    • MrMobberley

      Still running perfectly fine for me

  • Pt

    I know this is a pretty basic question but what tool are you using to benchmark the SD and external drive?

  • Pt

    Thank you so much for your fast answer, it worked like a charm!

    I have another question: what if you decide to return all files to your SD Card. I’m guessing I need to reverse the process. Can you direct some instructions please?

    I’m really that noob… :-)

    • MrMobberley

      As you have said the main part is to reverse the tutorial. But most importantly this is the line that needs the switch:

      sudo dd if=/dev/root of=/dev/sda1 bs=4M

      switch those around to copy backwards

  • http://- Michal

    Hi, I’m trying to do is use a 8GB usb stick, and after: sudo fdisk /dev/sda1, then d, to delete old partition(s), next n, enter, enter (default values) and finally w. Then I have message: “WARNING: re-reading the partition table failed with error 22: invalid argument. The kernel still uses the old table. The new table will be used at the next reboor or after you run partprobe(8) or kpartx(8). Syncing disks.”
    So I tried to reboot, and it still gives this message. What should I do?

  • Pingback: OpenEnergyMonitor su RaspberryPi - Pagina 16

  • Pingback: Clicknoise » Blog Archive » Moving Home: Raspberry Pi

  • http://gravatar.com/esegev1 esegev1

    I am trying to do this with a 187GB external HDD and i am stuck on “sudo resize2fs -p”. It has been going for over 12 hours and I am just wondering if this should just take this long or if something is wrong.

  • joao

    Hi,

    I could understand you maintain a fully working root partition on the SD card, even though you are using the root in the USB stick.
    I was wondering if it would be possible to define some kind of “boot fall-back”: Some way to tell the raspberry to use the root FileSystem from the SD if the USB is not there. (not automatically, of course, only during booting).
    In other words:
    When booting, do: if USB present, then boot from USB, else, boot from SD.

    Thanks,
    Joao

  • Pingback: URL

  • Bradley Halstead

    I have been trying to move the rasbmc OS off of my sd card and onto a usb stick that will be permanently inserted, i have the usb stick formatted on ext4 and only has one partition (this is a 16gb usb stick), the problem is when i use the dd command to clone the sd card to the usb stick, it tells me the file system is 3.2GB used is -12G and has 15G available, and when trying to use resize2fs i get a kernel error and no file is available on the usb stick, im not sure what to do, i disclosed images of the error

%d bloggers like this: