Dd, seek with one block size, write with another block size

dddisksd card

Background Info:

  • Copying some .bin files to an SD card (to be read by an embedded device, no filesystem)
  • Commissioning the card requires some segments to be wiped (i.e. zero'd), and others to have binary files copied to them
  • Calling dd from a python script using subprocess module (as the dd operations involved are triggered by a sort of configuration script that needs to be parsed and validated first, I also make the user confirm the operation, as they might wipe out an important disk that is mistaken for the SD card)

Problem:

Writes to the SD card are slow with bs=512. For large spans, bs=8M is much faster.

Is it possible to somehow 'bs=512 seek={n_small_blocks}' and then change to 'bs=8M' for the actual write (once I've seek'd to the correct position)?

I found the following resource:
http://www.delorie.com/gnu/docs/textutils/coreutils_65.html

But it's not clear to me why 2 invocations are required, and how they're working together to accomplish what the guide claims they will.


UPDATE

Found the answer here:

https://superuser.com/questions/380717/how-to-output-file-from-the-specified-offset-but-not-dd-bs-1-skip-n

See my full solution below

Best Answer

Solution:

dd if='input_file.bin'           \
   of='/dev/sd{X}'               \
   bs={desired write block size} \
   seek={start offset in bytes}  \
   count={write size in bytes}   \
   oflag=seek_bytes              \
   iflag=count_bytes

From the man page:

count_bytes
    treat 'count=N' as a byte count (iflag only)

...

seek_bytes
    treat 'seek=N' as a byte count (oflag only)

This does seem to slow down the transfer a bit, but at least puts it in MB/s, instead of kB/s. Also, be sure to check the man page on your system, as it seems the ones available on the web (i.e. googling 'man dd') don't include these options.

Related Question