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框架。
- 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
具體的源代碼後面再分析了。