mini2440 u-boot linux 内核启动,u-boot.2012.10——mini2440(二、启动流程分析)
參考資料:https://blog.csdn.net/suiyuan19840208/article/details/7239949
https://blog.csdn.net/pugu12/article/details/47011159
http://tscsh.blog.163.com/blog/static/200320103201312645149965/
https://blog.csdn.net/winheroii58/article/details/6803327
1、第一階段功能
* 硬件設(shè)備初始化
* 加載u-boot第二段代碼到RAM空間
* 設(shè)置好棧
* 跳轉(zhuǎn)到第二段代碼入口
2、第二段代碼的功能
* 初始化本階段使用的硬件設(shè)備
* 檢測系統(tǒng)的內(nèi)存映射
* 將內(nèi)核從Flash讀到RAM中
* 為內(nèi)核設(shè)置啟動參數(shù)
* 調(diào)用內(nèi)核
3 、u-boot第一階段代碼分析
我們在編譯完成之后,觀察頂層目錄有個u-boot.lds的鏈接腳本
* 經(jīng)過編譯之后,查看文件u-boot.lds鏈接腳本,可以看到第一個鏈接文件是start.S
4、start.S
* 設(shè)置異常向量
當(dāng)一個異常產(chǎn)生時,CPU根據(jù)異常號在異常向量表中找到對應(yīng)的異常向量,然后執(zhí)行異常向量處的跳轉(zhuǎn)指令,,CPU跳轉(zhuǎn)到對應(yīng)的異常處理程序執(zhí)行。
其中復(fù)位異常向量的指令“b start_code”決定了啟動后將自動跳轉(zhuǎn)到標(biāo)號"start_code"處執(zhí)行。
* CPU進(jìn)入SVC模式
從數(shù)據(jù)手冊上可以看到10011就是設(shè)置為管理模式
* 設(shè)置控制寄存器的地址
* 關(guān)閉看門狗
* 屏蔽中斷
*設(shè)置時鐘
CPU上電幾毫秒后,晶振輸出穩(wěn)定,FCLK=Fin(晶振頻率),CPU開始執(zhí)行指令。但實際上,FCLK可以高于Fin,為了提高系統(tǒng)時鐘,需要用軟件來啟用PLL。這就需要設(shè)置CLKDIVN,MPLLCON,UPLLCON這3個寄存器。
CLKDIVN寄存器,CLKDIVN寄存器用于設(shè)置FCLK,HCLK,PCLK三者間的比例
設(shè)置CLKDIVN為5,就將HDIVN設(shè)置為二進(jìn)制的10,由于CAMDIVN[9]沒有被改變過,取默認(rèn)值0,因此HCLK = FCLK/4。
PDIVN被設(shè)置為1,因此PCLK= HCLK/2。因此分頻比FCLK:HCLK:PCLK = 1:4:8 。
FCLK提供給ARM920T的時鐘
HCLK 是提供給用于 ARM920T,存儲器控制器,中斷控制器,LCD 控制器,DMA 和 USB 主機(jī)模塊的 AHB總線的時鐘
PCLK 是提供給用于外設(shè)如WDT,IIS,I2C,PWM 定時器,MMC/SD 接口,ADC,UART,GPIO,RTC 和SPI的 APB 總線的時鐘
FCLK與Fin的關(guān)系如下面公式:
MPLLCON寄存器用于設(shè)置FCLK與Fin的倍數(shù)。MPLLCON的位[19:12]稱為MDIV,位[9:4]稱為PDIV,位[1:0]稱為SDIV。
MPLLCON與UPLLCON的值可以根據(jù)參考:
MPLLCON=(0x7f<<12) | (0x02<<4) | (0x01) = 0x7f021
UPLLCON=(0x38<<12) | (0x02<<4) | (0x02) = 0x38022
5、關(guān)閉 MMU、cache
代碼中的c0,c1,c7,c8都是ARM920T的協(xié)處理器CP15的寄存器。其中c7是cache控制寄存器,c8是TLB控制寄存器。325~327行代碼將0寫入c7、c8,使Cache,TLB內(nèi)容無效。
第332~337行代碼關(guān)閉了MMU。這是通過修改CP15的c1寄存器來實現(xiàn)的,先看CP15的c1寄存器的格式(僅列出代碼中用到的位):
V : 表示異常向量表所在的位置,0:異常向量在0x00000000;1:異常向量在 0xFFFF0000
I : 0 :關(guān)閉ICaches;1 :開啟ICaches
R、S : 用來與頁表中的描述符一起確定內(nèi)存的訪問權(quán)限
B : 0 :CPU為小字節(jié)序;1 : CPU為大字節(jié)序
C : 0:關(guān)閉DCaches;1:開啟DCaches
A : 0:數(shù)據(jù)訪問時不進(jìn)行地址對齊檢查;1:數(shù)據(jù)訪問時進(jìn)行地址對齊檢查
M : 0:關(guān)閉MMU;1:開啟MMU
332~337行代碼將c1的 M位置零,關(guān)閉了MMU。
6 、初始化 RAM 控制寄存器
其中的lowlevel_init就完成了內(nèi)存初始化的工作,由于內(nèi)存初始化是依賴于開發(fā)板的,
因此lowlevel_init的代碼一般放在board下面相應(yīng)的目錄中。
對于mini2440,lowlevel_init在board/samsung/mini2440/lowlevel_init.S中定義如下:
7、初始化堆棧、復(fù)制U-Boot第二階段代碼到RAM
* 設(shè)置棧,跳轉(zhuǎn)到board_init_f
*?board_init_f
* 設(shè)置gd結(jié)構(gòu)體
* 初始化函數(shù)
* board_early_init_f函數(shù)在board/samsung/smdk2410目錄下的smdk2410.c文件內(nèi)
* timer_init函數(shù)在arch/arm/cpu/arm920t/s3c24x0目錄下的timer.c文件內(nèi)
* env_init函數(shù)在common目錄下的env_flash.c文件內(nèi)
* init_baudrate函數(shù)在arch/arm/lib目錄下的board.c文件內(nèi)
* serial_init函數(shù)在drivers/serial目錄下的serial_s3c24x0.c文件內(nèi),在include/configs/smdk2410.h中CONFIG_S3C24X0_SERIAL
* console_init_f函數(shù)在common目錄下的console.c文件內(nèi)
* display_banner函數(shù)在arch/arm/lib目錄下的board.c文件內(nèi)
* dram_init函數(shù)在board/samsung/smdk2410目錄下的smdk2410.c文件內(nèi)
env_init最后關(guān)聯(lián)到這個數(shù)組,用于設(shè)置環(huán)境變量
'\0'表示未進(jìn)行設(shè)置
board_init_f 先是把RAM的地方給大家分好,設(shè)置各個模塊的地址,例如堆棧、第二段代碼的鏈接地址,
最后復(fù)制地位段代碼到RAM上去。
8、跳轉(zhuǎn)到第二階段執(zhí)行
2、board_init_r:各種初始化
enable_caches();
board_init(); /* Setup chipselects 、初始化啟動參數(shù)的位置*/
set_cpu_clk_info();
serial_initialize();
nand_init(); /* go init the NAND */
env_relocate();/* initialize environment */
stdio_init(); /* get the devices list going. */
console_init_r(); /* fully init console as a device */
2、開始執(zhí)行 main_loop():執(zhí)行各種命令
main_loop()函數(shù)做的都是與具體平臺無關(guān)的工作,主要包括初始化啟動次數(shù)限制機(jī)制、設(shè)置軟件版本號、打印啟動信息、解析命令等。
參考資料:https://blog.csdn.net/winheroii58/article/details/6803327
bootcmd 、 bootargs這兩個環(huán)境變量比較重要,下面我們介紹這兩個環(huán)境變量
bootcmd
#define CONFIG_BOOTARGS "console=ttySAC0 root=/dev/mtdblock3"
#define CONFIG_BOOTCOMMAND "nand read 30000000 kernel;bootm 30000000"
參考資料:https://blog.csdn.net/g_salamander/article/details/8463854
https://blog.csdn.net/liangkaiming/article/details/5986680
* 一些小知識點(diǎn)
bootm
1.設(shè)置傳遞給內(nèi)核的參數(shù)
2.啟動
代碼中執(zhí)行獲取執(zhí)行bootcmd
s = getenv ("bootcmd");//獲取環(huán)境變量
run_command_list(s, -1, 0);//執(zhí)行環(huán)境變量
總結(jié)
以上是生活随笔為你收集整理的mini2440 u-boot linux 内核启动,u-boot.2012.10——mini2440(二、启动流程分析)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 内核维护,Linux 4.1
- 下一篇: linux 其他常用命令