Here’s a quick way to create a disk image of the SD card containing openHABian (or any other SD card, actually).
I’m working on MacOS but if you’re working on Linux the instructions are very similar.
First, safely power off your Raspberry Pi. Log onto your Raspberry Pi with the openhabian
user and type:
$ sudo shutdown now
Power off the Raspberry Pi and remove the microSD card.
Insert the microSD card in an SD adapter card, and plug it in your Mac (or Linux computer).
For MacOS, there’s the diskutil
tool that is useful for identifying the microSD card you want to image.
$ diskutil list
...
/dev/disk4 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *32.0 GB disk4
1: Windows_FAT_32 NO NAME 32.0 GB disk4s1
On MacOS Mojave, /dev/disk0 and /dev/disk1 are the system disk. All other storage media, including the microSD card, will have a number higher than 1. In practice, on my laptop, it’s invariably /dev/disk4
.
You could also use mount
to identify potential disk identifiers, as in:
$ mount | grep ' /Volumes/'
...
/dev/disk4s1 on /Volumes/openHABian (msdos, local, nodev, nosuid, noowners)
Note: On Linux, you should rely on the mount
command and identify the default mount folder (often /mnt/
) and adapt the command accordingly, as in:
$ mount | grep ' /mnt/'
Once the SD card has been identified, it is time to create an image. This is easily done with the dd
command. The main difference between MacOS and Linux is that the bs
option only accepts numeric values in MacOS, while most if not all Linux distributions also accept binary units (e.g. 4M instead of 4194304). Also, MacOS has the .dmg
file extension for disk images.
There are now two ways of reading / writing to an SD card: either through /dev/disk#
or through the raw device: /dev/rdisk#
. Using the raw device is perfectly fine in our use case; it will also dramatically speed up the reading and writing operations (by a factor 4-5 on my machine).
To further speed up the operation, it is good to increase the block size. The default block size used by dd
is 512 bytes. So every read of a block is followed by a write before moving on to the next block. This can generate a huge overhead when reading a SD card and writing the image. It is wise to use powers of 2 for the block size, and preferably in the 2-16MB range. Using larger block sizes may again adversely affect performance. So let’s use a block size of 16MB.
For MacOS, type the following (using a 16MB block size):
$ sudo dd if=/dev/rdisk4 of=/Volumes/Backup/openHABian-rpi3/openhabian_rpi3_2019_11_22.dmg bs=16777216
For Linux, type the following (using a 16MB block size):
$ sudo dd if=/dev/rdisk4 of=/mnt/Backup/openHABian-rpi3/openhabian_rpi3_2019_11_22.bin bs=16M
Now be patient. On my machine, taking an image of a 32GB microSD card takes about 10 minutes. The dd
tool will remain silent until it terminated, and will then produce a summary of blocks read and written.
I keep track of progress in another terminal by means of the following code (assuming bash shell):
$ while [ true ] ; do sleep 30 ; du -h /Volumes/Backup/openHABian-rpi3/openhabian_rpi3_2019_11_22.dmg ; done
This will give me an update of the imaging process every 30 seconds. Once the image creation process is done, you can exit this while
loop by hitting <Ctrl>+C
in the terminal.
The output file will now contain a binary image of the full SD card.
Now you can eject the SD card from your computer and plug it again into your Raspberry Pi. Time to power on the Raspberry Pi and now you have a replica of your live SD card.
Note: To write this image to another card, you can again use dd
but then you of course need to invert the if
and of
parameter values. Or you can use a disk flashing utility such as Balena Etcher.