Creating a Custom Shrinked Raspberry Pi Image

by hoffma0901 in Circuits > Raspberry Pi

14920 Views, 38 Favorites, 0 Comments

Creating a Custom Shrinked Raspberry Pi Image

Unbenannt.JPG

Hey guys,

this is my first instructable, I hope you like it! Please be patient with me, english isn't my motherlanguage.

Since I've started doing stuff with the Raspberry Pi, I've always backed up my sd cards. It's nice to have a backup, but in case you use very big sd cards (> 8 Gb) the backups will fill the same amount on your hard drive.

So how do you shrink those big backups?

First of all you could pack them into an archive. Hmm ok, but what if you want to use this image on a smaller sd card?

Now I want to show you a way, where you can create your own custom .img-files. Like the ones you can download from the Pi Foundation.

You will need:

  • a (micro) sd-card with preinstalled and costumized raspbian and a sd-card reader of course
  • a computer with a linux-distro (I'm using a Ubuntu Mate Live DVD, so you don't need to install a new os if you have a windows pc)
  • enough free disk space (at least 1,5*sd-card size)
  • gparted (if you don't have it already installed, install it with "sudo apt-get install gparted")

WARNING!

Tools like gParte d and fdisk can erase your whole data if you use it wrong, read carefully and read twice before you click any fancy buttons!

I'm not responsible for any kind of dataloss you may experience as a result of false usage!

You may have to adjust some of the values or paths according to your custom image and your Linux machine/hard drives.

Please note: the paths in the description and in the pictures are diffrent!

But now, let's start

Preparation

auswahlsdkarte.png
sdd1_sektoren.png
resize.png
sdd2_sektoren.png
new_partitions.png

First of all, shutdown your Raspberry, unplug it and remove the sd-card.

Every next step will take place on a Linux-PC (or Linux Live System).

Please don't use your Raspberry Pi for the next steps! I tried it several times and always failed.

Boot your Linux machine, fire up a console window and start gparted with

sudo gparted

Now plug in your sd-card reader (with the sd-card of course) und refresh the gparted device list (CTRL+R).

Choose your sd-card in the top-right dropdown menu. Note the device path for later use (e.g. /dev/sdd). In the next steps we will shrink the main data partition. It will save us a lot of time for the next steps. So

  • right click on the available ext4 partition in the list
  • select Resize/Move
  • In the Resize/Move window drag and drop the partition to the desired size or just enter the new size manually. In my case its 4096MiB
  • Hit Resize/Move and the "Apply All Operations"-button

gParted will now resize your partition.

For further steps please note the specific data of the partitions:

  • right click on the partition sdd1 in the list and click on "Information"
  • note the size, First sector, Last sector and Total Sectors
  • repeat the steps for partition sdd2

For example:

/dev/sdd1

Size: 63.00MiB
First sector: 8192
Last sector: 137215
Total sectors: 129024

/dev/sdd2

Size: 4.00 GiB
First sector: 137216
Last sector: 8525823
Total sectors: 8388608

Now you got a resized partition and some important values for the next steps.

Save Your Data

backup_process.png
dd_ready.png

In this step we will create a complete backup of the sd card.

Wait, you said we want to create a smaller one!?

That's correct, but before we can shrink our backup, we need a backup that we can shrink.

So fire up a new console window and type:

su root 

(type in the root password, if haven't created one yet, type "sudo passwd" und set a root password)
(su without 'root' will also work)

If you want to create the backup on an external device you have to mount it first. If you use a Linux live system and want to backup on the internal (windows) hard drive you have to mount it as well.

First crate a mount point:

mkdir -p /mnt/backup

Get your backup target device name with gParted:

  • refresh with CTRL+R
  • identify your hard drive with the device drop-down menu, you used in step 1 and the known size.Choose it and note the device path to the desired partition (e.g. /dev/sda1).

Mount your backup hard drive:

mount /dev/sda1 /mnt/backup

Your backup space can now be reached at /mnt/backup.

Lets start and make the backup already!

dd if=/dev/sdd of=/mnt/backup/rpi.img bs=1M

This command copies the entire sd-card to our backup hard drive and creates an image file as big as the sd-card.

Please be patient, the process can take a long time! Grab a Coffee or better a beer, maybe two...

Create a Custom Image

fdisk_info.png
empty_image.png

Finally we can start creating a custom image.

For this we create one image disk with the same properties like the backup image, but a diffrent size.

Remember the strange numbers, like sectors you should note? Now we need them!

Just to be sure we use the fdisk tool to obtain the specific data of the created backup image:

fdisk -l -u=cylinders /mnt/backup/rpi.img

The output should look like this:

Disk /mnt/backup/rpi.img: 58.2 GiB, 62537072640 bytes, 122142720 sectors
255heads, 63 sectors/track, ... cylinders, ...
Units = sectors of 1 * 512 bytes = 512 bytes

And so on ...

For the next steps we need (those should be identic for every sd card, but to be sure look it up!):

  1. heads = 255
  2. sectors/track = 63
  3. Units = 512 bytes

Now we have to do some math. Don't panick it's quite simple.

heads*sectors/track*Units = bytes per cylinder

255*63*512 = 8225280 => Note this value, it is important!

The structure of the image is the following:

4 MB unallocatet space for the master boot record (mbr)

63MB fat32 boot partition

4096MB for the data partition

Sum this space up and you will get 4163MB

With this information we can calculate the numbers of cylinder we need.

Its just (imagesize in bytes)/(bytes per cylinder) = cylinders

the imagesize is 4163 MB, to convert it into bytes we multiply this term twice by 1024.

4163*1024*1024 = 4365221888 => 4365221888 bytes

(imagesize in bytes)/(bytes per cylinder) = cylinders

4365221888/8225280 = 530,71 => 531 cylinder

Now create the empty image by:

dd if=/dev/zero of=/mnt/backup/5gb.img bs=8225280 count=531

The result is a whole new empty image with the size of 4163MB

Step: Create Partitions

fdisk_part.png

The created image has got no partions or anything else in it. So lets create some partitions... Yay!

fdisk -u -C531 -S63 -H255 /mnt/backup/5gb.img

Now the tool fdisk creates a new boottable und asks you for further actions. Now you need the sector data you got out of gparted.

Command (m for help): n
Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1):1 Using default value 1 First sector (2048-6425999, default 2048): 8192 Last sector, +sectors or +size{K,M,G} (8192-6425999, default 6425999): 137215 Command (m for help): t Selected partition 1 Hex code (type L to list codes): c Changed system type of partition 1 to c (W95 FAT32 (LBA)) You've just created the first boot partition. Now the data partition: Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) e extended Select (default p): p Partition number (1-4, default 2):2 Using default value 2 First sector (2048-6425999, default 2048): 137216 Last sector, +sectors or +size{K,M,G} (122880-6425999, default 6425999): 8525823 Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): 83

Just ignore the default sector sizes and use the one you got from gParted!

Now type in "w", hit enter and you are done!

Command (m for help): w
The partition table has been altered! WARNING: If you have created or modified any DOS 6.x partitions, please see the fdisk manual page for additional information. Syncing disks

Copy Your Data

copy_boot.png
copy_ready.png
Screenshot at 2016-07-15 13_42_11.png

Now we've come to part, where you can transfer your data to the blank image.

Just copy the boot data from the boot partition to the new boot partition with:

dd if=/mnt/backup/rpi.img of=/mnt/backup/5gb.img bs=512 count=129024 skip=8192 seek=8192

Explanation:

We skip the first 4MB on the image (mbr!) and start with the block 8192 where our fist partition starts, then we copy the next 129024 sectors and stop at the last sector of the partition (137215).

We do the same thing again but with fixed values for the second partition:

dd if=/mnt/backup/rpi.img of=/mnt/backup/5gb.img bs=512 count=8388608 skip=137216 seek=137216

count => Total sectors

skip & seek => First sector

Done! Now you got a new 4.4 GiB image, you can use with every sd-card > 4GiB.

Copy it on an sd-card like every other image for the Pi and boot it up.

In this description, I've used a 64GiB sd-card. I've tested the new custom image on 16 GiB, 8GiB and 32GiB cards. Everthing worked fine. At first boot, run "sudo raspi-config" and resize the filesystem.

Feel free to use this instructable, change it or sell it. I don't care :D

Inspired by this How-To:german instruction

Changelog:

2016-08-08

Added more pictures, minor corrections

2017-05-20

Code snippets are now displayed as code