Preliminary notes:
The title is kinda XY problem. It's good the question body clarifies your specific case. I mean you don't exactly want to "bitwise-OR 2 binary files", arbitrary files. You want to merge two HDD images, one of them was created by ddrescue
.
dd
is not the best tool for reading from faulty devices. conv=sync,noerr
is often advised but it's not enough. Please read this. Unless you also used iflag=fullblock
, the image generated by dd
cannot be trusted. Having ddrescue
I would not use dd
at all. The right way to retry is to run ddrescue
again with the same mapfile.
My answer assumes your image generated by dd
can be trusted.
If you have the mapfile from the ddrescue
run, then use --fill-mode
.
When ddrescue
is invoked with the --fill-mode
option it operates in "fill mode", which is different from the default "rescue mode". That is, if you use the --fill-mode
option, ddrescue
does not rescue anything. It only fills with data read from infile
the blocks of outfile
whose status character from mapfile
coincides with one of the type characters specified as argument to the --fill-mode
option.
(source)
In your case it will be like:
ddrescue --OPTIONS --fill-mode='?*/-' image_from_dd image_from_ddrescue mapfile_from_ddrescue
where ?*/-
mean:
?
non-tried block
*
failed block non-trimmed
/
failed block non-scraped
-
failed block bad-sector(s)
And there's +
you don't want in your command:
+
finished block
--OPTIONS
denotes some options you originally used; options that, if changed, would make the tool misinterpret the mapfile. The set contains --sector-size
for sure. Hint: the original command line may be stored in the mapfile as a comment.
If you used --input-position
and/or --output-position
(and/or skip=
and/or seek=
with dd
) then some recalculations are required, I think. Without testing I cannot give you the right formula. You probably did not use these options anyway.
Thanks to --fill-mode
all sectors that are not considered rescued by your original ddrescue
will be filled with data taken from respective fragments of image_from_dd
.
If the mapfile from the original ddrescue
run is unavailable or if you really want to overwrite all sectors filled with zeros (even ones where ddrescue
has actually read zeros without errors), then you should ask ddrescue
to generate a mapfile:
When ddrescue
is invoked with the --generate-mode
option it operates in "generate mode", which is different from the default "rescue mode". That is, if you use the --generate-mode
option, ddrescue
does not rescue anything. It only tries to generate a mapfile for later use.
[…]
ddrescue
can in some cases generate an approximate mapfile
, from infile
and the (partial) copy in outfile
, that is almost as good as an exact mapfile
. It makes this by simply assuming that sectors containing all zeros were not rescued.
[…]
Note that you must keep the original offset between --input-position
and --output-position
of the original rescue run.
(source)
The manual gives this example:
ddrescue --generate-mode infile outfile mapfile
but my tests indicate infile
is only formally checked for existence and general sanity, then it doesn't matter; only outfile
is used to generate mapfile
. So you don't need the original HDD at all, the command may be:
ddrescue --generate-mode /dev/zero image_from_ddrescue new_mapfile
After it finishes you will have the new_mapfile
. Use it with --fill-mode
, like described above (--OPTIONS
should match the relevant options used with --generate-mode
).
Note you can work in the opposite direction: generate a (different) mapfile from image_from_dd
and use --fill-mode
to write parts of image_from_ddrescue
into image_from_dd
.
cmp -l image1 image2
to verify that the only differences are zero-vs-nonzero.