I run in to similar problem, I had a backup image with older kernel and needed to restore it so that I could troubleshoot ALSA issues.
The problem was that the other 4GB SD cards that I have were slightly smaller than the one from which the image backup was made.
The original card had size of 3965MB and spare cards that I have were 3963MB or 3904MB respectively.
So clearly, writing the backup image to either one of these cards would result in a corrupted file system.
Here is how I solved this problem.
First, create a copy of your backup image to play with
In my case:
Searching google I found that image files can be mounted as a block devices using losetup command:
Code: Select all
sudo losetup -f --show test.img
/dev/loop1
Let's see what we got:
Code: Select all
sudo fdisk -l /dev/loop1
Disk /dev/loop1: 3965 MB, 3965190144 bytes
255 heads, 63 sectors/track, 482 cylinders, total 7744512 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: 0x000714e9
Device Boot Start End Blocks Id System
/dev/loop1p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/loop1p2 122880 7744511 3810816 83 Linux
As you can see, this image is 3965MB and 7744512 sectors (512b x 7744512 = 3965190144b)
Also geometry of the card is important to note, 255 heads and 63 sectors.
The last sector of the last partition is Total sectors - 1, so there is no spare room left on the card.
Now, let's have a look at the target SD card
Code: Select all
sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 3963 MB, 3963617280 bytes
128 heads, 63 sectors/track, 960 cylinders, total 7741440 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: 0x00000000
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 7741439 3866624 6 FAT16
The target SD card is 3963MB and 7741440 sectors, so it is smaller than the image by 3072 sectors or 1572864b. Also note the geometry of the card showing 128 heads and 63 sector. For some reason this is incorrect as this card has 255 heads and 63 sectors. For some reason fdisk does not show this always correctly. At another occasion, it showed this card with 4 heads and 16 sectors. Not sure why...
We need to shrink second partition of the image, otherwise if we attempt to write image to the card, it will result in a corrupted file system
let's mount the second partition of the image as a loopback device so that we can resize it
image starts at sector 122880, which is 512*122880=62914560b
Now that we have the offset for mounting the second partition of the image,
we can now use with losetup’s -o argument to set an offset
Code: Select all
sudo losetup -f --show -o 62914560 test.img
/dev/loop2
scan for errors before resizing the image
Code: Select all
sudo e2fsck -f /dev/loop2
e2fsck 1.42 (29-Nov-2011)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop2: 80300/245760 files (0.2% non-contiguous), 604445/952704 blocks
using resize2fs we can shrink the partition, using -p option to show progress and specifing new size which is
slightly smaller than the new SD card
-p Prints out a percentage completion bars for each resize2fs operation, so that the user can keep track of what the program is doing.
size parameter may be suffixed by one of the following the units designators: 's', 'K', 'M', or 'G', for 512 byte sectors, kilobytes, megabytes, or gigabytes, respectively.
We need to scale dovwn the image by 3072 sectors, lets go with 4096 sectors just to be sure. Image size is End - Start = 7744512 - 122880 = 7621632 sectors, substracting 4096 sectors, the new size is 7621632 - 4096 = 7617536 sectors
Code: Select all
sudo resize2fs -p /dev/loop2 7617536s
Resizing the filesystem on /dev/loop2 to 952192 (4k) blocks.
The filesystem on /dev/loop2 is now 952192 blocks long.
Now that the filesystem was resized, loopback devices are no needed anymore:
Code: Select all
sudo losetup -d /dev/loop1 /dev/loop2
To write the modified image to the SD card, use command:
(this may take a while, depending on the speed of your card, in my case it took more than 30 minutes)
Code: Select all
sudo dd if=test.img of=/dev/mmcblk0
dd: writing to `/dev/mmcblk0': No space left on device
7741441+0 records in
7741440+0 records out
3963617280 bytes (4.0 GB) copied, 1908.13 s, 2.1 MB/s
As you can see, there is an error message 'No space left on the device', but because we re-sized the file system, card will be useable and Raspberry Pi will boot up without any issues.
However, if you attempt to look at the partition(s) on the card with a tool such us parted or gparted, it will end up with an error "...partition extends beyond end of device..."
To correct this, we need to modify MBR (Master Boot Record) of the SD card.
First, we will extract the first sector from the card which contains MBR
Code: Select all
dd if=/dev/mmcblk0 of=sd.mbr bs=512 count=1
This will create a file sd.mbr which we will need to edit with a hex editor (I did this on my laptop using Ubuntu 12.04LTS Live CD and tried GHex and Bless Hex editors, I liked Bless Hex better, but that's just my preference).
To play with the MBR in the hex editor, you need to know what values at which address need to be modified, Wikipedia has very good reference material about MBR.
http://en.wikipedia.org/wiki/Master_boot_record
From there you can see that Partition entry #1 starts at address 0x1BE and Partition entry #2 starts at address 0x1CE.
Layout of the partition entry is described here
http://en.wikipedia.org/wiki/Master_boot_record#PTE
Values for the CHS address of last absolute sector in partition, LBA of first absolute sector in the partition and number of sectors in partition need to be calculated and changed.
I can explain this in more detail if someone is interested.
Once MBR was modified, it can be written back to the sd card
Code: Select all
dd if=sd.mbr of=/dev/mmcblk0 bs=512 count=1
running:
Code: Select all
sudo fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 3963 MB, 3963617280 bytes
4 heads, 16 sectors/track, 120960 cylinders, total 7741440 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: 0x000714e9
Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 7741439 3809280 83 Linux
We can see that the end sector of last partition is less than total number of sectors.
If we run now parted or gparted, the card partitions will be recognized and can be further manipulated by using these tools.
I hope this helps to someone
Cheers,
Roman