14

I've been trying to create a new Raspbian image with a different kernel (with CAN support) and with Python 3.3 installed. Rather than doing all of this on the Raspberry Pi, I thought it would be interesting to do it on the computer instead (following these instructions). However, once I'd got the image mounted and ready to go, I quickly ran out of disk space. I presume this is because the image is sized to be only just big enough with the expectation that the user will resize the file-system once it has been written to an SD card.

Is it possible to resize the image and file-system before writing it to the SD card so that I can do more customisation without running out of space?

2
  • This question will probably help you.
    – Jivings
    Commented Feb 12, 2013 at 8:32
  • 1
    @Jivings: all of these answers describe how to resize the image after it has been written to the SD card. I know how to do that; I'm interested in how to resize the image before writing it to the SD card.
    – DrAl
    Commented Feb 12, 2013 at 8:41

4 Answers 4

8

This is how to resize a raw image file. I know it sounds stupidly simplistic, but it will work.

Create a blank image, of the size you want to expand the original (in my example I use 5GB);

dd if=/dev/zero of=/path/to/temp_image bs=1 count=1 seek=5G

Append this to the original image:

cat /path/to/temp_image >> /path/to/rasperrypi.img

Resize the filesystem that lives at the end of the disk (usually this is the one you want bigger):

resize2fs -f /path/to/rasperrypi.img

Done! Your disk should now be 5GB bigger!

7
  • That sounds perfect, thank you: I'll test this tonight.
    – DrAl
    Commented Feb 12, 2013 at 11:46
  • 5
    I've just tried this and when I get to the resize2fs stage (after adding 1GB to the file), I get "Bad magic number in super-block while trying to open 2012-12-16-wheezy-raspbian.img Couldn't find valid filesystem superblock." Any suggestions as to what I'm doing wrong?
    – DrAl
    Commented Feb 12, 2013 at 19:04
  • It looks to me like it's an issue with the fact I'm trying to resize2fs the whole image (the equivalent of /dev/sda) instead of the partition (the equivalent of /dev/sda2). However, I could be wrong and I've tried a few other things without success (like resizing the partition with fdisk, which seems to work but doesn't help me resize the file system).
    – DrAl
    Commented Feb 12, 2013 at 19:11
  • 3
    Okay, I've found the answer to the last bit with a bit of googling: I needed to create a loop device pointing to the partition in the image. I did this by getting the start sector of the second partition from fdisk -l file.img (it was 122880) and then losetup --offset $((122880 * 512)) /dev/loop0 file.img. I could then use resize2fs on /dev/loop0 and tidy up with losetup -d /dev/loop0. If you update your answer to include this, I'll mark it as the accepted answer. Thanks for pointing me in the right direction.
    – DrAl
    Commented Feb 12, 2013 at 19:38
  • 1
    @DrAl Hey, I tried your solution using resize2fs on /dev/loop0 but got I get a kernel panic at boot saying the superblock size and partition size don't match: The filesystem size (according to the superblock) is 483840 blocks The physical size of the device is 458240 blocks Have you come across something like this?
    – GuySoft
    Commented Aug 14, 2013 at 0:05
8

This is a synthesis of the answers above and elsewhere that worked for me - back up your image in case you make a mistake:

Firstly make the image file bigger (here we're adding 1GB to the end):

truncate -s +1G ./image.img

Next map the whole image as a loop device so we can poke at the partition table

sudo losetup /dev/loop0 ./image.img

For future reference lets dump it:

sudo fdisk -l /dev/loop0

Output looks like:

Disk /dev/loop0: 2962 MB, 2962227200 bytes
255 heads, 63 sectors/track, 360 cylinders, total 5785600 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: 0x000c4661

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/loop0p2          122880     5785599     2831360   83  Linux

Now we'll remake the last partition by deleting it, then recreating it at the same start location, same type but different end location. So make note of the "Start" column for loop0p2 (partition 2 - the Linux partition) - we'll use it later - its 122880 here.

sudo fdisk /dev/loop0

Enter the following - they are safe to enter - nothing permanent happens until you've read my explanation that follows:

  1. p
  2. d
  3. 2
  4. n
  5. p
  6. 2
  7. 122880
  8. just hit enter to accept the default
    
  9. p

Step 1 - print current table. Steps 2-3 - delete partition 2, Steps 4-8 - recreate partition 2 with new end point (default is end of image), Step 9 - print out the new table.

Assuming your newly printed table is identical to the original table except for the End value and Blocks value (ie the size has changed) you're ready to commit.

Enter w to commit your change, then enter q to quit.


Updating here - in 2023:

You can skip this next section on most modern Linux distributions as loop devices support partitions - eg you could simply access /dev/loop0p2 instead of having to map using an offset. eg:

sudo e2fsck -f /dev/loop0p2
sudo resize2fs /dev/loop0

Resumes original text:


You can delete that loopback device, we'll make another for the second partition. Remember the start offset you noted and used above - we'll use it again:

sudo losetup -d /dev/loop0     # delete the old loop setup
sudo losetup -o $((122880*512)) /dev/loop0 ./image.img

That will create a new mapping on /dev/loop0 pointing just at partition 2 - for reference 512 is the sector-size you can see in the first fdisk output.

Now resize the partition to fill the available space:

sudo e2fsck -f /dev/loop0
sudo resize2fs /dev/loop0

Done - now clean up:

sudo losetup -d /dev/loop0
4
  • thanks... the above instructions didn't work for me but this did. I did get some warning when writing the partition table: ``` Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Re-reading the partition table failed.: Invalid argument The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8). ``` I just ignored it and that was fine.
    – StFS
    Commented Mar 18, 2017 at 17:45
  • 1
    Excellent! You are the only one who made the correct answer! Thanks.
    – yushulx
    Commented Jun 23, 2017 at 7:47
  • I don't get the upvotes for the other solutions. Without changing the partition table all other solutions are nonsense. Thanks @Greg. Here s solution script solution of the fdisk call (echo p; echo d; echo 2; echo n; echo p; echo 2; echo $FDISK_START; echo ; echo N; echo p; echo w; echo q) | sudo fdisk /dev/loop0 The N is for Do you want to remove the signature?
    – delijati
    Commented Feb 18, 2021 at 18:20
  • Great, thanks! Important updates: 1) when asked Do you want to remove this signature?, answer N 2) I think resize2fs has to be run before e2fsck
    – chronos
    Commented Dec 21, 2023 at 12:43
4

For the ones who have Oracle VM VirtualBox running it is quite easy.

On a Windows machine the things go as follows:

input.img is here the image which size should be reduced and output.img is the final image - in this example defined to be 7000 MB large.

ECHO "========================================================================="
ECHO "input.img => output.img"

ECHO "========================================================================="

DEL  input.vdi

DEL  output.vdi

DEL  output.img

ECHO "========================================================================="
"C:\Program Files\Oracle\VirtualBox\VBoxManage" convertfromraw input.img input.vdi -format VDI --variant Standard

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" createhd --filename output.vdi --size 7000 --format VDI --variant Standard

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" clonehd input.vdi output.vdi --existing

ECHO =========================================================================
"C:\Program Files\Oracle\VirtualBox\VBoxManage" clonehd output.vdi output.img --format RAW

Hope this helps a bit.

3
  • Thanks for this solution, very crafty. It's the only one I've been able to find that is free and works perfectly on Windows. I had some issues with 16GB cards that were not quite the same size and needed to resize my image.
    – Josh
    Commented Feb 17, 2017 at 10:41
  • I got kernel panic error. Kernel panic - not syncing: VFS: Unable to mount rootfs on unknown-block(179,2)
    – JPX
    Commented Apr 19, 2017 at 7:38
  • 1
    Note this is truncating the image - you'll lose data if there is any past the 7000MB mark - the commands won't warn or complain. Commented Jun 5, 2017 at 15:22
2

This is how to resize a raw image file. I know it sounds stupidly simplistic, but it will work.

Create a blank image, of the size you want to expand the original (in my example I use 5GB);

dd if=/dev/zero of=/path/to/temp_image bs=1 count=1 seek=5G

Append this to the original image:

cat /path/to/temp_image >> /path/to/rpi.img

Next is resizing the partition and filesystem. First, get the offset of the partition;

fdisk -l /path/to/rpi.img

Results in a table like this:

Device    Boot   Start      End   Sectors   Size  Id  Type
rpi.img1          8192   122879    114688    56M   c  W95 FAT32 (LBA)
rpi.img2       1122880  8447999   8325120     4G  83  Linux

Note the start offset of the second partition

losetup --offset $((122880 * 512)) /dev/loop0 /path/to/rpi.img
e2fsck -f /dev/loop0
resize2fs -f /dev/loop0

Lastly unmount /dev/loop

losetup -d /dev/loop0

Done! Your disk should now be 5GB bigger!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.