Linux/GParted can see partition table but dd bs=512 count=1 can’t

ddgpartedmbrpartition

I have an MBR formatted sd card and when connect to a Linux machine (xubuntu 12.04) it can mount a partition and parse the file system (as can GParted). However, when I try to read the MBR from the device using dd it gives me a bunch of spurious data.

Could anyone shed any light into how Linux/GParted is able to read and make sense of the MBR when dd isn't able to read the MBR. Do they use different methods to get at the data? I.E not open(), read()

DD command is:

dd if=/dev/sdb of=mbr.bin bs=512 count=1

DD output is:

1+0 records in
1+0 records out
512 bytes transferred in 0.000786 secs (651345 bytes/sec)

mbr.bin dump with hexdump -C mbr.bin is:

00000000  04 16 41 53 4d 49 2d 53  44 03 00 00 00 00 16 f1  |..ASMI-SD.......|
00000010  00 7f 00 32 1f 5b 80 00  36 db bf bf 96 c0 00 01  |...2.[..6.......|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  6f 00 00 10 00 00 02 2e  00 00 00 00 00 00 00 00  |o...............|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200

Best Answer

The card does not have a Master Boot Record (MBR). If it had your hexdump would have given you at least one partition entry at offset 0x1C0 and 55aa at the end.

Not all partition tables lay out data in the first 512 bytes. The spurious data you see is SID and CSD register of (a / the) SD card. But from the looks of it, it is not the correct data for the card (unless it is an old 1 MiB 2001 model.)

First 16 bytes are:

CID Register:
----------------------------------------------------------------------------
Manufacturer ID       (MID): 04               => (Transcend)
OEM/Application ID    (OID): 16 41            =  ?A
Product name          (PNM): 53 4d 49 2d 53   =  SMI-S
Product revision      (PRV): 44               =  0100 0100 => 4.4
Product serial number (PSN): 03 00 00 00
reserved               (-) : 00 >> 4          = 0000b
Manufacturing date    (MDT): (00 & 0x0f)|0x16 = 0001b,0110b => 2000+1,6=> Jun 2001
CRC7 checksum         (CRC): 1f >> 1          = 120
always 1               (1) : 1f & 1           = 1

Next 16 bytes (at least part of it):

CSD Register:
----------------------------------------------------------------------------
CSD Structure        (CSD_STRUCTURE): 00 >> 6  = 00b => CSD Version 1.0
reserved                         (-): 00 & 3f  = 00 0000b
Data read access time 1       (TAAC): 7f = 1111b => time val 8.0, 111b => 7=10ms
Data read access time 2       (NSAC): 00
Max. data transfer rate (TRAN_SPEED): 32 = 0110,010 time val 2.5, 2=10Mbit/s 25MHz
Card command classes           (CCC): 1f << 4 | 5b >> 4 = 0x1f5

...
Device size (C_SIZE) : (0x80 & 0x03) << 0xa | 00h | 36 >> 6 : 0

Max. read  current @VDD min (VDD_R_CURR_MIN) : 110 => 60mA
Max. read  current @VDD max (VDD_R_CURR_MAX) : 110 => 80mA
Max. write current @VDD min (VDD_W_CURR_MIN) : 110 => 60mA
Max. write current @VDD max (VDD_W_CURR_MAX) : 110 => 80mA
Device size multiplier         (C_SIZE_MULT) : 111 => 2^(7 + 2) = 512
Erase single block enable     (ERASE_BLK_EN) : 0
Erase sector size              (SECTOR_SIZE) : 1111111 => 127 + 1 = 128
Write protect group size       (WP_GRP_SIZE) : 0111111 =>  63 + 1 = 64

MULT      = 2^(C_SIZE_MULT + 2)  = 2^(7 + 2) = 512
BLOCKNR   = (C_SIZE + 1) * MULT  = 1 * 512   = 512
BLOCK_LEN = 2^READ_BL_LEN        = 2^11      = 2048

memory capacity = 
BLOCKNR * BLOCK_LEN = 512 * 2048 = 1048576 bytes = 1024 KiB = 1 MiB

Also, the CRC7 check for CSD register is wrong. It could be old data left from a pastime.

Those registers and more can be queried from the card directly by various commands. This is done by module drivers, card hubs, etc.


Would be interesting to see what you find by the commands given by Stephane Chazelas, slm etc.

Related Question