posts - 189,comments - 115,trackbacks - 0

          Android rom 刷機(jī)包制作研究(2)boot.img和recovery.img的編輯和修改【轉(zhuǎn)】


          http://www.eoeandroid.com/thread-52481-1-1.html

          以下是偶翻譯的關(guān)于boot.img和recovery.img的編輯和修改方面的文章,希望能夠?yàn)楦信d趣的朋友節(jié)約一些看資料的時(shí)間。感謝本文的作者:Alansj, DarkriftX, RyeBrye, Will, Try OP9, Tonyb486, Timmmm, Lxrose還有好多不知名的作者們?cè)趙iki上的不懈努力。
          如何解包/編輯/大包boot.img文件

          很多人用自己的方式解決了boot.img的解包/編輯/打包的問題,有人要求我來寫一篇關(guān)于boot和recovery映像的文件結(jié)構(gòu)和如何對(duì)其編輯的文章,于是就有了下面這篇文章。

          目錄
          1、背景知識(shí)
          2、boot和recovery映像的文件結(jié)構(gòu)
          3、對(duì)映像文件進(jìn)行解包、編輯、打包的常規(guī)方法
          3.1、另一種解包、編輯、打包的方法
          4、將新的映像刷回到手機(jī)
          5、解包、編輯、打包為我們帶來了什么
          6、本文講的內(nèi)容與使用update.zip刷機(jī)包不是一碼事

          正文
          1、背景知識(shí)

          Android手機(jī)的文件系統(tǒng)有許多存儲(chǔ)器組成,以下是在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"
          注意,不同的手機(jī)在上述存儲(chǔ)設(shè)備的順序可能會(huì)各不相同!一定要檢查您的手機(jī),確定在以下的操作中選擇正確的設(shè)備號(hào)(mtdX,這個(gè)X的序號(hào)一定要檢查清楚)。

          在本向?qū)е校覀冎饕枋鰧?duì)"recovery"和"boot"的存儲(chǔ)設(shè)備進(jìn)行操作;"system"存儲(chǔ)設(shè)備保存了android系統(tǒng)目錄的所有數(shù)據(jù)(在系統(tǒng)啟動(dòng)后會(huì)掛載到“system/”目錄);“userdata”存儲(chǔ)設(shè)備將保存了android數(shù)據(jù)目錄中的所有數(shù)據(jù)(在系統(tǒng)啟動(dòng)后會(huì)掛載到“data/”目錄,里面是會(huì)有很多應(yīng)用數(shù)據(jù)以及用戶的preference之類的配置數(shù)據(jù))。

          從上面的輸出可以看出來,recovery和boot分區(qū)對(duì)應(yīng)著/dev/mtd/mtd1和/dev/mtd/mtd2,在你您開始做任何修改之前一定要做兩件事情,第一件事情,一定要先對(duì)這兩個(gè)分區(qū)進(jìn)行備份。
          可以使用如下命令進(jìn)行備份:
          # cat /dev/mtd/mtd1 > /sdcard/recovery.img
          # cat /dev/mtd/mtd2 > /sdcard/boot.img
          (注意added by lxros,只有手機(jī)獲取了ROOT權(quán)限以后才能夠執(zhí)行上述的備份命令)

          第二件事情,你您應(yīng)該把你您最喜歡的update.zip刷機(jī)包放置到你您的sd卡的根目錄上面。如此一來,即使你您在后續(xù)的操作中出了問題,也可以啟動(dòng)到recovery模式進(jìn)行恢復(fù)。

          另外一個(gè)你您需要知道的重要文件是在android系統(tǒng)目錄下的/system/recovery.img,此文件是mtd1存儲(chǔ)設(shè)備的完全拷貝。這個(gè)文件在每次關(guān)機(jī)的時(shí)候,會(huì)自動(dòng)地被寫回到mtd1存儲(chǔ)設(shè)備里面。

          這會(huì)意味著兩個(gè)事情:
          (1)任何對(duì)/dev/mtd/mtd1中數(shù)據(jù)的直接修改都會(huì)在下一次重啟手機(jī)以后消失。
          (2)如果希望對(duì)/dev/mtd/mtd1進(jìn)行修改,最簡單的做法是用你您自己的recovery.img替換掉/system/recovery.img。當(dāng)你您創(chuàng)建自己的update.zip刷機(jī)包的時(shí)候(特別是在做刷機(jī)包的適配的時(shí)候),如果你您忘記替換這個(gè)/system/recovery.img,這個(gè)recovery.img就會(huì)在關(guān)機(jī)的時(shí)候被燒寫到mtd1里面去或許會(huì)變磚。一定要注意這一點(diǎn)!

          (譯者的話,關(guān)于這個(gè)/system/recovery.img文件,在2.1的android的平臺(tái)里面并沒有找到,或許這個(gè)機(jī)制已經(jīng)out了?!或者偶本人對(duì)這段話的理解不夠深入?!希望明白的朋友不吝斧正)

          2、boot和recovery映像的文件結(jié)構(gòu)
          boot和recovery映像并不是一個(gè)完整的文件系統(tǒng),它們是一種android自定義的文件格式,該格式包括了2K的文件頭,后面緊跟著是用gzip壓縮過的內(nèi)核,再后面是一個(gè)ramdisk內(nèi)存盤,然后緊跟著第二階段的載入器程序(這個(gè)載入器程序是可選的,在某些映像中或許沒有這部分)。此類文件的定義可以從源代碼android-src/system/core/mkbootimg找到一個(gè)叫做bootimg.h的文件。

          (譯者的話,原文是一個(gè)叫做mkbootimg.h的文件,但從Android 2.1的代碼來看,該文件名應(yīng)該是改為bootimg.h了)。

          /*
          ** +-----------------+ 
          ** | 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映像是一個(gè)最基礎(chǔ)的小型文件系統(tǒng),它包括了初始化系統(tǒng)所需要的全部核心文件,例如:初始化init進(jìn)程以及init.rc(可以用于設(shè)置很多系統(tǒng)的參數(shù))等文件。如果你您希望了解更多關(guān)于此文件的信息可以參考以下網(wǎng)址:
          http://git.source.android.com/?p=kernel/common.git;a=blob;f=Documentation/filesystems/ramfs-rootfs-initramfs.txt
          以下是一個(gè)典型的ramdisk中包含的文件列表:
          ./init.trout.rc
          ./default.prop
          ./proc
          ./dev
          ./init.rc
          ./init
          ./sys
          ./init.goldfish.rc
          ./sbin
          ./sbin/adbd
          ./system
          ./data

          recovery映像包含了一些額外的文件,例如一個(gè)叫做recovery的二進(jìn)制程序,以及一些對(duì)該程序支持性的資源圖片文件(當(dāng)你您按下home+power組合鍵的時(shí)候就會(huì)運(yùn)行這個(gè)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

          3、對(duì)映像文件進(jìn)行解包、編輯、打包的常規(guī)方法
          (注意,下面我給你您介紹的是手工命令行方式進(jìn)行解包以及重新打包的方法,但是我仍然創(chuàng)建了兩個(gè)perl腳本,這兩個(gè)腳本可以讓你您的解包和打包工作變得輕松許多。可以參考本文的附件unpack-bootimg.zip和repack-bootimg.zip)

          如果你您很擅長使用16進(jìn)制編輯器的話,你您可以打開boot.img或者recovery.img,然后跳過開始的2K的頭數(shù)據(jù),然后尋找一大堆0的數(shù)據(jù),在這一堆0的數(shù)據(jù)后面,緊跟著1F 8B這兩個(gè)數(shù)字(1F 8B是gzip格式的文件的結(jié)束標(biāo)記)。從此文件開始的地方(跳過2K的頭),一大堆0后面緊跟著到1F 8B這兩個(gè)數(shù)字為止的全部數(shù)據(jù),就是gzip壓縮過的linux內(nèi)核。從1F 8B后面緊跟著的數(shù)據(jù)一直到文件的結(jié)尾包含的全部數(shù)據(jù),就是ramdisk內(nèi)存盤的數(shù)據(jù)。你您可以把把內(nèi)核和ramdisk兩個(gè)文件分別保存下來,在進(jìn)行分別的修改和處理。我們可以通過un-cpio和un-gzip操作來讀取ramdisk文件中的數(shù)據(jù),可以使用如下的命令來實(shí)現(xiàn)這個(gè)目的,以下操作會(huì)生成一個(gè)目錄,直接cd進(jìn)去就可以看到ramdisk中的數(shù)據(jù)了:

          gunzip -c ../your-ramdisk-file | cpio -i

          此命令可以將ramdisk中的所有的文件解包到當(dāng)前的工作目錄下面,然后就可以對(duì)它進(jìn)行編輯了。

          當(dāng)需要重新打包ramdisk的時(shí)候,就需要re-cpio然后re-gzip這些數(shù)據(jù)和目錄,可以通過如下命令來實(shí)現(xiàn):(cpio會(huì)把所有當(dāng)前目錄下面的文件都打包進(jìn)去,因此,在進(jìn)行此步驟之前,請(qǐng)把不需要的文件都清除掉。)

          find . | cpio -o -H newc | gzip > ../newramdisk.cpio.gz

          最后一步就是通過mkbootimg這個(gè)工具,把kernel和ramdisk打包在一起,生成一個(gè)boot.img:

          mkbootimg --cmdline 'no_console_suspend=1 console=null' --kernel your-kernel-file --ramdisk newramdisk.cpio.gz -o mynewimage.img

          這里的mkbootimg工具會(huì)在編譯android的源代碼的時(shí)候會(huì)在~/android-src/out/host/linux-x86/bin目錄下面自動(dòng)生成。
          下載地址:
          http://git.source.android.com/?p=platform/system/core.git;a=tree;f=mkbootimg

          現(xiàn)在,如果不想背這些復(fù)雜的命令或者擺弄那個(gè)讓人眩暈的16進(jìn)制編輯器的話,可以嘗試使用我編寫的用于解包和打包的perl腳本了。希望這些腳本能夠節(jié)約各位的鍵盤。

          3.1、另一種解包、編輯、打包的方法
          下載split_bootimg.zip文件(譯者注,會(huì)在本文的附件中提供),在此zip文件中包含一個(gè)perl文件,split_bootimg.pl腳本,該腳本可以讀取boot.img頭(根據(jù)Android源碼中的bootimg.h讀取)將kernel和ramdisk讀取出來,此腳本也會(huì)輸出內(nèi)核命令行和板子名字。

          (注意,不要使用從/dev/mtd/mtd2直接拷貝出來的boot.img,此映像可能在讀取過程遭到損壞。)
          下面是一個(gè)從TC4-RC28更新中提取出來的boot.img進(jìn)行解包操作:
          % ./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.

          解包ramdisk的命令如下:
          % mkdir ramdisk
          % cd ramdisk
          % gzip -dc ../boot.img-ramdisk.gz | cpio -i
          % cd ..

          解碼完畢后,就可以修改了(例如,在default.prop設(shè)置ro.secure=0等等)

          使用mkbootfs工具(mkbootfs工具是編譯完畢Android源代碼以后,就會(huì)在~/android-src/out/host/linux-x86/bin自動(dòng)生成)來重新創(chuàng)建ramdisk,可以使用如下命令來操作:
          % mkbootfs ./ramdisk | gzip > ramdisk-new.gz

          使用mkbootimg來重新創(chuàng)建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
          (注意:console=null的命令行選現(xiàn)是從TC4-RC30的boot.img引入的,用以去掉root shell)

          4、將新的映像刷回到手機(jī)
          可以將recovery.img拷貝到/system目錄下面,然后重新啟動(dòng)手機(jī),讓手機(jī)自動(dòng)為你您刷寫到mtd里面(工作原理在上面已經(jīng)提過了)。對(duì)于boot.img可以通過將其拷貝到sd卡的根目錄,然后通過手機(jī)內(nèi)的刷寫工具將此映像寫入到手機(jī)中。

          例如,使用adb工具將boot.img拷貝到手機(jī)的sd卡的根目錄:
          adb push ./mynewimage.img /sdcard
          然后通過adb shell登錄手機(jī)的shell交互模式,利用命令行進(jìn)行交互:
          # cat /dev/zero > /dev/mtd/mtd2
             write: No space left on device [this is ok, you can ignore]
          # flash_image boot /sdcard/mynewimage.img
          然后重啟手機(jī)。

          如果手機(jī)能夠正常啟動(dòng),那么祝賀你您,你您的修改和替換已經(jīng)成功了;如果不能夠順利啟動(dòng),則需要重新啟動(dòng)進(jìn)入recovery模式,并且使用update.zip來恢復(fù)。

          5、解包、編輯、打包為我們帶來了什么
          可以修改手機(jī)開機(jī)啟動(dòng)時(shí)候的畫面,具體的操作的地址為:
          http://forum.xda-developers.com/showthread.php?t=443431

          6、本文講的內(nèi)容與使用update.zip刷機(jī)包不是一碼事
          您可以很容易地在其他論壇上看到關(guān)于如何自制update.zip刷機(jī)包的方法,也可以下載到很多在網(wǎng)絡(luò)上共享的自制刷機(jī)包。例如:近期的多數(shù)刷機(jī)包都來自對(duì)rc30包的修改和調(diào)整。在update.zip刷機(jī)包里面會(huì)包括新的boot.img,recovery.img以及整個(gè)system/目錄下的若干文件的替換和更新。如果您希望自己自制boot.img以及recovery.img,建議您選取相對(duì)較新的更新和版本。(選用較老的映像的話,或許會(huì)出現(xiàn)兼容性問題)。

          posted on 2011-12-14 14:58 MEYE 閱讀(5222) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 泌阳县| 墨竹工卡县| 抚顺市| 伊宁市| 英德市| 曲水县| 新巴尔虎右旗| 永清县| 贺兰县| 靖边县| 越西县| 临高县| 永兴县| 贵溪市| 临湘市| 阜宁县| 黄大仙区| 六盘水市| 寿宁县| 伽师县| 武定县| 嘉祥县| 江口县| 苏尼特右旗| 定结县| 九江县| 安仁县| 兰州市| 乌苏市| 葫芦岛市| 宜阳县| 伽师县| 曲沃县| 灵璧县| 玉树县| 东乡族自治县| 通山县| 新干县| 平和县| 玉田县| 邢台县|