感謝本文的作者:Alansj, DarkriftX, RyeBrye, Will, Try OP9, Tonyb486, Timmmm, Lxrose還有好多不知名的作者們在wiki上的不懈努力。
來源:http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack%2C_Edit%2C_and_Re-Pack_Boot_Images
1、背景知識
2、boot和recovery映像的文件結構
3、對映像文件進行解包、編輯、打包的常規方法
3.1、另一種解包、編輯、打包的方法
4、將新的映像刷回到手機
5、解包、編輯、打包為我們帶來了什麼
6、本文講的內容與使用update.zip刷機包不是一碼事正文1、背景知識Android手機的文件系統有許多存儲器組成,以下是在adb shell下面的輸出:
#cat / proc / mtd
dev: size erasesize name
mtd0: 00040000 00020000 " misc "
mtd1: 00500000 00020000 " recovery "
mtd2: 00280000 00020000 " boot "
mtd3: 04380000 00020000 " system "
mtd4: 04380000 00020000 " cache "
mtd5: 04ac0000 00020000 " userdata "
dev: size erasesize name
mtd0: 00040000 00020000 " misc "
mtd1: 00500000 00020000 " recovery "
mtd2: 00280000 00020000 " boot "
mtd3: 04380000 00020000 " system "
mtd4: 04380000 00020000 " cache "
mtd5: 04ac0000 00020000 " userdata "
# cat / dev / mtd / mtd1 > / sdcard / recovery.img
# cat / dev / mtd / mtd2 > / sdcard / boot.img
# cat / dev / mtd / mtd2 > / sdcard / boot.img
/*
** +-----------------+
** | boot header | 1 page
** +---------------- -+
** | kernel | n pages
** +-----------------+
** | ramdisk | m pages
** +---------- -------+
** | second stage | o pages
** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
**
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
** 3. load each element (kernel, ramdisk, second) at
** the specified physical address (kernel_addr, etc)
* * 4. prepare tags at tag_addr. kernel_args[] is
** appended to the kernel commandline in the tags.
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
** 6. if second_size != 0: jump to second_addr
** else: jump to kernel_addr */
** +-----------------+
** | boot header | 1 page
** +---------------- -+
** | kernel | n pages
** +-----------------+
** | ramdisk | m pages
** +---------- -------+
** | second stage | o pages
** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size
**
** 0. all entities are page_size aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
** 3. load each element (kernel, ramdisk, second) at
** the specified physical address (kernel_addr, etc)
* * 4. prepare tags at tag_addr. kernel_args[] is
** appended to the kernel commandline in the tags.
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
** 6. if second_size != 0: jump to second_addr
** else: jump to kernel_addr */
ramdisk映像是一個最基礎的小型文件系統,它包括了初始化系統所需要的全部核心文件,例如:初始化init進程以及init.rc(可以用於設置很多系統的參數)等文件。如果你您希望了解更多關於此文件的信息可以參考以下網址:http://git.source.android.com/?p=kernel/common.git;a=blob;f=Documentation/filesystems/ramfs- rootfs-initramfs.txt以下是一個典型的ramdisk中包含的文件列表:
. / init.trout.rc
. / default .prop
. / proc
. / dev
. / init.rc
. / init
. / sys
. / init.goldfish.rc
. / sbin
. / sbin / adbd
. / system
. / data
. / default .prop
. / proc
. / dev
. / init.rc
. / init
. / sys
. / init.goldfish.rc
. / sbin
. / sbin / adbd
. / system
. / data
recovery映像包含了一些額外的文件,例如一個叫做recovery的二進製程序,以及一些對該程序支持性的資源圖片文件(當你您按下home+power組合鍵的時候就會運行這個recovery程序)。
典型的文件列表如下:
. / res
. / res / images
. / res / images / progress_bar_empty_left_round.bmp
. / res / images / icon_firmware_install.bmp
. / res / images / indeterminate3.bmp
. / res / images / progress_bar_fill.bmp
. / res / images / progress_bar_left_round.bmp
. / res / images / icon_error.bmp
. / res / images / indeterminate1.bmp
. / res / images / progress_bar_empty_right_round.bmp
. / res / images / icon_firmware_error.bmp
. / res / images / progress_bar_right_round.bmp
. / res / images / indeterminate4.bmp
. / res / images / indeterminate5.bmp
. / res / images / indeterminate6.bmp
. / res / images / progress_bar_empty.bmp
. / res / images / indeterminate2.bmp
. / res / images / icon_unpacking .bmp
. / res / images / icon_installing.bmp
. / sbin / recovery
. / res / images
. / res / images / progress_bar_empty_left_round.bmp
. / res / images / icon_firmware_install.bmp
. / res / images / indeterminate3.bmp
. / res / images / progress_bar_fill.bmp
. / res / images / progress_bar_left_round.bmp
. / res / images / icon_error.bmp
. / res / images / indeterminate1.bmp
. / res / images / progress_bar_empty_right_round.bmp
. / res / images / icon_firmware_error.bmp
. / res / images / progress_bar_right_round.bmp
. / res / images / indeterminate4.bmp
. / res / images / indeterminate5.bmp
. / res / images / indeterminate6.bmp
. / res / images / progress_bar_empty.bmp
. / res / images / indeterminate2.bmp
. / res / images / icon_unpacking .bmp
. / res / images / icon_installing.bmp
. / sbin / recovery
3、對映像文件進行解包、編輯、打包的常規方法
(注意,下面我給你您介紹的是手工命令行方式進行解包以及重新打包的方法,但是我仍然創建了兩個perl腳本,這兩個腳本可以讓你您的解包和打包工作變得輕鬆許多。
可以參考本文的附件
unpack-bootimg.zip http://android-dls.com/files/apps/unpack-bootimg.zip
repack-bootimg.zip http://android-dls.com/files/apps/repack-bootimg.zip
如果你您很擅長使用16進制編輯器的話,你您可以打開boot.img或者recovery.img,然後跳過開始的2K的頭數據,然後尋找一大堆0的數據,在這一堆0的數據後面,緊跟著1F 8B這兩個數字(1F 8B是gzip格式的文件的結束標記)。從此文件開始的地方(跳過2K的頭),一大堆0後面緊跟著到1F 8B這兩個數字為止的全部數據,就是gzip壓縮過的linux內核。從1F 8B後面緊跟著的數據一直到文件的結尾包含的全部數據,就是ramdisk內存盤的數據。你您可以把把內核和ramdisk兩個文件分別保存下來,在進行分別的修改和處理。我們可以通過un-cpio和un-gzip操作來讀取ramdisk文件中的數據,可以使用如下的命令來實現這個目的,以下操作會生成一個目錄,直接cd進去就可以看到ramdisk中的數據了:
gunzip - c .. / your - ramdisk - file | cpio - i
此命令可以將ramdisk中的所有的文件解包到當前的工作目錄下面,然後就可以對它進行編輯了。當需要重新打包ramdisk的時候,就需要re-cpio然後re-gzip這些數據和目錄,可以通過如下命令來實現:(cpio會把所有當前目錄下面的文件都打包進去,因此,在進行此步驟之前,請把不需要的文件都清除掉。)
find . | cpio - o - H newc | gzip > .. / newramdisk.cpio.gz
最後一步就是通過mkbootimg這個工具,把kernel和ramdisk打包在一起,生成一個boot.img:
mkbootimg -- cmdline ' no_console_suspend=1 console=null ' -- kernel your - kernel - file -- ramdisk newramdisk.cpio.gz - o mynewimage.img
這裡的mkbootimg工具會在編譯android的源代碼的時候會在~/android-src/out/host/linux-x86/bin目錄下面自動生成。
下載地址:
http://git.source.android.com/?p=platform/system/core.git;a=tree;f=mkbootimg 現在,如果不想背這些複雜的命令或者擺弄那個讓人眩暈的16進制編輯器的話,可以嘗試使用我編寫的用於解包和打包的perl腳本了。希望這些腳本能夠節約各位的鍵盤。3.1、另一種解包、編輯、打包的方法下載split_bootimg.zip文件,在此zip文件中包含一個perl文件,split_bootimg.pl腳本,該腳本可以讀取boot.img頭(根據Android源碼中的bootimg .h讀取)將kernel和ramdisk讀取出來,此腳本也會輸出內核命令行和板子名字。http://android-dls.com/files/linux/split_bootimg.zip (注意,不要使用從/dev/mtd/mtd2直接拷貝出來的boot.img,此映像可能在讀取過程遭到損壞。)下面是一個從TC4-RC28更新中提取出來的boot.img進行解包操作:
% . / split_bootimg.pl boot.img Page size: 2048 ( 0x00000800 ) Kernel size: 1388548 ( 0x00153004 ) Ramdisk size: 141518 ( 0x000228ce ) Second size: 0 ( 0x00000000 ) Board name: Command line: no_console_suspend = 1
Writing boot.img - kernel ... complete. Writing boot.img - ramdisk.gz ... complete.
Writing boot.img - kernel ... complete. Writing boot.img - ramdisk.gz ... complete.
解包ramdisk的命令如下:
% mkdir ramdisk % cd ramdisk % gzip - dc .. / boot.img - ramdisk.gz | cpio - i % cd ..
解碼完畢後,就可以修改了(例如,在default.prop設置ro.secure=0等等)使用mkbootfs工具(mkbootfs工具是編譯完畢Android源代碼以後,就會在~/android-src/out/host /linux-x86/bin自 動生成)來重新創建ramdisk,可以使用如下命令來操作:
% mkbootfs . / ramdisk | gzip > ramdisk - new .gz
使用mkbootimg來重新創建boot.img,mkbootimg也可以在~/android-src/out/host/linux-x86/bin目錄中可以找到:
% mkbootimg -- cmdline ' no_console_suspend=1 console=null ' -- kernel boot.img - kernel -- ramdisk ramdisk - new .gz - o boot - new .img
adb push . / mynewimage.img / sdcard
# cat / dev / zero > / dev / mtd / mtd2 write: No space left on device [ this is ok, you can ignore] # flash_image boot / sdcard / mynewimage.img
您可以很容易地在其他論壇上看到關於如何自製update.zip刷機包的方法,也可以下載到很多在網絡上共享的自製刷機包。例如:近期的多數刷機包都來自對rc30包的修改和調整。在update.zip刷機包裡面會包括新的boot.img,recovery.img以及整個system/目錄下的若干文件的替換和更新。如果您希望自己自製boot.img以及recovery.img,建議您選取相對較新的更新和版本。(選用較老的映像的話,或許會出現兼容性問題)。
沒有留言:
張貼留言