android 手機中boot.img基址的計算方法(zz)

來源:互聯網
上載者:User

boot.img基址 base的計算方法


如果您看這個文章,沒有耐心的話,我只能對你說,出現任何問題都是你自己的錯,有點耐心繼續 看吧,雖然在文章最後有點邪惡,大家原諒一下!我在工具包中給了一個參數,對於我的GT540肯定沒有什麼問題,但是對於其他手機我不敢保證,所以可能還 需您自己計算,或者使用版區前輩得到的數值!如果您做完之後刷回到手機之後會卡在開機介面,螢幕一閃一閃啊黑屏啊之類的癥狀層出不窮,普遍有兩種可能。
一、boot.img是加過密的。各位手機出產的公司,在做ROM的時候,以他們獨自的密碼編譯演算法,對整個檔案進行CRC驗算,然後將驗算值添加到 boot.img的最末尾。刷機的時候,手機的硬體BIOS就像一名盡職計程車兵,對此進行驗算,對不上口令的,那麼對不起,請君離開,不離開我警示了~~ 呃,報不了警,那反正我不讓你進門~~
二、boot.img還有一個重要的參數,基址 base,用於告訴手機從哪個地址開始,是準備給記憶體盤的入口,哪個地址是給kernel的入口。如果你對不上號,對不起,不能非法入室的。
如果是第一種,那隻能望風而逃,罷手了。
各種查閱,終於發現在ROM的boardconfig.h中存在地址位移的define。雖然本人手機的ROM中不存在這檔案,但各android系統這個位移是通用的,一般沒吃錯藥不會去改。
位移DEFINE如下:

 

  1. #define PHYSICAL_DRAM_BASE 0x00200000<!--IWMS_AD_BEGIN--> //基址,各不相同,我們的目的是為了獲得這個基址,但由於沒有ROM原始碼,這貌似是不可能的。<!--IWMS_AD_END-->#define KERNEL_ADDR (PHYSICAL_DRAM_BASE + 0x00008000)#define RAMDISK_ADDR (PHYSICAL_DRAM_BASE + 0x01000000)#define TAGS_ADDR (PHYSICAL_DRAM_BASE
    + 0x00000100)#define NEWTAGS_ADDR (PHYSICAL_DRAM_BASE + 0x00004000)

複製代碼

還記得WIKI中有這句話吧?For Nexus One : Add --base 0x20000000 to mkbootimg command-line. 翻譯一下,如果是nexus one手機,那麼需要在mkbootimg命令中加入 --base 0x20000000。。現在是不是很熟了?原來基址寫在這裡,mkbootimg會自動為你加入位移量,並寫入boot.img。。
好吧,我們現在需要知道,這些值是在哪個位置的。
為什麼需要呢?在第上面,我們已經知道了位移量了,那麼如果我們再從官方ROM的boot.img中擷取 kernel_addr,再用kernel_addr -位移量0x00008000,不就可以得出基址了嗎?
沒轍,需要知道bootimg工具把它們寫到哪了,只能查看mkbootimg的原始碼(幸好bootimg作為一個典型的LINUX工具,是開源的。若換成WIN,哥就真悲情了)。
各種尋找,找到bootimg.c檔案,看吧。
header + padding + kernel + padding + ramdisk + padding + ...(padding是補全,還記得上面所說的,一個盒子裝10張卡片,11張卡片需要幾個盒子的事情吧?第二個盒子由於只放了一張卡片,所以需要9張空白卡片來填充位置,即padding)
4 * 2, magic,固定為"ANDROID!"
4 * 1, kernel長度,小端unsigned類型
4 * 1, kernel地址,應為base + 0x00008000
4 * 1, ramdisk長度,小端unsigned
4 * 1, ramdisk地址,應為base + 0x01000000
4 * 1, second stage長度,小端unsigned,為0
4 * 1, second stage地址,應為base + 0x00f00000
4 * 1, tags地址,應為base + 0x00000100
4 * 1, page大小,小端unsigned, 為2048或者4096
4 * 2, 未使用,固定為0x00
4 * 4, 板子名字,一般為空白
4 * 128, 核心命令參數,一大串
4 * 8, id,不知道啥玩意,0x00
給親愛的16進位帖張圖吧,看圖說話,是N600+官方2.1ROM的16進位圖片,如下:
 

我們可以知道:
41 4E 44 52 4F 49 44 21 就是Magic Number ,內容是固定的ANDROID!。一一對應
kernel_size就是0x00237470。注意,小端讀法。是Byte內,順讀,整個類型中,逆讀。故70 74 23 00 的確切數字是0x 00 23 74 70
kernel_addr即0x 03008000。這時有人就問了,那用這個減去上面擷取的kernel位移,0x00008000,那麼base是不是0x030000000?好了,我知道了,我就用--base 0x03000000來打包。那麼,恭喜你,在N600上,這樣寫依然是不能啟動的,為什麼,請繼續看。
ramdisk_size是:B9 66 03 00 -->0x 00 03 66 B9。
ramdisk_addr即00 00 A0 03 -->0x 03 A0 00 00。減去位移0x01000000,base=0x02a00000
second_stage size:00000000
second_stage addr:00 00 90 03-->0x 03 90 00 00.減去位移0x00f00000,base=0x02a00000
tags_addr:00 01 a0 02-->0x 02a00100.減去位移0x00000100,base=0x02a00000
page_size:00 80 -->0x0800.這是頁長。記得我前面說過的頁長一般都為1K(1024)的整數倍吧?此處頁長是0x0800,轉為十進位,則是2048

好吧,我們來看下base吧,嗯,kernel的base是0x03000000,ramdisk和second_stage及tags_addr的基址都一樣啊,是...是0x02a000000。。我了個去~~4個base竟然有不一樣的~是的,我當時就是這麼罵的。
我就想,還好本人閑著無事算了4個base,如果有只算第1個,然後用0x03000000來打包的,基本就是悲劇的結果,可能還摸不著頭腦,以為這個boot.img是CRC校正的,而非基址弄錯。
好吧,以少數服從多數的原則,我們在打包的時候,把基址填為0x02a00000。然後把第一個地址kernel_addr,手動修正。
那麼,正確的命令如下:

  1. bootimg ramdisk |gzip >ramdisk-new.gzmkbootimg --kernel boot.img-kernel --ramdisk ramdisk-new.gz --base 0x02a00000 -o boot.img

複製代碼

然後用ghex2開啟boot.img,忽略前面的4*2Byte,41 4E 44 52 4F 49 44 21,這是magic number,固定不變的。
再跳過4*1Byte,在我這是70 74 23 00。這是kernel_size,程式產生,不需要手動改。
其後的4*1Byte才是kernel_addr,現在是00 80 A0 02,修改成 00 80 00 03。儲存之。
好了,將它放到刷機包目錄中,開啟刷機工具,刷之。快樂的啟動吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.