5

I have an embedded device which is loosely based around a Olinixino iMX233 design. This has a Freescale iMX233 microprocessor and boots from a socketed 2GB microSD card.

I wish to alter the filesystem, but also backup the filesystem prior to altering it so that I don't brick the device.

To achieve this, I obtained a similar 2GB micro SD card, and cloned the current SD card using dd in a USB card reader:

dd if=/dev/sdc of=HeatmiserSDC.img

then after swapping cards:

dd if=HeatmiserSDC.img of=/dev/sdc

When this new card is placed in the device, it fails to boot.

I have also now tried the sg3_utils utility sg_dd which operates at a slightly lower level. This has produced a slightly different image file but still won't boot.

I have also now used a SD to micro SD adapter in a direct SD card interface (/dev/mmcblk0) in a Thinkpad x220. This also failed to boot.

The serial console produces a single error code when it fails to boot, 0x8020a007, which doesn't provide much useful during a Google search.

I have tried multiple cards, including some 4GB cards. This doesn't seem to be a space issue - sometimes one 2GB SD card is slightly smaller than another. The board also seems to be using the SD protocol and not the SPI protocol. The SPI protocol is sometimes not very reliable on newer cards.

fsutil -l produces the following output:

Disk /dev/sdc: 1996 MB, 1996488704 bytes
8 heads, 7 sectors/track, 69632 cylinders, total 3899392 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: 0x0f6c2d46

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            2048       32000       14976+  53  OnTrack DM6 Aux3
/dev/sdc2           32001      200000       84000   83  Linux
/dev/sdc3          200001      400000      100000   83  Linux
/dev/sdc4          400001     3899391     1749695+  83  Linux

Is there something I am missing here? Some data that isn't copied as part of dd?

4

Micro SD cards have a card identification register (CID) that can be read from the card. The CID contains, among other things, the product serial number and manufacturing date, which are different between cards.

Your firmware might be specific to a certain CID as a form of copy protection.

This blog post is about reading the CID on a iMX233 running Linux and using it as a copy protection mechanism.

4

After some searching, it seems that the boot process on the iMX233 is fairly non-standard. By default it looks for a "Boot Control Block" (BCB) in the last block of the SD card.

Examining the original SD card, find the last block using fdisk -l:

Disk /dev/mmcblk0: 1996 MB, 1996488704 bytes
4 heads, 16 sectors/track, 60928 cylinders, total 3899392 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: 0x0f6c2d46

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            2048       32000       14976+  53  OnTrack DM6 Aux3
/dev/mmcblk0p2           32001      200000       84000   83  Linux
/dev/mmcblk0p3          200001      400000      100000   83  Linux
/dev/mmcblk0p4          400001     3899391     1749695+  83  Linux

There are 3899392 sectors.

Examine the last sector of the SD card using dd:

root@kali:~# dd if=/dev/mmcblk0 bs=512 count=1 skip=3899391 2> /dev/null | hexdump -C
00000000  33 22 11 00 01 00 00 00  04 00 00 00 04 00 00 00  |3"..............|
00000010  04 00 00 00 04 08 00 00  50 00 00 00 50 00 00 00  |........P...P...|
00000020  50 00 00 00 50 00 00 00  ef be ad de 00 00 00 00  |P...P...........|
00000030  01 00 00 00 02 00 00 00  03 00 00 00 04 00 00 00  |................|
00000040  05 00 00 00 06 00 00 00  07 00 00 00 08 00 00 00  |................|
00000050  09 00 00 00 0d 0a 00 00  00 0b 00 00 00 0c 00 00  |................|
00000060  00 0d 00 00 00 0e 00 00  00 0f 00 00 00 10 00 00  |................|
00000070  00 11 00 00 00 12 00 00  00 13 00 00 00 14 00 00  |................|
00000080  00 15 00 00 00 16 00 00  00 17 00 00 00 18 00 00  |................|
00000090  00 19 00 00 00 1a 00 00  00 1b 00 00 00 1c 00 00  |................|
000000a0  00 1d 00 00 00 1e 00 00  00 1f 00 00 00 20 00 00  |............. ..|
000000b0  00 21 00 00 00 22 00 00  00 23 00 00 00 24 00 00  |.!..."...#...$..|
000000c0  00 25 00 00 00 26 00 00  00 27 00 00 00 28 00 00  |.%...&...'...(..|
000000d0  00 29 00 00 00 2a 00 00  00 2b 00 00 00 2c 00 00  |.)...*...+...,..|
000000e0  00 2d 00 00 00 2e 00 00  00 2f 00 00 00 30 00 00  |.-......./...0..|
000000f0  00 31 00 00 00 32 00 00  00 33 00 00 00 34 00 00  |.1...2...3...4..|
00000100  00 35 00 00 00 36 00 00  00 37 00 00 00 38 00 00  |.5...6...7...8..|
00000110  00 39 00 00 00 3a 00 00  00 3b 00 00 00 3c 00 00  |.9...:...;...<..|
00000120  00 3d 00 00 00 3e 00 00  00 3f 00 00 00 40 00 00  |.=...>...?...@..|
00000130  00 41 00 00 00 42 00 00  00 43 00 00 00 44 00 00  |.A...B...C...D..|
00000140  00 45 00 00 00 46 00 00  00 47 00 00 00 48 00 00  |.E...F...G...H..|
00000150  00 49 00 00 00 4a 00 00  00 4b 00 00 00 4c 00 00  |.I...J...K...L..|
00000160  00 4d 00 00 00 4e 00 00  00 4f 00 00 00 50 00 00  |.M...N...O...P..|
00000170  00 51 00 00 00 52 00 00  00 53 00 00 00 54 00 00  |.Q...R...S...T..|
00000180  00 55 00 00 00 56 00 00  00 57 00 00 00 58 00 00  |.U...V...W...X..|
00000190  00 59 00 00 00 5a 00 00  00 5b 00 00 00 5c 00 00  |.Y...Z...[...\..|
000001a0  00 5d 00 00 00 5e 00 00  00 5f 00 00 00 60 00 00  |.]...^..._...`..|
000001b0  00 61 00 00 00 62 00 00  00 63 00 00 00 64 00 00  |.a...b...c...d..|
000001c0  00 65 00 00 00 66 00 00  00 67 00 00 00 68 00 00  |.e...f...g...h..|
000001d0  00 69 00 00 00 6a 00 00  00 6b 00 00 00 6c 00 00  |.i...j...k...l..|
000001e0  00 6d 00 00 00 6e 00 00  00 6f 00 00 00 70 00 00  |.m...n...o...p..|
000001f0  00 71 00 00 00 72 00 00  00 73 00 00 00 74 00 00  |.q...r...s...t..|
00000200

The magic number of 0x33221100 is mentioned in some Freescale documentation, though I was expecting to see it with the opposite endianness.

So to make a successful clone, choose a SD card of larger capacity to ensure nothing is overwritten (or you can resize partitions).

Take an image of the original card:

root@kali:~# dd if=/dev/mmcblk0 of=wholeSD.img
3899392+0 records in
3899392+0 records out
1996488704 bytes (2.0 GB) copied, 98.3687 s, 20.3 MB/s

Then take an image of just the last sector for the BCB:

root@kali:~# dd if=/dev/mmcblk0 bs=512 count=1 skip=3899391 of=BCB.img
1+0 records in
1+0 records out
512 bytes (512 B) copied, 0.000220203 s, 2.3 MB/s

Find out how big the new SD card is:

Disk /dev/mmcblk0: 2002 MB, 2002780160 bytes
4 heads, 16 sectors/track, 61120 cylinders, total 3911680 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: 0x0f6c2d46

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            2048       32000       14976+  53  OnTrack DM6 Aux3
/dev/mmcblk0p2           32001      200000       84000   83  Linux
/dev/mmcblk0p3          200001      400000      100000   83  Linux
/dev/mmcblk0p4          400001     3899391     1749695+  83  Linux

This one is larger with 3911680 sectors.

Move the whole card image onto the new card:

root@kali:~# dd if=wholeSD.img of=/dev/mmcblk0
13899392+0 records in
3899392+0 records out
1996488704 bytes (2.0 GB) copied, 1545.45 s, 1.3 MB/s

And then move the BCB image to the last sector of the card:

root@kali:~# dd if=BCB.img bs=512 count=1 seek=3911679 of=/dev/mmcblk0
1+0 records in
1+0 records out
512 bytes (512 B) copied, 8.4684e-05 s, 6.0 MB/s

Note the use of seek (output side) rather than skip (input side).

It is worth double checking that the last block has been written. Several cheap SD cards don't seem to work in the last sectors, possibly because they misreport size.

Now you have a booting card.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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