MTK67xx+Android啓動----pre-loader

Bootloader能夠準備一個至關重要的執行環境和引導linux操作系統及Android框架(framework)。

bootloader主要包括設置處理器和內存的頻率、調試信息端口、可引導的存儲設備等等。在可執行環境創建好之後,接下來把software裝載到內存並執行。除了裝載software,一個外部工具也能和bootloader握手(handshake),可指示設備進入不同的操作模式,比如USB下載模式和META模式。就算沒有外部工具的握手,通過外部任何組合或是客戶自定義按鍵,bootloader也能夠進入這些模式。

 

因爲bootloader的一部分和系統有關,所以MTK爲了不同的應用將它分爲兩部分的bootloader:

(1)  第1部分bootloader,也就是MTK內部(in-house)的pre-loader,這部分依賴平臺。(flash_tool 二次燒寫的引導)

(2)  第2部分bootloader,也就是u-boot,這部分依賴操作系統,負責引導linux操作系統和Android框架。

 

  1.  Pre-loader源代碼

   1.1源代碼目錄

(1)  Pre-loader的代碼在alps\vendor\mediatek\proprietary\bootable\bootloader

Pre-loader核心和平臺驅動源碼。

 

(2)  xxx\mediatek\custom\<project>\preloader

依賴於平臺自定義文件的部分(platform dependent customization),比如EMI(external memory interface,外部存儲器接口)設置。

 

Inc文件夾:

1)     cust_bldr.h

pre-loader的一些定製的特徵,比如是從SDMMC還是NAND啓動、調試口選擇(UART1或是UART4)和波特率的配置等宏定義。

 

2)     cust_msdc.h

MSDC的自定義,比如包括MSDC的時鐘頻率、命令鎖存跳變沿(上升沿或是下降沿)、數據鎖存的跳變沿、高速或是全速模式等等。

 

3)     cust_nand.h

定義了所支持的NAND FLASH信息,比如FLASH ID、多少塊、一塊多少頁等信息,但這些被註釋掉了,主要定義了默認的訪問時間等

 

4)     cust_rtc.h

RTC年月日的默認設置。

 

5)     cust_sec_ctl.h

一些安全設置的定義,比如包括了項目名稱(比如cust)、平臺名稱(MT6577)、S-Boot的一些屬性等。

 

6)     cust_usb.h.h

USB設置的宏定義,包括USB製造商、USB供應商ID(VID)、USB識別碼ID(PID)等。

 

7)     custom_emi.h

擴展存儲器接口的寄存器和設置的結構體定義。

 

8)     custom_MemoryDevice.h

定了採用的內存設備類型,比如H9TP32A4GDMCPR。

 

9)     mt6762_emi.h

mt6762內存的一些函數原型,如:

extern voidmt6762_set_emi (void);

extern voidmt6762_256M_mem_setting (void);

 

10)  mt6762_emi_reg.h

內存控制寄存器的宏定義。

 

11)  mt6762_memory.h

內存的一些設置,比如用於內存測試的大小、E1和E2內存的大小和一些函數原型。

 

12)  mt6762_nfi.h

nfi是Nand Flash Interface的縮寫,和cust_nand.h內容一樣。

 

(3)  xxx\mediatek\source\preloader

開發工具,例如building、trace32 cmm文件等,pre-loader對象和鏡像二進制輸出文件

 

1.2  編譯命令

1)Pre-loader的編譯命令:

  • 腳本編譯          cd ./vendor/mediatek/proprietary/bootable/bootloader/preloader

                                ./build.sh 2>&1 | tee preloader_build.log

  • 或者先全編譯一次後模塊   mmm vendor/mediatek/proprietary/bootable/bootloader/preloader:pl
  • 直接編譯        make -j8 pl 2>&1 |  tee pl.log

                                           生成在./out/target/product/k62v1_64_bsp/obj/PRELOADER_OBJ/bin

 2)lk

  • 全編譯後      mmm vendor/mediatek/proprietary/bootable/bootloader/lk:clean-lk       

       mmm vendor/mediatek/proprietary/bootable/bootloader/lk:lk

  • 直接編譯     make -j4 lk 2>&1 | tee lk_build.log

3)kernel

mmm kernel-4.9:clean-kernel 

make -j8 kernel  bootimage

 

android平臺提供了三個命令用於編譯,這3個命令分別爲: 
1. make: 不帶任何參數則是編譯整個系統; 
make MediaProvider: 單個模塊編譯,會把該模塊及其依賴的其他模塊一起編譯(會搜索整個源代碼來定位MediaProvider模塊所使用的Android.mk文件,還要判斷該模塊依賴的其他模塊是否有修改); 
2. mmm packages/providers/MediaProvider: 編譯指定目錄下的模塊,但不編譯它所依賴的其它模塊; 
3. mm: 編譯當前目錄下的模塊,它和mmm一樣,不編譯依賴模塊; 
4. mma: 編譯當前目錄下的模塊及其依賴項 
以上三個命令都可以用-B選項來重新編譯所有目標文件。
 

2.     bootloader的工作流程

 

2.1  bootloader正常的啓動流程

先來看啓動流程圖:

2.1  bootloader正常的啓動流程

先來看啓動流程圖:

 

圖1

正常啓動的主要工作如下:

(1)  設備上電後,Boot ROM開始運行。

(2)  BootROM初始化軟件堆棧(software stack)、通信端口和可引導存儲設備(比如NAND/EMMC)。

(3)  BootROM從存儲器中加載pre-loader到內部SRAM(ISRAM)中,因爲這時候還沒有初始化外部的DRAM。

(4)  BootROM跳轉到pre-loader的入口處並執行。

(5)  Pre-loader初始化DRAM和加載U-Boot到RAM中。

(6)  Pre-loader跳轉到U-Boot中並執行,然後U-Boot做一些初始化,比如顯示的初始化等。

(7)  U-Boot從存儲器中加載引導鏡像(boot image),包括linux內核和ramdisk(Android呢?)

(8)  U-Boot跳轉到linux內核並執行。

 

2.2  bootloader正常的下載流程

先來看正常的下載流程圖:

 

圖2

正常的下載主要工作如下:

(1)  設備上電後,Boot ROM開始運行。

(2)  BootROM初始化軟件堆棧(software stack)、通信端口和可引導存儲設備(比如NAND/EMMC)。

(3)  BootROM通過UART/USB和flash工具握手。

(4)  BootROM通過UART下載pre-loader鏡像到NAND flash/EMMC中,然後重啓。

(5)  BootROM加載pre-loader到內部SRAM彙總,因爲DRAM還沒有初始化。

(6)  BootROM跳轉到pre-loader並執行。

(7)  Pre-loader初始化DRAM和通過USB與flash工具握手。

(8)  Pre-loader通過USB下載其餘鏡像文件,比如U-Boot、boot image、recovery image、android system image、user data到NAND FLASH/EMMC中。

 

 

2.3  Bootloader備用的下載流程(emergency download procedure)

(1)  設備上電後,Boot ROM開始運行。

(2)  BootROM初始化軟件堆棧(software stack)、通信端口和可引導存儲設備(比如NAND/EMMC)。

(3)  BootROM在emergency DL按鍵按下後,通過USB和flash工具握手。

(4)  BootROM通過USB把指定的鏡像文件下載到NAND FLASH/EMMC中。

 

 

3.     pre-loader的功能

pre-loader是MTK內置的loader,它的主要功能如下:

(1)  負責在芯片組平臺(chipset platform)上準備好可執行的環境

(2)  如果外部工具有效,它會試圖通過UART或是USB來和外部工具握手。

(3)  從NAND/EMMC加載U-Boot,並跳轉到U-Boot。

(4)  使用工具握手,設備能夠觸發進入下載模式來下載需要的鏡像,或是進入工廠/測試模式,比如META模式和ATE工廠模式,在這些模式下可以測試模塊,或是通過傳遞引導參數給U-Boot和linux內核來校準設備(device calibration)

 

對於安全的執行環境,安全引導程序會檢查(checking)或是查證(verification),這樣能夠保護我們的芯片被攻擊(hacked)。

 

4.     Bootloader硬件環境

當設備上電後,bootloaders被加載到不同的內存區域並執行,如下圖所示:

 

 

圖3

Pre-loader在芯片內部系統(chipset’s internal system)RAM的0Xc2010000位置開始執行,U-Boot在外部RAM的0x01E00000處執行。當bootloaders執行時,初始化多種硬件模塊來創建一個可執行的環境,具體是哪些硬件模塊,下面有詳細的描述。

 

4.1  pre-loaders中涉及的硬件部分

當系統啓動時,芯片組(chipset)內部的可引導ROM開始執行,並從可引導存儲設備(NAND/EMMC等等)上拷貝pre-loader。所以,需要通過初始化一些硬件模塊來爲軟件創造必要的可執行環境(essential execution environment),所有這些硬件模塊在接下來描述。

(1)  PLL模塊

1)     PLL模塊用於調整處理器和外部內存的頻率。

2)     在PLL模塊初始化後,處理器和外部內存的頻率可由26MHZ/26MHZ增加到1GHZ/192MHZ。

(2)  UART模塊

1)     UART模塊用於調試或是META模式下的握手。

2)     默認情況下,UART4初始化波特率爲9216000bps和用於調試信息的輸出,UART1初始化爲115200bps和作爲UART META魔獸端口。但也可以使用UART1作爲調試或是UART META端口。

 

(3)  計時器(timer)模塊

這是個基本的模塊,用來計算硬件模塊所需要的延時或是超時時間。

 

(4)  內存模塊

1)     Pre-loader由boot ROM加載和在芯片組內部的SRAM中執行,因爲外部的DRAM還沒有初始化。

2)     爲了準備軟件整個可執行環境,pre-loader採用內置的內存設置來初始化DRAM(DRAM is initialized upon pre-loader built-inmemory settigns)。這樣,U-Boot就能夠被加載到DRAM中並執行。

 

(5)  GPIO模塊

(6)  PMIC模塊

爲了提供一些基本的硬件功能,比如控制外設電源,pre-loader初始化上層模塊(upper modules)。

 

(7)  RTC模塊

1)     當通過power按鍵開機後,pre-loader拉高RTC的PWBB來保持設備一直有電(keep the device alive)和繼續引導U-Boot。

2)     RTC鬧鐘(alarm)有可能是設備開機的啓動源,對於這種情況,設備部需要按power按鍵就可自動啓動。

 

(8)  USB模塊

當USB線插入時,它初始化來和外部工具通信,比如用於升級系統的下載工具或是META模式觸發器的META工具。

 

(9)  NAND模塊

(10) MSDC模塊

Pre-loader可以從NAND flash或是EMMC中加載U-Boot,這兩者只能選擇其中一種來啓動。

 

5.     Pre-loader的過程(procedure)和流程(flow)

如下圖:

 

圖4

具體的源代碼後面再分析了。

 

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 2501
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章