标题: 红米移动版root后刷"CWM Recovery"、备份原始Recovery引发的dd使用疑问 https://scz.617.cn/android/201404091511.txt 一般用"SP Flash Tool"线刷"CWM Recovery",这个跟root无关。已经有root的情况下, 另有办法刷"CWM Recovery"、备份原始Recovery。 假设是红米移动版。将CWM_Recovery.img放到SD卡上,可以: adb push CWM_Recovery.img /storage/sdcard0/downloaded_rom/ 也可以通过U盘模式复制到手机上。接着用dd把这个IMG灌到/dev/recovery即可: adb shell su -c "busybox dd if=/storage/sdcard0/downloaded_rom/CWM_Recovery.img of=/dev/recovery bs=1M count=6 conv=sync" su的用法如下: shell@android:/ $ su -h Usage: su [options] [LOGIN] Options: -c, --command COMMAND pass COMMAND to the invoked shell -h, --help display this help message and exit -v, --version display version number (Compat. with SuperUser) -V display version code (Compat. with SuperUser) -s, --shell SHELL use SHELL instead of the default in passwd 可以在"root shell"下直接用dd: busybox dd if=/storage/sdcard0/downloaded_rom/CWM_Recovery.img of=/dev/recovery bs=1M count=6 conv=sync 写入6MB数据,"conv=sync"意思是单块(block)不足指定大小(本例中是1MB)时,以0填 充补足单块指定大小。 shell@android:/ $ ls -l /storage/sdcard0/downloaded_rom/ ----rwxr-x system sdcard_rw 6125568 2013-12-31 13:08 CWM_Recovery.img ----rwxr-x system sdcard_rw 5601280 2014-03-20 12:00 recovery.img 我用的临时目录是/storage/sdcard0/downloaded_rom/,有人用/data/local/tmp: shell@android:/ $ ls -ld /storage/sdcard0/downloaded_rom/ d---rwxr-x system sdcard_rw 2014-04-09 12:50 shell@android:/ $ ls -ld /data/local/tmp/ drwxrwx--x shell shell 2014-04-09 13:37 线刷包的MT6589_Android_scatter_emmc.txt文件指出: RECOVERY 0x2d80000 { } SEC_RO 0x3380000 { } 卡刷包的scatter.txt文件指出: RECOVERY 0x2d80000 SEC_RO 0x3380000 这意味着留给RECOVERY的空间大小是6MB(6291456): 0x3380000-0x2d80000=0x600000 如果CWM_Recovery.img超出6MB,千万不能用! 受此启发,观察/dev/下可能与IMG相关的设备名(作了裁剪): shell@android:/ $ ls -l /dev/ crw------- root root 253, 0 2014-04-09 11:27 BOOT crw-r----- root system 234, 10 2014-04-09 11:27 bootimg crw------- root root 234, 18 2014-04-09 11:27 cache crw------- root root 234, 2 2014-04-09 11:27 ebr1 crw------- root root 234, 15 2014-04-09 11:27 ebr2 crw------- root root 234, 20 2014-04-09 11:27 fat crw------- root root 234, 1 2014-04-09 11:27 mbr crw-rw---- root system 234, 5 2014-04-09 11:27 nvram crw-r----- root system 234, 0 2014-04-09 11:27 preloader drwxrwx--- radio radio 2014-04-09 11:27 radio crw-r----- root system 234, 11 2014-04-09 11:27 recovery crw------- root root 234, 9 2014-04-09 11:27 uboot 结合scatter信息,可以刷或备份相应IMG。 可以向/dev/recovery写入数据,也可以从/dev/recovery读出数据: busybox dd if=/dev/recovery of=/storage/sdcard0/downloaded_rom/orig_recovery.img bs=1M count=6 conv=sync 用这招在刷"CWM Recovery"之前备份原始Recovery。 细心的读者可能会问,为什么不直接用dd,非要"busybox dd"? shell@android:/ $ ls -l /system/bin/ lrwxrwxrwx root root 2010-01-01 08:02 dd -> toolbox -rwxr-xr-x root shell 134912 2008-08-01 20:00 toolbox shell@android:/ $ ls -l /system/xbin/busybox -rwxr-xr-x root shell 1165484 2008-08-01 20:00 busybox shell@android:/ $ busybox dd -h BusyBox v1.20.2-MIUI (2012-08-20 20:59:32 CST) multi-call binary. Usage: dd [if=FILE] [of=FILE] [ibs=N] [obs=N] [bs=N] [count=N] [skip=N] [seek=N] [conv=notrunc|noerror|sync|fsync] Copy a file with converting and formatting if=FILE Read from FILE instead of stdin of=FILE Write to FILE instead of stdout bs=N Read and write N bytes at a time ibs=N Read N bytes at a time obs=N Write N bytes at a time count=N Copy only N input blocks skip=N Skip N input blocks seek=N Skip N output blocks conv=notrunc Don't truncate output file conv=noerror Continue after read errors conv=sync Pad blocks with zeros conv=fsync Physically write data out before finishing Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024), MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824) 直接dd用的是toolbox,toolbox的dd不支持k、M这种后缀: # dd if=/dev/recovery of=/storage/sdcard0/downloaded_rom/test.img bs=1M count=6 conv=sync 6+0 records in 6+0 records out 6 bytes transferred in 0.001 secs (6000 bytes/sec) # dd if=/dev/recovery of=/storage/sdcard0/downloaded_rom/test.img bs=1anything count=6 conv=sync 6+0 records in 6+0 records out 6 bytes transferred in 0.001 secs (6000 bytes/sec) # ls -l /storage/sdcard0/downloaded_rom/test.img ----rwxr-x system sdcard_rw 6 2014-04-09 12:51 test.img 看见了吧,"bs=1M"和"bs=1anything"实际是"bs=1"。为了直接用(toolbox的)dd, 稍微改一下命令行参数即可(bs=1048576): # dd if=/dev/recovery of=/storage/sdcard0/downloaded_rom/test.img bs=1048576 count=6 conv=sync 6+0 records in 6+0 records out 6291456 bytes transferred in 0.058 secs (108473379 bytes/sec) # ls -l /storage/sdcard0/downloaded_rom/test.img ----rwxr-x system sdcard_rw 6291456 2014-04-09 12:54 test.img test.img与orig_recovery.img完全一样: shell@android:/ $ busybox md5sum /storage/sdcard0/downloaded_rom/orig_recovery.img 51652554ae69d15bd1220e276b1523a8 /storage/sdcard0/downloaded_rom/orig_recovery.img shell@android:/ $ busybox md5sum /storage/sdcard0/downloaded_rom/test.img 51652554ae69d15bd1220e276b1523a8 /storage/sdcard0/downloaded_rom/test.img 关于toolbox的dd实现,参看源码: https://android.googlesource.com/platform/system/core.git/+/master/toolbox/dd.c 它支持的命令行参数其实比busybox的dd多: -------------------------------------------------------------------------- { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, { "cbs", f_cbs, C_CBS, C_CBS }, { "conv", f_conv, 0, 0 }, { "count", f_count, C_COUNT, C_COUNT }, { "files", f_files, C_FILES, C_FILES }, { "ibs", f_ibs, C_IBS, C_BS|C_IBS }, { "if", f_if, C_IF, C_IF }, { "obs", f_obs, C_OBS, C_BS|C_OBS }, { "of", f_of, C_OF, C_OF }, { "progress", f_progress, 0, 0 }, { "seek", f_seek, C_SEEK, C_SEEK }, { "skip", f_skip, C_SKIP, C_SKIP }, -------------------------------------------------------------------------- { "block", C_BLOCK, C_UNBLOCK, NULL }, { "fdatasync", C_FDATASYNC, 0, NULL }, { "noerror", C_NOERROR, 0, NULL }, { "notrunc", C_NOTRUNC, 0, NULL }, { "osync", C_OSYNC, C_BS, NULL }, { "sparse", C_SPARSE, 0, NULL }, { "swab", C_SWAB, 0, NULL }, { "sync", C_SYNC, 0, NULL }, { "unblock", C_UNBLOCK, C_BLOCK, NULL }, --------------------------------------------------------------------------