Building your custom Raspbian image
I recently had to prepare a Raspberry Pi for a client, but it would take too long to send the Pi itself. I had to come with a way to prepare the Pi locally, create an image and send this image electronically.
The problem with creating an image of an SD card, is that it’s size is the size of the SD card. So if you take an image of 32 GB SD card, it has to be flashed back to a 32 GB SD card. That’s something you want to avoid.
In this blog post, I will explain how to prepare a Raspbian image on the Pi and turn it into a distributable image using Mac OS.
First, start by removing the following line from the /boot/cmdline.txt
file:
init=/usr/lib/raspi-config/init_resize.sh
This will prevent the Pi from expanding its file system upon boot. We need this removed, because we want to keep our partition as small as possible.
Next, boot from the SD card as you normally would. Install all the applications you want.
When your done, put your SD card back in to your Mac. Next, put the part your just removed from /boot/cmdline.txt
back (or restore a backup if you took one).
Next, open the Terminal application and list your drives with
diskutil list
You will probably recognise your SD card as /dev/disk2:
/dev/disk2 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *128.0 GB disk2
1: Windows_FAT_32 boot 45.0 MB disk2s1
2: Linux 1.8 GB disk2s2
Find the block size with diskutil info /dev/disk2
:
$ diskutil info disk2
Device Identifier: disk2
Device Node: /dev/disk2
Whole: Yes
Part of Whole: disk2
Device / Media Name: SD Card ReaderVolume Name: Not applicable (no file system)
Mounted: Not applicable (no file system)
File System: NoneContent (IOContent): FDisk_partition_scheme
OS Can Be Installed: No
Media Type: Generic
Protocol: USB
SMART Status: Not SupportedDisk Size: 128.0 GB (128043712512 Bytes) (exactly 250085376 512-Byte-Units)
Device Block Size: 512 BytesRead-Only Media: No
Read-Only Volume: Not applicable (no file system)Device Location: Internal
Removable Media: Removable
Media Removal: Software-ActivatedVirtual: No
Next, find the used size of the SD card’s partitions with sudo fdisk /dev/disk2
:
$ sudo fdisk /dev/disk2
Disk: /dev/disk2 geometry: 15567/255/63 [250085376 sectors]
Signature: 0xAA55
Starting Ending
#: id cyl hd sec - cyl hd sec [start - size]
-------------------------------------------------------------------
1: 0C 0 130 3 - 5 249 31 [ 8192 - 87851] Win95 FAT32L
2: 83 6 30 25 - 219 68 41 [98304 - 3424256] Linux files*
3: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
4: 00 0 0 0 - 0 0 0 [ 0 - 0] unused
I our case, the last partition starts at block 98304 and is 3424256 blocks big. That means the last used block of our SD card is 3522560 (98304+3424256).
To copy only the used part of our SD card to a file, use dd
:
sudo dd if=/dev/disk2 of=image.img bs=512 count=3522561
Note that we added 1 to the last used block to be on the safe side. Set bs
to the block size you found earlier.
You should now have a small image (image.img) which you can further zip:
zip -r image.zip image.img
In my case, this resulted in a file of 483 MB, similar to the size of original Raspbian image.
That’s it. Now you can easily flash the image to any SD card larger than 483 MB (which equals 99% of the SD cards in the world I guess).