要切割的大文件为DGJD,共98336321字节,则:
dd if=dgjd of=zz1 bs=1 count=20000000
dd if=dgjd of=zz2 bs=1 count=20000000 skip=20000000
dd if=dgjd of=zz3 bs=1 count=20000000 skip=40000000
dd if=dgjd of=zz4 bs=1 count=20000000 skip=60000000
dd if=dgjd of=zz5 bs=1 count=18336321 skip=80000000
其中IF(INPUT FILENAME)是要切割的大文件名,OF(OUTPUT FILENAME)是切割后的子文件名,BS是指明以多少字节作为一个切割记录单位,COUNT是要切割的单位记录数,SKIP是说明切割时的起点,单位同样以BS设定值为准。通过上述五条指令就将DGJD大文件切割成为4个2千万字节、1个18336321字节的子文件。要注意的是SKIP的值不能错。 由此
也不难看出,DD切割是“非损耗”式的切割,并且支持从任意位置开始的任意大小的切割。
要将生成的ZZ1、ZZ2、ZZ3、ZZ4四个子文件组装为XDGJD,则:
dd if=zz1 of=xdgjd bs=1 count=20000000
dd if=zz2 of=xdgjd bs=1 count=20000000 seek=20000000
dd if=zz3 of=xdgjd bs=1 count=20000000 seek=40000000
dd if=zz4 of=xdgjd bs=1 count=20000000 seek=60000000
dd if=zz5 of=xdgjd bs=1 count=18336321 seek=80000000
其中SKIP参数改为SEEK参数,指明组装的新大文件XDGJD每次的开始位置是从文件头开始多少字节。如果缺省,则组装从文件头开始,显然这不是我们每次都希望的, 所以需用SEEK参数明确指出开始位置。通过以上5个指令,即可将5个子文件重新组装为一个大文件。
要用skip 和seek两个参数
读取的skip
选项和写入的seek
选项都是以块为单位, 输入和输出的默认块大小(bs
)为512字节
seek=N skip N obs-sized blocks at start of output
skip=N skip N ibs-sized blocks at start of input
替换文件前面512字节内容:
dd if=a of=b bs=512 count=1 conv=notrunc
notrunc
do not truncate the output file
notrunc代表不截断输出文件的内容
dd的单位:
N and BYTES may be followed by the following multiplicative suffixes: c =1, w =2, b =512, kB =1000, K =1024, MB =1000*1000, M =1024*1024, xM =M GB =1000*1000*1000, G =1024*1024*1024, and so on for T, P, E, Z, Y.
任何数字后缀上加上b
“乘以512”(0x200)和K
“乘以1024”(0x400)
例如:
lzm@compilere:~$ dd if=/dev/zero of=testdd bs=2b count=1
1+0 records in
1+0 records out
1024 bytes (1.0 kB) copied, 0.000260301 s, 3.9 MB/s
在块大小和计数参数中,一些实现也可以使用x
表示乘运算。 所以不要认为是十六进制!!!
例如,块大小bs=2x80x18b
表示2 × 80 × 18 × 512 = 1474560字节
lzm@compilere:~$ dd if=/dev/zero of=testdd bs=2x1024 count=1
1+0 records in
1+0 records out
2048 bytes (2.0 kB) copied, 0.000251264 s, 8.2 MB/s
如果要十六进制的偏移
使用外壳程序的算术替换(bash和其他符合Posix的外壳程序以及某些非Posix外壳程序都可以使用)。Shell确实可以理解十六进制数,并且它允许以常规方式编写的所有算术运算符。您只需要在表达式周围加上$((...))
:
# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))
十六进制的 0xb0000 = 720896
lzm@compilere:~$ echo $((0xb0000))
720896
lzm@compilere:~$ echo $((0xB0000))
720896
大小写都能认识,没问题!!!
还能做加减法
lzm@compilere:~$ echo $((0x130000-0xB0000))
524288
重点来了
替换flash镜像特定位置内容,这里是logo分区
空间划分如下:
Creating 12 MTD partitions on "RtkSFC":
0x000000000000-0x000000020000 : "factory"
0x000000020000-0x0000000b0000 : "uboot"
0x0000000b0000-0x000000130000 : "logo"
0x000000130000-0x0000002b0000 : "afw"
0x0000002b0000-0x0000002c0000 : "dtb"
0x0000002c0000-0x000000600000 : "kernel"
0x000000600000-0x000000e00000 : "initrd"
0x000000e00000-0x000000e10000 : "art"
0x000000e10000-0x000000e20000 : "dtb_bak"
0x000000e20000-0x000001160000 : "kernel_bak"
0x000001160000-0x000001960000 : "initrd_bak"
0x000001960000-0x000001df4000 : "oem"
0x000000000000-0x000002000000 : "disc"
有了上面的铺垫,就很简单了
dd if=openwrt-rtd1295-nas_spi-rtk-spi-8M-initrd-logo.bin bs=1 count=$((0x130000-0xb0000)) of=NAS1000-FLASH-V1.00-20210107.bin seek=$((0xb0000)) conv=notrunc
dd if=openwrt-rtd1295-nas_spi-rtk-spi-8M-initrd-logo.bin bs=1 count=$((0x130000-0xb0000)) of=EVS8000-FLASH-V1.00-20210107.bin seek=$((0xb0000)) conv=notrunc
524288+0 records in
524288+0 records out
524288 bytes (524 kB, 512 KiB) copied, 5.05487 s, 104 kB/s
参考: