I am using my Raspberry Pi for a backup and torrent server, however even high quality SD cards do not survive for more than a month. Maybe I should have moved the swap file first before attempting what is described here, but in any case, a hard drive is a more reliable medium than an SD card.
So I decided to move the OS to one of the attached hard drives.
In the case of a single usb storage attached to the Pi this would require two steps:
Step 1: The boot loader
You will have to keep the bootloader on the SD card as this is the only device that the Pi recognises and checks early in the boot.
Just prepare an SD card as usual. Then open the boot partition and modify the
cmdline.txt file in order to boot Linux from the hard drive instead of from the
second SD card partition. The bootloader used here is sufficiently smart to
enumerate the USB devices, so you just need to point to the appropriate USB
device by changing the
root parameter to
N is the
appropriate partition number.
Step 2: Place a Pi distribution on the hard drive
You can just use your SD card and type on your laptop
dd if=/dev/mmcblk0p2 of=/dev/sdLN
L is the letter for the appropriate external hard drive and
appropriate partition. After that just use
parted to expand the
partition. And you are done.
You have to use
dd and not
cp, otherwise your system will boot but it
would be unusable because all the user permissions will be lost.
If you wish you can skip the SD card and
dd directly from the image file.
The issue is that the image file contains two partitions so you will have to
specify and offset in order to copy only the second partition (the Linux
partition, not the bootloader partition). Use
parted to find the appropriate offset:
root@debian-laptop:/home/stefan# parted 2013-12-20-wheezy-raspbian.img GNU Parted 2.3 Using /home/stefan/2013-12-20-wheezy-raspbian.img Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) unit Unit? [compact]? B (parted) print Model (file) Disk /home/stefan/2013-12-20-wheezy-raspbian.img: 2962227200B Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 1 4194304B 62914559B 58720256B primary fat16 lba 2 62914560B 2962227199B 2899312640B primary ext4 (parted) quit
And then use
dd to copy from the offset on (and keep the appropriate size):
root@debian-laptop:/home/stefan# dcfldd if=2013-12-20-wheezy-raspbian.img of=/dev/sdLN skip=62914560 count=2899312640 bs=1 2899312640 blocks (2765Mb) written. 2899312640+0 records in 2899312640+0 records out
If you do not care about the few megabytes dedicated to the boot partition you can just dd the whole image instead of cutting out only the second partition. However this will impose the use of the old-style MBR partition table and as you will see in the next section, this might be undesirable.
Step 3: Make it work with more than one USBs attached
I have more than one hard drive attached, so I need a way to distinguish them. The bootloader enumerates the drives asynchronously so the same drive will have different letter designation each time.
The solution is to address the drives by GUID (a unique identification number). However this is not supported by the old style MBR partition table that is set up by default with most partition and formating utilities. You will need to set up your hard drive to use the GUID partition table (GPT) in gparted first.
After that you repeat step 2 and copy the Linux partition to your hard drive. You have to copy only the Linux partition, because copying the whole image will overwrite the GPT table and reinstate the MBR table.
After you are done with that you need to find the GUID of your Linux partition.
You can do this with
root@raspberrypi:/home/pi# gdisk /dev/sda GPT fdisk (gdisk) version 0.8.5 Partition table scan: MBR: hybrid BSD: not present APM: not present GPT: present Found valid GPT with hybrid MBR; using GPT. Command (? for help): i Partition number (1-3): 2 Partition GUID code: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 (Linux filesystem) Partition unique GUID: 176ADF0D-357D-4C4B-ADC0-371342F444AB First sector: 2099200 (at 1.0 GiB) Last sector: 23070719 (at 11.0 GiB) Partition size: 20971520 sectors (10.0 GiB) Attribute flags: 0000000000000000 Partition name: '' Command (? for help): q
And you use this in
Keep in mind that the GUID is not the same number as the UUID that you would
fstab in order to assign the same
mount points for your drives. This
is a separate (and quite useful, so do it) setup process.
- Mounting a hard disk image including partitions using Linux
- Mounting root partition by UUID (no initrd needed)
And now the bootloader will always know which hard drive to use in order to boot Linux.