今天到了星期日下午,開始分析usrRoot()函數,看看這個函數實現了哪些功能。
(1) memInit (pMemPoolStart, memPoolSize); /* initialize memory pool */
我們知道在romstart函數中已經對記憶體進行了清零,這個記憶體池是幹什麼用的呢。搜了半天也沒有資料具體說到底是如何初始化記憶體的,根據以前調試QNX的經驗來看,我個人覺得這一步很可能為了確保相應記憶體的清零操作。
(2) usrMmuInit (); /* initialize the mmu */
初始化MMU單元,這個比較容易理解,MMU就是記憶體管理單元,負責管理虛擬位址,可以保證每個使用者進程都有自己獨立的地址空間使用,及時兩個不同的進程讀寫相同的記憶體虛地址,實際上讀寫的物理地址是不一樣的。這裡就初始化MMU單元,開啟函數可以看到,針對不同CPU類型載入相應的庫函數進行初始化。
(3)時鐘設定
sysClkConnect ((FUNCPTR) usrClock, 0); /* connect clock ISR串連系統時鐘中斷服務程式*/
我們知道,作為一個多任務作業系統,任務環境切換是最基礎的功能,系統調度用到的就是系統時鐘中斷,這裡的時鐘設定就提供了這樣的功能。有了這個機制,接下來才可能實現多線程。其中掛接的中斷處理常式在什麼地方呢。原來VxWorks提供的usrClock()函數是系統預設時鐘中斷處理函數,用來調用計數器函數tickAnnounce(),實現系統計數器的作用。
sysClkRateSet (SYS_CLK_RATE); /*set system clock rate設定每秒鐘系統時鐘中斷次數,預設中斷頻率為60,一般在60到100,但不能大於600,也就是1s產生60次中斷,大概是16.67ms*/
這裡有一個有意思的話題,就是按照預設的中斷頻率60次,是不是設定的越高即時性就越高呢。其實並不是這樣的,VxWorks手冊建議不要將時鐘率設得太高,否則它就由硬即時變得趨向於軟即時了。因為過高的時鐘率使得核心調度頻繁進入,更可能導致一些低優先順序的硬體中斷不能得到及時響應。
sysClkEnable (); /* start it使能系統時鐘中斷*/
(4) selectInit (NUM_FILES);這個函數是幹啥的呢。說是_func_selWakeupListInit函數需要其先進行初始化
(5) iosInit (NUM_DRIVERS, NUM_FILES, "/null");,初始化IO系統,這裡面限制了最多同時開啟20個裝置以及50個檔案,也申請一些記憶體空間,包括裝置表,裝置的驅動函數表等。
(6) ttyDrv(); /*install console driver */
ttyDrv是一個字元型裝置,負責串口與IO系統之間的互動。裝置驅動的初始化過程首先調用系統函數ttyDrv(),該函數通過調用iosDrvInstall()將ttyOpen()、ttyIoctl()、tyRead()、tyRead、tyWrite安裝到系統驅動函數表中,供I/O系統調用。其實理解起來一點都不難,就像我之前寫的QNX 的SD卡driver的流程一樣,負責底層魚上層的互動。驅動模組初始化成功後,應用程式就可以用標準的I/O函數read()和write()收發資料了。
有一個問題是,ttyDrv初始化的是哪個串口呢。往下看。
在下面一些代碼中就找到了一個可用的串口,就是sprintf (tyName, "%s%d", "/tyCo/", ix);
於是就找到了/tyCo/0,ttyDrv()實現了驅動函數與IO系統標準POSIX介面的對接,然後通過
(void) ttyDevCreate (tyName, sysSerialChanGet(ix), 512, 512);建立一個串口0的驅動程式,如果是系統CONSOLE_TTY口的話,就開啟,並且進行設定。
consoleFd =open (consoleName, O_RDWR, 0);
(void) ioctl(consoleFd, FIOBAUDRATE, CONSOLE_BAUD_RATE);
(void) ioctl(consoleFd, FIOSETOPTIONS, OPT_TERMINAL);
通過
ioGlobalStdSet(STD_IN, consoleFd);
ioGlobalStdSet (STD_OUT,consoleFd);
ioGlobalStdSet (STD_ERR,consoleFd);
將標準輸入輸出定位到控制台上,就可以實現使用printf實現對控制台的調用了。
(7) 接下來初始化一些結構、訊號、管道、調試資訊、標準IO函數庫、訊號隊列、訊號量、線程庫、訊息佇列,以及一些POSIX功能支援。
dosFsLibInit( 0 ) dosFsLibInit中調用iosDrvInstall將7個函數指標填入驅動程式表中,並得到一個驅動號表中各函數的入口對應檔案系統提供的相應函數。
(8) /*initialize USB components */
包含了一系列的USB裝置初始化,包括USBhost協議棧、滑鼠、鍵盤、印表機、擴音器等等。
(9) SCSI裝置初始化
什麼是SCSI。在Tornado DeviceDriver Workshop一書中解釋為Small Computer System Interface,其目的為提供獨立的裝置介面,其優點在於一個控制器就可以控制多個外設,這就提供了一種驅動編寫方法,以後再研究。
(10)對ideDrvIDE 硬碟的驅動、SATA硬碟的支援、PCMCIA卡、tffs flash檔案系統、對於浮點數軟體以及硬體計算的支援、任務調度工具、時間工具、設定環境變數、模組管理器、引導裝置初始化等。
(11) usrNetInit()網路裝置初始化。
稍後再仔細對SCSI裝置以及usrNetInit()網路初始化進行分析。