TIL: dd and fdisk
The day begins with me trying to create a Raspberry Pi image. I had in mind just a default Raspbian installation with nothing extra installed on it. With this I could later on create something else where I don’t need all the python, xorg, LXDE, or other rubbish that comes with the default Raspbian Wheezy image. No, I’m not saying those pieces of software are really rubbish. I just might not need them in every project.
So I take my 16 GB Kingston SD-card and start installing the Raspbian. I didn’t watch the clock but the installation took about two hours. There’s a lot of waiting in it, so I could happily do other things and once in a while press a “Yes” or something like that. I made the image with 768 MB root partition, because I knew that I could grow that partition bigger depending on how big SD card I would some day put this image on.
When all was done, I took my Win32DiskImager and backed up the image I was working on. After this was done, I noticed that the image size was 16 GB, regardless of the fact that the last 15 GB of the disk was unallocated space! I know I could just gzip the image after taking it and it would compress somewhere near the 1 GB, but I didn’t want to do that. I was sure there was another option, since other people have done images in less than 1 GB. What I wanted in the image was all of the partitions and not the unallocated space.
I tried dd with default settings, nothing, Still 16 GB image. A bit of googling did tell me that dd had an operand called “count” which told the dd that it should clone only a certain part of the disk. I was still a bit unsure how to calculate the amount I should put on the count variable. I sure could put an “1 GB and maybe some extra, just in case” but I wanted to be sure. Finally with trial and error, I found the golden solution. It has to do with sector size and end cylinder, which both could be found using the fdisk tool.
So my fdisk looks like this:
$ fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 15.9 GB, 15896412160 bytes 4 heads, 16 sectors/track, 485120 cylinders, total 31047680 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 Disk identifier: 0x0000f87b Device Boot Start End Blocks Id System /dev/mmcblk0p1 * 2048 155647 76800 b W95 FAT32 /dev/mmcblk0p2 155648 655359 249856 82 Linux swap / Solaris /dev/mmcblk0p3 655360 2154495 749568 83 Linux
So there’s two numbers here we need. One of them is the sector size of the disk and another is the end cylinder of the last partition. If we give these two parameters to the dd, everything should work out. dd takes the parameters like this:
$ dd if=<the sd-card> of=<image file> bs=<sector size> count=<end cylinder>
So what I did was:
$ dd if=/dev/mmcblk0 of=/mnt/usb/raspisa-stage0-2.img bs=512 count=2154495
2154495+0 records in 2154495+0 records out 1103101440 bytes (1.1 GB) copied, 285.682 s, 3.9 MB/s
It seems that with a bit of a struggle, we found an elegant solution of cloning just the needed part of the SD card! Yay!