How to Install an M.2 hard drive on a Raspberry Pi 4

Looking to remove one more speed bottleneck from your Raspberry Pi server? Me, too! That’s why I looked into SSD hard drive technology, specifically an M.2 drive, for my Raspberry Pi 4. The Pi4 has two USB3 sockets and I really wanted to take advantage of its interface speed. Those little blue sockets hold big secrets. Just take a look at how the speed has increased over the past few years!

USB Interface Speeds

USB version1233.13.24
Introduction199620012011201420172019
Data rate1.5 Gb/s1.5 Gb/s5 Gb/s10 Gb/s20 Gb/s40 Gb/s
USB speed comparison

Let’s see if we can get some better read / write times out of that USB3. I’m tired of looking at top and seeing the “wa” (hard drive waiting times) posting such high numbers!

Hardware Used in this Test

Geekworm X872 m.2 HAT A quick search on Amazon yielded this little device that lets me put a NAND gate drive on my Raspberry PI’s USB3 port.

WD_Black SN750 250GB M.2 2280 format drive from Western Digital. Geekworm recommended not using a Samsung…

Raspberry Pi 4 Model B (4GB model )

SanDisk 32GB Ultra microSDHC I buy these 5 at a time.

SanDisk Cruzer Fit 8 GB USB Flash Drive (buy these IN a 5 pack)

Here’s the Geekworm kit. Basically you get a board to clip the M.2 drive to, some standoffs, the USB3 coupler, and a screwdriver.

Assembly is simple. Use the standoffs to attach the boards and put the USB3 coupler in place. Slide the M.2 drive into place and use the flathead screw to hold it in place.

Boot Time!

Boot it up and let’s see if it works:

root@node4-0:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 232.9G 0 disk
└─sda1 8:1 0 232.9G 0 part /m2
sdb 8:16 1 7.5G 0 disk
└─sdb1 8:17 1 7.5G 0 part /thumb
mmcblk0 179:0 0 29.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 29.5G 0 part /

Ahhh! It’s so nice when things work the first time! sda is the M.2 drive on the Geekworm board. sdb is a Sandisk 8Gb thumb drive. mmcblk0 is the SD card.

Here’s a different view:

root@node4-0:~# lsusb
Bus 002 Device 002: ID 152d:0562 JMicron Technology Corp. / JMicron USA Technology Corp.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0781:5571 SanDisk Corp. Cruzer Fit
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@node4-0:~#

Here you can see the M.2 interface board, the thumb drive and SD card. Let’s see if we can partition the M.2 drive. I’ve been using parted. I like it because you can tell 100% for the end of the partition to use the whole drive. I hate trying to figure out the math.

M.2 drive Configuration

root@node4-0:~# parted
GNU Parted 3.2
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) mklabel gpt
(parted) mkpart
Partition name? []? m2
File system type? [ext2]? ext4
Start? 1
End? 100%
(parted) quit
Information: You may need to update /etc/fstab.
root@node4-0:~# mkfs /dev/sda1
mke2fs 1.44.5 (15-Dec-2018)
Creating filesystem with 61049344 4k blocks and 15269888 inodes
Filesystem UUID: 341e5082-773e-4ee6-b6e4-41a80c304ac5
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

Mount it and check it:

root@node4-0:~# mount /dev/sda1 /mnt
root@node4-0:~# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 29G 3.1G 25G 12% /
devtmpfs 1.8G 0 1.8G 0% /dev
tmpfs 1.9G 20K 1.9G 1% /dev/shm
tmpfs 1.9G 492K 1.9G 1% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/mmcblk0p1 253M 54M 199M 22% /boot
tmpfs 380M 0 380M 0% /run/user/1000
tmpfs 380M 0 380M 0% /run/user/0
/dev/sda1 230G 60M 218G 1% /mnt

Speed Testing

OK. It really works! I’m dying to speed test this thing in comparison to the SD card and the thumb drive. Let’s set up three directories, each one on a different media:

root@node4-0:~# mkdir /m2
root@node4-0:~# mkdir /thumb
root@node4-0:~# mkdir /sdcard
root@node4-0:~# mount /dev/sda1 /m2
root@node4-0:~# mount /dev/sdb1 /thumb

Let’s use dd’s “direct mode” to test the three mounted media. I mounted the M.2 drive to /m2. I mounted the thumb drive to /thumb and the SD card is the root drive, so I just created a directory “/sdcard” to represent the SD card. I’ll issue a dd to copy from the zero “device” to each of the mount points. The combination of command line arguments will create a 2GB file on each device and we can analyze the results in the dd standard out.

First the SD card:

root@node4-0:~# dd if=/dev/zero of=/sdcard/2G_test_file.txt oflag=direct bs=128k count=16k
16384+0 records in
16384+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 170.724 s, 12.6 MB/s

That last number, 12.6 MB/s is our baseline. Nothing to write home about. Next, the thumb drive:

root@node4-0:~# dd if=/dev/zero of=/thumb/2G_test_file.txt oflag=direct bs=128k count=16k 16384+0 records in 16384+0 records out 2147483648 bytes (2.1 GB, 2.0 GiB) copied, 596.521 s, 3.6 MB/s

3.6 MB/s!?!? We’re going in the wrong direction. Actually, this is no surprise. I always tell people that you trade speed for reliability when you go from SD card to thumb drive. Finally, let’s hit our fancy new M.2:

root@node4-0:~# dd if=/dev/zero of=/m2/2G_test_file.txt oflag=direct bs=128k count=16k
16384+0 records in
16384+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 16.4942 s, 130 MB/s
root@node4-0:~#

The Big Winner

130MB/s! Hell, yeah! That’s what I’m talking about! Thanks, Geekworm! Awesome product! Time to get my Minecraft world file copied over to my new drive!!

Author: John

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.