官术网_书友最值得收藏!

第3章 VxWorks操作系統啟動過程詳解

本章將著重分析VxWorks的啟動過程,首先,簡單介紹VxWorks操作系統支持的幾種啟動方式,每種啟動方式下映像的組成和基本啟動流程;其次,詳細介紹下載啟動方式下bootrom的組成和執行流程;再次,詳細介紹VxWorks本身的啟動過程;最后,詳細介紹BSP下的文件組成。

3.1 VxWorks操作系統啟動

3.1.1 VxWorks基本啟動方式

按VxWorks內核的下載形式,VxWorks啟動總體上分為兩種方式:下載型和ROM型。

● 下載型啟動方式:bootrom+VxWorks。此時bootrom被燒入ROM中,而VxWorks內核映像通過串口或者網口下載到系統RAM中。

● ROM型啟動方式:VxWorks直接從ROM中運行,不借助于bootrom引導程序。此時VxWorks內核映像被燒入ROM中,無bootrom程序。

對于不同的啟動方式,VxWorks操作系統內核映像的組成也略有不同。

bootrom引導程序一般稱為VxWorks boot Image。該程序由如下文件創建而成:romInit.s、bootInit.c、sysALib.s、sysLib.c、bootConfig.c、設備驅動程序。

注意

雖然bootrom中包含sysALib.s文件,但是并未使用其中定義的任何函數,這與ROM形式的VxWorks內核映像類似。

VxWorks內核映像一般被稱為VxWorks Application Image。VxWorks內核映像是系統啟動后實際運行的程序(操作系統本身)。對于下載形式的VxWorks內核映像,由于需要對硬件環境進行重新初始化(即不依賴于romInit函數所做的初始化工作),所以最先需要運行sysInit函數進行重新初始化,這些初始化工作與romInit函數基本相同,但是不再需要對內存控制器進行重新初始化,這是sysInit區別于romInit函數之處。sysInit最后跳轉到usrInit函數。而對于ROM方式直接運行的VxWorks內核映像,由于romInit.s函數此時是作為內核映像的一部分,所以就省去了對sysInit函數的調用。下載型和ROM型在VxWorks內核文件的構成上有一些差別。

● 下載形式的VxWorks內核映像組成:sysALib.s、sysLib.c、usrConfig.c、設備驅動程序文件。

● ROM形式的VxWorks內核映像組成:romInit.s、bootInit.c、sysALib.s、sysLib.c、usrConfig.c、設備驅動程序文件。

注意

雖然ROM形式的VxWorks內核映像并未使用sysALib.s文件中的函數(sysInit),但是該文件仍然作為一部分存在于該VxWorks內核映像中。當然用戶可以修改defs.bsp文件中的MACH_DEP宏定義,將sysALib.o從如下形式定義中去掉即可。

                    MACH_DEP =|sysLib.o| sysLib.o $(MACH_EXTRA) $(ADDED_MODULES)

3.1.2 VxWorks操作系統內存布局

在VxWorks操作系統過程中可能使用到的BootRom和VxWorks內核映像本身都可以存在兩種方式:壓縮的和非壓縮的。

1.非壓縮形式

如果沒有進行壓縮,則只有一次重定位,即從ROM到RAM只存在一次代碼復制過程,所有ROM中存儲的代碼都被一次性復制到RAM中。

① 對于BootRom而言,所有的代碼被一次性復制到RAM_HIGH_ADRS指定地址處,如圖3-1所示。

圖3-1 非壓縮版BootRom引導程序ROM及載入RAM后分布圖

② 對于VxWorks_rom而言,所有的代碼被一次性復制到RAM_LOW_ADRS指定地址處,如圖3-2所示。

圖3-2 非壓縮版VxWorks_rom內核映像類型ROM及載入RAM后布局圖

2.壓縮形式

如果有進行壓縮,則代碼復制過程將分為兩次,一次是非壓縮代碼,另一次是壓縮代碼,且二者復制到內存不同的位置處。

① 對于BootRom而言,非壓縮代碼(romInit.s、bootInit.c)被直接復制到RAM_LOW_ADRS處;壓縮代碼復制到RAM_HIGH_ADRS處,并在復制過程中完成解壓縮,如圖3-3所示。

圖3-3 壓縮版BootRom引導程序ROM及載入RAM后分布圖

② 對于VxWorks_rom而言,非壓縮代碼(romInit.s、bootInit.c)被直接復制到RAM_HIGH_ADRS處;壓縮代碼復制到RAM_LOW_ADRS處,并在復制過程中完成解壓縮,如圖3-4所示。

圖3-4 壓縮版VxWorks_rom內核映像類型ROM及載入RAM后分布圖

事實上,對于壓縮版本,在進行編譯時,進行了兩次代碼鏈接:一次是針對壓縮代碼的鏈接,另一次是將非壓縮代碼和壓縮代碼整合在一起時的鏈接。注意,在進行非壓縮代碼和壓縮代碼的整合時,壓縮代碼部分是作為數據進入整個映像的,所以不會對其進行重新鏈接。對壓縮代碼的鏈接,實際上是在代碼被壓縮之前完成的,完成代碼的鏈接后,生成特定格式的目標文件(如ELF或者COFF),為了在解壓縮后可以直接執行,首先必須將其轉成二進制可執行文件,通過objcopy函數完成此項功能,此后對生成的二進制可執行文件調用deflate函數進行壓縮,由于需要將壓縮后的代碼最后整合到整個映像中,故壓縮后的文件還需要通過binToAsm工具進行轉換,轉成一個匯編源文件,該文件將壓縮后的二進制代碼作為數據部分進行保存,從而避免在與非壓縮代碼最后進行二次鏈接時被修改。

兩步鏈接過程中各自指定了不同的鏈接地址,對于壓縮代碼而言,其分為兩種情況,對于BootRom,壓縮代碼被鏈接到了RAM_HIGH_ADRS地址處,而對于VxWorks_rom,則被鏈接到了RAM_LOW_ADRS地址處,在與非壓縮代碼進行整合鏈接時指定的鏈接地址(即_romInit函數地址)與壓縮代碼鏈接時指定的地址相對應:如果壓縮代碼為RAM_HIGH_ADRS,則最后整合時就為RAM_LOW_ADRS;如果壓縮代碼為RAM_LOW _ADRS,則整合時就為RAM_HIGH_ADRS。

3.1.3 下載型啟動方式概述

下載形式的VxWorks啟動方式需要bootrom引導程序,該程序將被燒錄到開發板的ROM或者Flash中,在上電時,系統將自動跳轉到ROM或者Flash起始地址處運行該bootrom引導程序,該引導程序進行必要的系統初始化,從而為下載VxWorks內核映像做準備,如通過網口下載時,則需要先調用網口驅動程序進行網口初始化。

由于bootrom的主要工作是下載真正的VxWorks內核映像到系統RAM中,所以其進行的初始化工作也是為這一目的,在文件組織上,雖然從上文中可以看到其與VxWorks內核映像的文件組成非常相似,但其使用bootConfig.c文件,而VxWorks內核映像則使用usrConfig.c文件。這兩個文件中雖然定義有相同的函數名(如usrInit、usrRoot),但在實現上存在很大的差異:bootConfig.c文件實現完成從某個服務器下載真正的VxWorks內核映像到系統RAM中(由變量RAM_LOW_ADRS指向的內存地址處),并跳轉到sysInit函數(定義在sysALib.s文件中第一個且必須是第一個函數,該函數即被裝載到變量RAM_LOW_ADRS指向的內存地址處)執行;usrConfig.c文件實現完成一個操作系統正常運行所需要的所有初始化工作。簡言之,bootConfig.c文件完成VxWorks內核映像的下載,而usrConfig.c完成初始化VxWorks操作系統的所有工作。

按bootrom執行方式的不同,bootrom文件存在如下三種文件類型。

(1)bootrom.bin

它為壓縮bootrom文件形式,此種文件形式主要為解決開發板上ROM或者Flash的空間限制。注意:壓縮并非對所有的文件進行壓縮,而是除了romInit.s和bootInit.c文件的其他所有文件,因為解壓縮程序必須是非壓縮形式的。

bootrom執行流程如下(以下采用“文件名:函數名:初始是否被壓縮”形式進行說明)。

① romInit.s:romInit:非壓縮。

romInit函數完成系統硬件環境下必要的初始化工作,如從系統角度禁止中斷,初始化相關寄存器到可知狀態,初始化內存控制器,初始化函數調用所需的棧,最后跳轉到romStart函數執行。

② bootInit.c:romStart:非壓縮。

romStart函數主要完成如下任務:

首先將romInit函數及其自身復制到RAM_LOW_ADRS變量指向的RAM區,以便從RAM執行。注意,此后在下載VxWorks內核映像時,內核映像也被下載到RAM_LOW_ADRS變量指向的內存處,所以這部分代碼此后將被覆蓋,同樣,bootrom占用的所有其他內存最后也將被VxWorks內核回收(如由RAM_HIGH_ADRS指向的內核空間)。

● 將bootrom程序其他部分(壓縮部分)從ROM區復制到RAM區(由RAM_HIGH_ADRS變量指向的內存地址處),并解壓縮。

● 對于cold boot(冷啟動)方式,將其復制到RAM區清零。

● 最后跳轉到usrInit(注意:是bootConfig.c文件中定義的)函數進行執行。

③ bootConfig.c:usrInit:壓縮。

usrInit函數此處主要進行外圍硬件初始化,為下載VxWorks內核映像做初始準備,而后創建tUsrBoot進程調用usrRoot程序進一步完成驅動程序初始化工作,為下載VxWorks內核映像做進一步工作,最后創建tBoot進程調用bootCmdLoop函數完成VxWorks的內核映像下載。在下載完成后,調轉到下載起始地址處執行,此時下載型VxWorks內核入口函數sysInit將被調用執行,真正開始VxWorks操作系統的啟動過程。最終在usrConfig.c:usrRoot函數執行完畢后,VxWorks操作系統即完成啟動,系統進入正常運行狀態。函數執行流程如下:(采用“映像類型:文件名:函數名”形式)

bootrom:romInit.s:romInit→bootrom:bootInit.c:romStart→bootrom:bootConfig.c:usrInit→bootrom:bootConfig.c:usrRoot→bootrom:bootConfig.c:bootCmdLoop→完成VxWorks內核映像下載,并跳轉到VxWorks內核入口函數(sysInit)執行代碼→VxWorks:sysALib.s:sysInit→VxWorks:usrConfig.c:usrInit→VxWorks:usrConfig.c:usrRoot→VxWorks操作系統完成啟動。

如圖3-5所示為bootrom完成下載VxWorks內核映像后的RAM布局,此時,之前bootrom占用的所有區域均被VxWorks操作系統回收。

圖3-5 VxWorks操作系統啟動后內存分布圖

(2)bootrom_uncmp.bin和bootrom_res.bin

上述兩種形式的bootrom執行流程基本與bootrom.bin相同。差別在于:

① bootrom_uncmp.bin。

該文件類型為非壓縮類型,所以區別以上壓縮形式的地方在于romStart函數將bootrom從ROM移動到RAM中時,無須進行解壓縮工作,移動到的RAM區地址仍然由RAM_HIGH_ADRS變量指定。注意,對于非壓縮bootrom,所有的代碼(包括已經執行的romInit函數、當前執行的romStart函數、構成bootrom的其他所有函數)都一次性從ROM復制到RAM中,RAM中目的地址由RAM_HIGH_ADRS變量指定,如圖3-1所示。函數執行流程同壓縮版本。

② bootrom_res.bin。

res全稱為resident,此處的意思為程序代碼部分將駐留在ROM中,所以不同于上文中的地方,即romStart函數只復制bootrom引導程序的數據段到RAM_HIGH_ADRS變量指向的RAM區。代碼執行還是從ROM區中取,此種方式一般在開發板ROM區較大時采用,但會增加執行時間,另外,由于需要從ROM中直接執行,故也不能采用代碼壓縮方式。

下載方式中使用的VxWorks內核映像一般命名為“VxWorks”(不包含內核符號表,此時創建一個獨立的內核符號表文件VxWorks.sym,如果需要將內核符號表包含其中,則在config.h文件中定義INCLUDE_STANDALONE_SYM_TBL組件)或者“VxWorks_st”(內含內核符號表),而其他啟動方式(一般就為ROM啟動方式)下的VxWorks內核映像名都具有一個后綴,如VxWorks_rom表示從ROM直接啟動,VxWorks_res_rom表示代碼部分駐留在ROM中,當然也是從ROM直接啟動。下載方式下,VxWorks內核映像文件構成以及完成下載后VxWorks內核函數的調用流程在前文已有介紹,此處不再贅述。

3.1.4 ROM型啟動方式概述

所有的VxWorks內核映像類型中,只有VxWorks類型使用上文中介紹的bootrom引導程序進行啟動,此時VxWorks內核映像放置在主機端,由目標板bootrom完成VxWorks的下載,一般通過網口(或串口)方式進行。其他類型(文件名中帶有rom字樣的)無須bootrom的配合,也即不需要bootrom。因為這些VxWorks類型的內核映像自身(而非bootrom)被燒入開發板系統ROM或者Flash中,均無須進行下載,系統上電時,將直接跳轉到VxWorks內核映像入口函數執行操作系統的初始化工作。

ROM型啟動方式下的VxWorks內核映像類型有以下幾類。

① VxWorks_rom.bin:非壓縮版VxWorks內核映像類型不含內核符號表。如果需要包含內核符號表,則在config.h文件中定義INCLUDE_STANDALONE_SYM_TBL組件。

② VxWorks.res_rom.bin:非壓縮版代碼駐留ROM中執行的VxWorks內核映像類型(含內核符號表)。

③ VxWorks.res_rom_nosym.bin:非壓縮版代碼駐留ROM中執行的,不包含內核符號表的VxWorks內核映像類型。

④ VxWorks.st_rom.bin:壓縮版本的內含內核符號表的VxWorks內核映像類型。

⑤ VxWorks_romCompress.bin:壓縮版的不含內核符號表的VxWorks內核映像類型。

不同的VxWorks內核版本下,在內核映像名稱上會有所變化,但一般都包含在以上類型中。從這些映像類型來看,主要有以下區分:

● 是否為ROM駐留方式,即代碼是否被復制到RAM中執行。

● 是否進行了壓縮。

● 是否包含符號表。

注意

VxWorks內核映像是否包含內核符號表對于后續函數的調用非常重要,如在串口命令行下輸入一個函數名稱,如果內核映像不包含內核符號表,即使在內核中包含該函數定義,在終端也會給出“undefined symbol”錯誤。

以下從三個不同角度介紹它們的不同點,首先以VxWorks_rom.bin文件類型介紹執行的基本流程(采用“文件名:函數名”方式)。

1)romInit.s:romInit。

此處romInit函數完成的工作同bootrom,實際上,二者使用相同的romInit函數實現。

2)bootInit.c:romStart。

首先將其自身復制到RAM_HIGH_ADRS變量指向的RAM區,以便從RAM執行。注意與上文中bootrom的區別,雖然使用的是相同的romStart函數實現,但在RAM地址上存在差別,關鍵點在于VxWorks內核映像被復制到RAM_LOW_ADRS指向的內存地址處。

romStart函數完成如下任務:

● 由于是非壓縮版本的VxWorks內核映像,故所有的代碼一次性從ROM復制到由RAM_LOW_ADRS變量指向的RAM內存處。

● 對于cold boot(冷啟動)方式,將其他BSS區清零。

● 最后跳轉到usrInit(注意:是usrConfig.c文件中定義的)函數進行執行。

3)此后的執行流程為:usrConfig.c:usrInit→usrConfig.c:usrRoot。usrConfig.c:usrRoot函數執行完畢后,VxWorks操作系統即已完成啟動,系統進入正常運行狀態。

其他ROM型VxWorks內核映像啟動流程差別如下:

1)是否為ROM駐留方式。

對于ROM駐留方式而言,在以上第一步中只將數據部分從ROM載入到由RAM_LOW_ADRS指向的內存區域,代碼仍然滯留在ROM中,此后一直從ROM中讀取代碼執行,此種執行方式造成效率的部分損失,一般也較少使用。涉及的文件類型為:

        VxWorks.res_rom.bin和VxWorks.res_rom_nosym.bin。

2)是否進行了壓縮。

對于壓縮的VxWorks內核映像,在以上第一步復制中,將分兩個階段完成:第一階段完成非壓縮代碼(romInit函數、romStart函數)的復制,這部分代碼被復制到RAM_HIGH_ADRS指向的RAM內存處;第二階段完成壓縮代碼的解壓縮和復制過程,這部分代碼被解壓縮到RAM_LOW_ADRS指向的RAM內存處。

3)是否包含了符號表。

所謂符號表,是內核中定義的所有函數與其(虛擬)地址的對應關系表。符號表與VxWorks內核映像一般是分離的,為了調試方便,一般需要獨立的載入符號表,當然也可以將符號表納入VxWorks內核映像中作為一個整體。VxWorks.st_rom.bin文件類型即將符號表作為了內核映像的一部分。

符號表最大的作用是在命令行直接輸入函數名即可運行該函數,內核查詢符號表獲得對應的地址并轉到該地址處執行。另外,在調試時,也可以對地址進行函數名標注,從而方便調試,符號表與VxWorks內核通常是獨立的,所以無論是否包含符號表,都不會對內核初始化流程造成影響。當VxWorks內核映像被載入RAM后,進入usrInit函數執行時,最終分布圖如圖3-5所示。

ROM型VxWorks內核映像類型啟動流程總結如下(由于其中只涉及VxWorks內核,故采用“文件名:函數名”方式)。

romInit.s:romInit→bootInit.c:romStart→完成VxWorks內核從ROM到RAM的復制(和解壓縮)→usrConfig.c:usrInit→usrConfig.c:usrRoot→VxWorks操作系統啟動完成。

主站蜘蛛池模板: 南京市| 横山县| 湘潭市| 乌拉特中旗| 崇信县| 夏河县| 宁强县| 凤山市| 都江堰市| 安阳市| 芦溪县| 通渭县| 泸溪县| 高青县| 宁海县| 吉隆县| 老河口市| 奈曼旗| 长沙市| 邯郸县| 黎川县| 喀什市| 莱州市| 武定县| 峡江县| 庄浪县| 辽阳市| 巴东县| 阿勒泰市| 明溪县| 眉山市| 大姚县| 板桥市| 阳高县| 南康市| 东乌珠穆沁旗| 绥阳县| 谢通门县| 庆城县| 沅江市| 南澳县|