Using HDD with Raspberry PI
Posted: Fri Jan 10, 2020 1:07 am
I tried to use some instructions to move root fs from the SD card to an external USB HDD. But nothing worked for me. So, I had to do id a bit differently. It probably would be better to post this to wiki. Except I have no idea how to do this. So, here are some (detailed) instructions on using USB HDD with RPI.
Warning: I used a very slow class 4 SD card since it is going to be used for only a boot partition
in the end. All operations with it take enormous amount of time. But I don't care as it will
not be used for actual work this RPI is intended for.
First 4 steps I did on my MAC. But any Linux computer could be used as well. Just replace diskutil
command with whatever Linux uses to unmount an fs.
1.
My antivirus (ESET) sometimes blocks this operation. So, it has to be repeared 2-3 times.
Note: SD card reader on my MAC shows up as /dev/disk4. It could be different on your
computer. Check before overwriting it. "df" or "disk utility" could help with it.
On Linux use "df", "lsblk" or "blkid". I warned you!
2.
3.
4.
My antivirus (ESET) sometimes blocks this operation. So, it has to be repeared 2-3 times.
Next steps are performed on Raspberry PI. I used the latest RPI 4 B.
5. Boot RPI using this SD card. Use Ethernet cable, at least for now.
6. Find this RPI's IP and login (ssh) with pi/raspberry. You can find IP in your DHCP server's "current leases" list.
7. Don't forget to change password
8. Attach USB HDD. I use 4 TB external USB-3 HDD. Btw, it came with a regular USB-3 cable. So, I had to
get another one with additional USB power connector off Ebay. I connect it to a 60W power supply, which
also powers RPI. It has 6 USB sockets rtated 2.4 A each. So, I can probably connect another USB HDD
to it.
9. Look for USB HDD. In my case it is /dev/sda
9. Clear the HDD (make sure no useful data is there). You might skip this step and the following
one if you already have a partition that satisfies you. Like in the above case, I have an Linux
type partition that occupies the whole drive. But for the sake of this tutorial I will delete
and recreate it.
10. Create a big partition
11. Doublechecking
12. Copy root fs to USB drive
13. Since we copied a live partition it needs to be cleaned.
14. And expanded. It took 1 hour and 12 min to expand partition to full 4 TB.
15. Mount new partition.
16. Get the PARTUUIDs for partitions.
PARTUUID for the boot partition is 6c586e13-01
PARTUUID for the new root partition is 6debc4c1-0e9f-864e-ba94-ec95db099690
17. Edit /boot/cmdline.txt: replace PARTUUID, add a delay for USB HDD to become ready.
New content:
console=serial0,115200 console=tty1 root=PARTUUID=6debc4c1-0e9f-864e-ba94-ec95db099690 rootdelay=5 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
18. Edit /etc/fstab on the USB drive (/mnt/etc/fstab actually).
To make boot filesystem readonly add ",ro". Warning, after this you won't be able to install some updates
Replace PARTUUID for the root system too.
19. Reboot
After the reboot:
20. Delete root partition from the SD card and backup the boot partition
20.1.
20.2. Not sure if this is the right way. But works for restoring the SD card.
21. Install zoneminder or whatever you need that huge drive for.
Warning: I used a very slow class 4 SD card since it is going to be used for only a boot partition
in the end. All operations with it take enormous amount of time. But I don't care as it will
not be used for actual work this RPI is intended for.
First 4 steps I did on my MAC. But any Linux computer could be used as well. Just replace diskutil
command with whatever Linux uses to unmount an fs.
1.
Code: Select all
diskutil unmount /Volumes/<whatever_name_your_SD_card_has>
Code: Select all
Volume boot on disk4s1 unmounted
computer. Check before overwriting it. "df" or "disk utility" could help with it.
On Linux use "df", "lsblk" or "blkid". I warned you!
2.
Code: Select all
dd if=/tmp/raspbian.img of=/dev/disk4 bs=1m conv=sync
2144+0 records in
2144+0 records out
2248146944 bytes transferred in 917.897363 secs (2449236 bytes/sec)
3.
Code: Select all
touch /Volumes/boot/ssh
Code: Select all
diskutil unmount /Volumes/boot
Code: Select all
Volume boot on disk4s1 unmounted
Next steps are performed on Raspberry PI. I used the latest RPI 4 B.
5. Boot RPI using this SD card. Use Ethernet cable, at least for now.
6. Find this RPI's IP and login (ssh) with pi/raspberry. You can find IP in your DHCP server's "current leases" list.
7. Don't forget to change password
8. Attach USB HDD. I use 4 TB external USB-3 HDD. Btw, it came with a regular USB-3 cable. So, I had to
get another one with additional USB power connector off Ebay. I connect it to a 60W power supply, which
also powers RPI. It has 6 USB sockets rtated 2.4 A each. So, I can probably connect another USB HDD
to it.
9. Look for USB HDD. In my case it is /dev/sda
Code: Select all
lsblk
Code: Select all
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 3.7T 0 disk
└─sda1 8:1 0 3.7T 0 part
mmcblk0 179:0 0 3.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 3.4G 0 part /
one if you already have a partition that satisfies you. Like in the above case, I have an Linux
type partition that occupies the whole drive. But for the sake of this tutorial I will delete
and recreate it.
Code: Select all
dd if=/dev/zero of=/dev/sda bs=1M count=1000
Code: Select all
lsblk
Code: Select all
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 3.7T 0 disk
mmcblk0 179:0 0 3.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 3.4G 0 part /
Code: Select all
fdisk /dev/sda
Code: Select all
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
The size of this disk is 3.7 TiB (4000787029504 bytes). DOS partition table format cannot be used on drives for volumes larger than 4294966784 bytes for 512-byte sectors. Use GUID partition table format (GPT).
Created a new DOS disklabel with disk identifier 0x47d1a7f2.
Command (m for help): g
Created a new GPT disklabel (GUID: C9252DF5-BBE3-8D41-A6A1-146CB4C56AC0).
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-7814037133, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-7814037133, default 7814037133):
Created a new partition 1 of type 'Linux filesystem' and of size 3.7 TiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Code: Select all
lsblk
Code: Select all
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 3.7T 0 disk
└─sda1 8:1 0 3.7T 0 part
mmcblk0 179:0 0 3.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 3.4G 0 part /
Code: Select all
dd if=/dev/mmcblk0p2 of=/dev/sda1 bs=1M
Code: Select all
3521+1 records in
3521+1 records out
3692560384 bytes (3.7 GB, 3.4 GiB) copied, 80.5194 s, 45.9 MB/s
Code: Select all
e2fsck -f /dev/sda1
Code: Select all
e2fsck 1.44.5 (15-Dec-2018)
rootfs: recovering journal
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 (602687, counted=560037).
Fix<y>? yes
Free inodes count wrong (180977, counted=180594).
Fix<y>? yes
rootfs: ***** FILE SYSTEM WAS MODIFIED *****
rootfs: 44750/225344 files (0.3% non-contiguous), 341467/901504 blocks
Code: Select all
resize2fs /dev/sda1
Code: Select all
resize2fs 1.44.5 (15-Dec-2018)
Resizing the filesystem on /dev/sda1 to 976754385 (4k) blocks.
The filesystem on /dev/sda1 is now 976754385 (4k) blocks long.
Code: Select all
mount /dev/sda1 /mnt
16. Get the PARTUUIDs for partitions.
Code: Select all
blkid
Code: Select all
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="5203-DB74" TYPE="vfat" PARTUUID="6c586e13-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="2ab3f8e1-7dc6-43f5-b0db-dd5759d51d4e" TYPE="ext4" PARTUUID="6c586e13-02"
/dev/sda1: LABEL="rootfs" UUID="2ab3f8e1-7dc6-43f5-b0db-dd5759d51d4e" TYPE="ext4" PARTUUID="6debc4c1-0e9f-864e-ba94-ec95db099690"
/dev/mmcblk0: PTUUID="6c586e13" PTTYPE="dos"
PARTUUID for the new root partition is 6debc4c1-0e9f-864e-ba94-ec95db099690
17. Edit /boot/cmdline.txt: replace PARTUUID, add a delay for USB HDD to become ready.
Code: Select all
nano /boot/cmdline.txt
New content:
console=serial0,115200 console=tty1 root=PARTUUID=6debc4c1-0e9f-864e-ba94-ec95db099690 rootdelay=5 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
18. Edit /etc/fstab on the USB drive (/mnt/etc/fstab actually).
To make boot filesystem readonly add ",ro". Warning, after this you won't be able to install some updates
Replace PARTUUID for the root system too.
Code: Select all
PARTUUID=6c586e13-01 /boot vfat defaults,ro 0 2
PARTUUID=6debc4c1-0e9f-864e-ba94-ec95db099690 / ext4 defaults,noatime 0 1
19. Reboot
After the reboot:
Code: Select all
df
Code: Select all
Filesystem 1K-blocks Used Available Use% Mounted on
[b]/dev/root 3846750000 1272876 3669881928 1% /[/b]
devtmpfs 860916 0 860916 0% /dev
tmpfs 993012 0 993012 0% /dev/shm
tmpfs 993012 16804 976208 2% /run
tmpfs 5120 4 5116 1% /run/lock
tmpfs 993012 0 993012 0% /sys/fs/cgroup
/dev/mmcblk0p1 258095 53933 204162 21% /boot
tmpfs 198600 0 198600 0% /run/user/1000
20.1.
Code: Select all
fdisk /dev/mmcblk0
Code: Select all
Welcome to fdisk (util-linux 2.33.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Command (m for help): p
Disk /dev/mmcblk0: 3.7 GiB, 3965190144 bytes, 7744512 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6c586e13
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
Command (m for help): w
The partition table has been altered.
Syncing disks.
Code: Select all
dd if=/dev/mmcblk0 of=/var/backups/boot_backup bs=1M count=260
Code: Select all
260+0 records in
260+0 records out
272629760 bytes (273 MB, 260 MiB) copied, 5.96281 s, 45.7 MB/s