VxWorks啟動代碼usrInit ()函數分析
DanielLee_USTB 2013-6-14晚
QQ:382899443
又到周五晚上了,明天不用加班,真是美好的一天。現在看vxworks啟動的第三個主要函數usrInit()。
這個函數是在RAM中執行的第一個函數,主要完成對BSS段的清除、設定異常向量、然後調用sysHwInit()初始化硬體。什麼是BSS段呢。所謂BSS就是用於存放未初始化的全域變數和靜態變數的一塊記憶體地區。
第一句是
while (trapValue1 != TRAP_VALUE_1 ||trapValue2 != TRAP_VALUE_2)
{
/* infinite loop */;
}
這用於檢查是否能正確調用到資料區段,如果資料區段沒有被拷貝到相應的RAM地區,或者拷貝過程出錯,那麼程式就將死在這裡,這樣做也可以提供一種調試手段。
SYS_HW_INIT_0();
cacheLibInit (USER_I_CACHE_MODE,USER_D_CACHE_MODE);
是用來開啟cache的函數,與定義的CPU有關。那麼arm的cache有什麼用呢,根據應用資料訪問資料集中性原理,其實就是去查詢最常用的資料,可以提高處理速度。
bzero (edata, end - edata); /* zero out bss variables */
這就是清除BSS段的資料,其實bzero 調用的是memset函數, edata被指向了ROM中的一塊地址空間。
excVecInit (); /* install exceptionvectors */
在原始碼中經常會看到這樣的情況,好多函數都是像extern STATUS excVecInit ()這樣的外部函數,都是系統內建的,去初始化系統所有預設中斷向量。
sysHwInit (); /* initializesystem hardware */這個函數在920t/sysLib.C中,看看都初始化了什麼硬體。
其實主要初始化了兩個硬體,一個是PCI一個是串口,暫時不關心PCI的初始化,串口才是我們看的重點。sysSerialHwInit(),的位置是在920t/sysSerial.c中,這個函數擷取了預先定義的串口基地址、傳輸速率、時鐘等資訊調用primeCellSioDevInit()à調用ambaInitChannel()去初始化晶片。作業系統初始化一個串口真是費勁,居然經過這麼多層才到關鍵位置,不過這也體現了人家編寫代碼的層次性。對於串口的初始化沒啥好說的,FIFO、控制寄存器、時鐘寄存器等一個不能少,比較容易理解。
初始完串口,能列印東西了,可是初始化的到底是哪個串口呢。
看到:
LOCALSYS_AMBA_CHAN_PARAS devParas[] =
{
{INT_VEC_UART_0, (UINT32 *)UART_0_BASE_ADR, INT_LVL_UART_0},
{INT_VEC_UART_1, (UINT32 *)UART_1_BASE_ADR, INT_LVL_UART_1}
};
說明這兩個串口都初始化了。
usrKernelInit ();
到這步就要初始化系統核心,位置在src\config\usrKernel.c中主要是配置作業系統的一些機制,這些都是不用變得,以後移植的話也不用管。
cacheEnable();
配置好cache就可以使用了,使能cache。
kernelInit(),建立第一個任務usrRoot,進一步去初始化板子硬體,這些都是啟動vxworks核心之前的准工作,其位置在config/all/usrConfig.c中。可以先看看他的注釋:
/*It initializesthe I/O system, installs drivers, creates devices, and sets
* up thenetwork, etc., as necessary for a particular configuration.
*/
Vxworks系統之所以寫的好,很詳細的函數注釋是一方面。通過這些注釋,很容易知道它的作用,具體內容比較多,下次再詳細分析。
總結一下,usrInit主要實現了清零BSS、設定預設中斷向量、初始化串口、使能cache、以及建立第一個usrRoot的根任務初始化一些基礎的機制和裝置。