本文以recovery.img爲例來講解說明,boot.img類似
1、獲取recovery.img
首先將手機root,一般使用360一鍵root或者百度一鍵root,這是一種軟件層面的root,無非是利用android漏洞在/system/app下植入一個superuser.apk來掌管root權限,每次用戶需要root權限時,使用su命令,界面會彈出對話框要求確認。下面還會講到另一種root,把它叫做內核root,也就是default.prop這個文件中兩個屬性值:
ro.secure=0
ro.debuggable=1
內核root之後,adb shell直接是root用戶登錄,而軟件層面root,adb shell依然是shell用戶登錄,必須通過su命令切換到root用戶($ 符號變成#)。
一般我們如果不是手機廠商用戶,剛開始只能是軟件層面的root。
adb shell
su
切換到root用戶後
1)如果是高通芯片的手機,採用以下命令將recovery.img拷貝出來
dd if=/dev/block/platform/msm_sdcc.1/by-name/recovery of=/storage/sdcard/recovery.img
ps:cd /dev/block/platform/msm_sdcc.1/by-name 到這個目錄下ls -al命令可以看到revoery其實是個鏈接文件,鏈接到/dev/block/mmcblk0p16 這個分區塊,因此也可以使用一下命令:
dd if=/dev/block/mmcblk0p16 of=/storage/sdcard/recovery.img
2)如果是MTK芯片的手機
有兩種方式:
dd if=/dev/recovery of=/storage/sdcard/recovery.img bs=1024 count=6144
dd if=/dev/block/mmcblk0 of=/storage/sdcard/recovery.img skip=xxxx bs=1024 count=6144注意:bs的值目前可以固定1024,count的值需要查看cat /proc/dumchar_info文件對應的recovery大小來確定(高通平臺沒有dumchar_info這個文件),
比如size一列爲0x600000,那麼count的值爲6144,也就是6M,如果爲0x700000,那麼count的值爲7168,也就是7M大小。
skip代表偏移,因爲MTK平臺recovery和boot等都在一個相同的分區中,通過地址偏移量來區分,這就是爲什麼高通平臺不需要執行bs 和count的原因。
3)如果手機是Nvidia芯片
ddif=/dev/block/platform/sdhci-tegra.3/by-name/SOS of=/storage/sdcard/recovery.img
2、解壓縮recovery.img
網上很多文章有關解壓縮和重新打包壓縮recovery.img的,利用perl腳本split_bootimg.pl 來解壓縮,但本人試驗過,解壓縮還行,重新打包就完全不行,生成的recovery.img根本沒法用。
recovery.img中主要包含內核recovery.img-kernel和根文件系統recovery.img-ramdisk.gz兩個東西。
這一步依然要區分MTK平臺和非MTK平臺
1)對於MTK平臺,過程稍微多一步
./split_bootimg.pl $1
//如果是非MTK平臺就不需要這一段代碼
filename=`basename $1`
echo $filename.....
dd if="$filename-ramdisk.gz" of="$filename-ramdisk.tmp.gz" skip=512 bs=1
mv "$filename-ramdisk.gz" "$filename-ramdisk.gz.full"
mv "$filename-ramdisk.tmp.gz" "$filename-ramdisk.gz"
rm -fr ramdisk_bak
mv ramdisk ramdisk_bak
mkdir -m 777 ramdisk
cd ramdisk
gzip -dc ../$1-ramdisk.gz | cpio -i
cd ../
chmod 777 -R ramdisk
$1代表傳入的參數recovery.img
執行這段腳本代碼後,屏幕會打印類似
Page size: 2048 (0x00000800)
Kernel size: 4285080 (0x00416298)
Kernel addr: 268468224 (0x10008000)
Ramdisk size: 1712833 (0x001a22c1)
Ramdisk addr: 285212672 (0x11000000)
Second size: 0 (0x00000000)
tag addr: 268435712 (0x10000100)
dt size: 0 (0x00000000)
Board name:
Command line:
dt: 0 (0x00000000)
dt_offset: 6002688 (0x005b9800)
Writing revocery.img-kernel ... complete.
Writing revocery.img-ramdisk.gz ... complete.
解壓之後在當前目錄下就生成了ramdisk目錄,裏面就是根文件系統
2)對於非MTK平臺,比如高通平臺
./split_bootimg.pl $1
rm -fr ramdisk_bak
mv ramdisk ramdisk_bak
mkdir -m 777 ramdisk
cd ramdisk
gzip -dc ../$1-ramdisk.gz | cpio -i
cd ../
chmod 777 -R ramdisk
執行解壓後會輸出如下:
Page size: 2048 (0x00000800)
Kernel size: 6471072 (0x0062bda0)
Kernel addr: 32768 (0x00008000)
Ramdisk size: 1995775 (0x001e73ff)
Ramdisk addr: 33554432 (0x02000000)
Second size: 0 (0x00000000)
tag addr: 31457280 (0x01e00000)
dt size: 5046272 (0x004d0000)
Board name:
Command line: console=none androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 restart.panic_to_dload=0 restart.download_mode=0
dt: 2464 (0x000009a0)
dt_offset: 8470528 (0x00814000)
Writing recovery.img-kernel ... complete.
Writing recovery.img-ramdisk.gz ... complete.
Writing recovery.img-dt.gz ... complete.
6640 blocks
注意上面的輸出內容:Kernel addr,Ramdisk addr,Command line 以及dt size(可能爲0)
Kernel addr = base addr + 0x8000
Ramdisk offset = Ramdisk addr - base addr
Ramdisk addr =base+0x2000000
tag addr =base+0x100
這裏base addr爲0x00000000,Ramdisk offset 爲0x02000000,注意還生成了一個recovery.img-dt.gz
同樣也生成了ramdisk目錄,可以替換sbin目錄下的可執行文件,換成自己定製的recovery,同樣的打開build.prop可以修改內核root的兩個屬性
ro.secure=0
ro.debuggable=1
注意,改這兩個屬性在boot.img中,並重新打包刷到手機中,就能實現內核root了。
3、重新壓縮打包recovery.img
1)對於非MTK平臺:
//將ramdisk目錄打包成ramdisk-new.gz壓縮包
rm -fr ramdisk-new.gz
./mkbootfs ./ramdisk | gzip > ramdisk-new.gz
rm -fr recovery-new.img
./mkbootimg --cmdline 'console=none androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 restart.panic_to_dload=0 restart.download_mode=0' --kernel recovery.img-kernel --ramdisk ramdisk-new.gz --base 0x00000000
--pagesize 2048 --ramdisk_offset 0x02000000 --dt recovery.img-dt.gz -o recovery-new.img
注意看命令,在第二步中計算過的--base 0x00000000 --pagesize 2048 --ramdisk_offset 0x02000000值都用上了,同時加上--dt命令(有些recovery.img也沒有包含dt文件,這種情況下就不需要--dt參數)
2)對於MTK平臺
就不需要上面計算的參數,直接
./repackMTK.pl -recovery recovery.img-kernel ramdisk recovery-new.img
4、接下來就是重新燒到手機中驗證了,可以通過fastboot來燒寫,可以參考我的上一篇記錄Android 採用fastboot刷system.img boot.img recovery.img