1. 程式人生 > >在虛擬機器上執行vxWorks

在虛擬機器上執行vxWorks

Vxworks是一個嵌入式系統,主要執行在arm、ppc、mips等嵌入式處理器上,它同樣可以執行在X86處理器上。風河公司開發的tornado開發環境就

包括了pentium版本,並且釋出了相應的bsp。因此我們可在vmware虛擬機器上執行vxworks,利用虛擬機器的功能,我們不需要額外的計算機硬體就可

以開始我們的實驗。

系統引導

計算機系統上電後,首先需要執行載入程式,然後載入作業系統。嵌入式系統中一般是將載入程式(稱之為bootrom)固化在ROM晶片(也稱為

bootrom,指的是物理硬體)中。系統上電後執行ROM中的載入程式,將作業系統由flash(或硬碟)載入到記憶體。對於PC而言,系統上電後執行BIOS

程式,之後將軟盤或則硬碟上的引導扇區載入記憶體執行引導過程,載入程式再將作業系統載入到記憶體中啟動。vmware的虛擬硬碟開始時沒有安裝

載入程式,因此無法從硬碟引導。因此我們需要製作一個引導軟盤來引導系統載入vxworks。我們的第一個實驗就是編譯載入程式映象,製作引導

盤。

製作引導盤

首先要在你的PC上Tornado 2.2 for pcPentium開發環境。另外需要安裝pcPentium的BSP包,這個軟體包可以到風河公司的網站免費下載。

製作引導盤當然還需要一張軟盤,但是目前的PC基本都不使用軟盤軟碟機了(如果你的古董機還有軟碟機的話,那麼恭喜你,你只需要一張軟盤就搞定了)。

好在vmware可以直接使用軟盤映象並且可以直接建立軟盤映象,因此我們在vmware中安裝一個虛擬的windowsxp系統,以便在虛擬的windowsXP系統中

將軟盤映象格式化,並製作啟動軟盤。當然也可以使用虛擬軟碟機RamDiskNT在主機上使用軟盤映象。

Ok,準備工作做好了,我們開始編譯bootrom。你可以通過tornado整合開發環境的選單命令build boot rom。

  彈出build boot rom對話方塊,我們選擇pcpentium BSP、編譯bootrom、工具使用gnu

 

編譯完成後可以在$WIND_BASE/target/config/pcPentium目錄下找到編譯出來的bootrom檔案。

我們也可以使用命令列方式編譯bootrom,進入cmd命令列介面,進入

$WIND_BASE/target/config/pcPentium目錄,目錄中有一個Makefile檔案,我們就是使用這個makefile檔案來編譯bootrom。實際整合開發環境也是使用它

來編譯的。編譯之前我們需要設定一下所需的環境變數:

set WIND_BASE=D:/Tornado2.2

set WIND_HOST_TYPE=x86-win32

實際上tornado已經提供了一個批處理檔案用於設定相關的環境變數,這個檔案就是

$WIND_BASE/host/x86-win32/bin/torVars.bat,我們也可以直接執行這個批處理

../../../host/x86-win32/bin/torVars.bat

然後執行命令

make bootrom

就可以在$WIND_BASE/target/config/pcPentium目錄下生成bootrom檔案

把上面的命令寫成一個批處理makeBootRom.bat,方便使用,內容如下:

D:/tornado2.2/host/x86-win32/bin/torVars.bat

cd %WIND_BASE%/target/ config/pcPentium

make bootrom

好了,編譯成功。下一步使用如下命令建立引導盤:

mkboot a: bootrom

mkboot.exe是tornado提供的製作啟動盤的工具,a盤是軟盤的碟符,bootrom就是我們的引導映象檔案。

將製作好的引導盤載入虛擬機器中:

 

虛擬機器上電後自動從軟盤啟動,出現如下介面。

 

是的,你沒看錯,系統確實已經成功啟動,只不過vxworks系統預設是不接受任何輸入輸出的。因此我們看不到它執行的任何東西,也無法操作它。

這樣一個介面讓人很無語,這跟一個人變成了瞎子瘸子沒什麼分別。下一步,我們將console元件加入到bootrom中。

開啟$WIND_BASE/target/config/pcPentium/config.h檔案,找到

#undef INCLUDE_PC_CONSOLE                /* PC keyboard and VGA console */

將它改為:

#define INCLUDE_PC_CONSOLE                /* PC keyboard and VGA console */

那麼結合上下文:

#ifdef INCLUDE_PC_CONSOLE

#   define PC_CONSOLE           (0)      /* console number */

#   define N_VIRTUAL_CONSOLES   (2)      /* shell / application */

#endif /* INCLUDE_PC_CONSOLE */

很明瞭,定義這個巨集之後console就打開了。重新編譯bootrom並製作啟動軟盤。在虛擬機器中執行,會看到如下介面:

輸入p命令,檢視系統的啟動引數,其意義如下:

boot device:fd=0,0 ——啟動裝置為軟碟機,0,0表示第一個軟碟機,3.5寸盤

unit number:0 ——裝置單元號,一般為0

processor:0 ——處理器編號,一般為0

host name:host ——主機名,訪問主機時用到,比如從主機複製檔案:cp “host:src”, “./dest”

file name:/fd0/vxWorks.st ——vxworks映象檔案(包括了完整的路徑)

inet on Ethernet (e):90.0.0.50 ——本地網絡卡ip地址

host inet(h):90.0.0.3 ——主機ip地址

user (u):target ——使用者名稱,用來訪問ftp伺服器,一般都是主機

flags (f):0 ——標識,十六進位制數,它的意義下面再講

BOOT_LINE

bootrom支援從本地磁碟上載入vxworks系統映象檔案,也支援從網路載入vxworks系統映象檔案。在系統開發階段需要頻繁的編譯

和載入系統映象,通常我們使用網路載入的方式,這樣在主機上修改完程式碼,編譯之後就可以通過網路載入到目標機上執行。而

在系統開發後期,或者系統釋出正式執行時,則設定為從本地磁碟載入,此時我們可以將系統映象檔案發在本地磁碟上,開機即

可自動載入執行。從上面的引數可以看出,系統預設從軟碟機載入。可以通過c命令修改這些引數,具體的修改步驟就不說了。也可

以通過配置檔案中的預設bootline來修改這些預設的引數。

開啟$WIND_BASE/target/config/pcPentium/config.h檔案,找到cpu==pcPentium選項下:

#define DEFAULT_BOOT_LINE /

         "fd=0,0(0,0)host:/fd0/vxWorks.st h=90.0.0.3 e=90.0.0.50 u=target"

這就是預設的bootline,bootline的格式如下:

bootDev(unitNum,procNum) hostname:bootFile e=ead b=bad h=had g=gad u=username pw=password f=flags tn=targetName s=startupScript o=other

具體含義:

bootDev / 裝置名,軟盤:fd; 硬碟:ATA;網路要根據網絡卡的型別來做:NE2000及其相容網絡卡為ENE,3COM乙太網卡為ELT,Intel網

卡為EEX,Intel82559網絡卡為fei ,3C905B PCI網絡卡為elPci。

unitNum / 裝置單元號,一般指為0

procnum / cpu的處理器號,一般為0

flags / 標識,十六進位制數,意義如下:

0x01: 關閉對處理器0的系統控制

0x02: 將區域性symbols和全域性symbols裝入目標機symbols表

0x04: 禁止自動啟動(即由使用者輸入boot line)

0x08: 快速boot(不計數等待使用者輸入)

0x40: 使用BOOTP or DHCP client

0x80: 使用TFTP獲取image,否則使用RSH或FTP,用FTP時pw不為空

0x100: 使目標機登記為一個代理ARP client

ead / 目標機ip地址,此值如為空,網路介面不被幫定

bad / 背板介面

had / 主機ip地址

gad / 閘道器地址,如果主機和目標機不在一個局網裡,需要

bootFile: / 存放vxworks image的路徑

usr: / 使用FTP或RSH時的使用者名稱

passwd: / ftp password

other: / 從網路啟動時此值可為空,當從軟盤或硬碟啟動時,如果此值為你的網路裝置,boot會為你繫結網路裝置

hostname: / 主機名,任意

targetName:/目標機名

startupScript: / 指令碼名,在boot以後的target shell裡執行

因為我們要做很多實驗,還是把它配置成網路載入方便一點。修改為:

#define DEFAULT_BOOT_LINE /

         "lnPci (0,0)host:d://ftp//vxWorks h=192.168.1.1 e=192.168.1.2 u=target"

這裡詳細講解一下裝置名稱,對於不同的裝置,其命名格式不同,對於塊裝置的命名規則我們可以在bootconfig.c

檔案的bootLoad函式中找到對應的格式化字串,比如軟碟機的格式是fd=x,x,可以找到如下語句:

             sscanf (params.bootDev, "%*2s%*c%d%*c%d", &drive, &type);

其中"%*2s%*c%d%*c%d"就是對應的格式,星號表示此資料忽略。再例如ATA硬碟其格式字元創為"%*3s%*c%d%*c%d";

對於網絡卡,則需要使用驅動程式中定義的名稱,vxworks一般使用END驅動(Enhanced Network Driver),在驅動程式

提供的xxxEndLoad函式會返回一個裝置名。比如AMD的PCNET-PCI網絡卡,驅動程式檔案為ln97xEnd.c,其中ln97xEndLoad

函式中會返回LN_97X_DEV_NAME

    if (initString [0] == NULL)

        {

        bcopy ((char *)LN_97X_DEV_NAME, initString, LN_97X_DEV_NAME_LEN);

         DRV_LOG (DRV_DEBUG_LOAD, "Returning string.../n", 1, 2, 3, 4, 5, 6);

        return ((END_OBJ *)OK);

        }

LN_97X_DEV_NAME的定義在標頭檔案ln97xEnd.h中:

#define LN_97X_DEV_NAME          "lnPci"      /* name of the device */

修改網絡卡驅動程式

Vmware自帶的虛擬網絡卡是AMD的PCnet-PCI, vxworks自帶的驅動程式(標頭檔案為target/h/drv/end/ln97xEnd.h)據測試在vmware中無法工作。

大家可以試一下,在config.h檔案中定義INCLUDE_LN_97X_END編譯巨集,執行make bootrom命令生成一個bootrom進行測試,你將得到下面的

錯誤提示:

 

因此需要從AMD官方網站下載最新驅動。解壓後得到一個tar目錄,將這個目錄覆蓋$WIND_BASE/tar目錄,然後執行

$(WIND_BASE)/host/x86-win32/bin/ torVars.bat

進入$(WIND_BASE)/target/src/drv/end目錄,執行:

make CPU=PENTIUM tool=gnu ln97xend.o

重新定位到$(WIND_BASE)/target/lib/pentium/PENTIUM/common目錄,並將上一步生成的檔案ln97xend.o複製到此目錄下。

備份此目錄下的檔案libdrv.a;執行命令

arpentium -d libdrv.a ln97xEnd.o,刪除libdrv.a中原有的ln97xEnd模組,然後再執行命令:

arpentium -ra iOlicomEnd.o libdrv.a ln97xEnd.o

將我們剛剛建立的新模組新增進去。這裡的-r選項是表示替換,-a選項表示檔案放在指定檔案(iOlicomEnd.o)之後。

然後我們需要修改配置檔案,使bootrom中包含我們的網絡卡驅動程式,確保

#define INCLUDE_END /* Enhanced Network Driver Support */

#define INCLUDE_LN_97X_END /* (END) AMD 79C97x PCI interface */

而其它的網絡卡驅動巨集都是#undef的。

修改sysLn97xEnd.c

開啟C:/tornado2.2/target/config/pcPentium目錄下的sysLn97xEnd.c檔案,先定位到 “memory-mapped IO

base”這段文字,然後將其前面的引數由pciRsrc[endUnit].bar[1]修改為NONE,儲存即可,

pciRsrc[endUnit].bar[1],     /* memory-mapped IO base */

NONE, /* memory-mapped IO base */

編譯bootrom並製作引導盤啟動虛擬機器,可以看到錯誤沒了,如下圖:

編譯vxWorks

為了測試一下網絡卡驅動功能正常,我們可以編譯一個vxworks映象檔案,然後通過ftp載入到虛擬機器中執行。

編譯vxworks檔案很簡單,只需要在target/config/pcPentium目錄下執行命令

make vxWorks

將生成一個vxWorks檔案,把這個檔案放到ftp目錄下。並且開啟ftp伺服器(這裡使用tornado自帶的wftpd32.exe),

新增一個新使用者user=target, password=target。使用引導盤啟動虛擬機器。載入程式將自動載入這個映象並執行:

可以看到,Attaching network interface lo0… done。並且vxworks已經正常執行。

加入SHELL元件

上面看到的這個介面與我們平時在實驗室看到的不一樣:沒有大大的vxworks的logo。原因是vxworks預設不包含shell元件,需要修改config.h檔案:

#define INCLUDE_SHELL

重新執行makevxwoks命令,生成檔案載入到虛擬機器中,就會出現如下介面,不過此時的shell還不能識別命令,因為製作的映象中沒有符號表,

因此無法解析命令。這樣的shell簡直就是廢材。

 使用符號表檔案

要shell識別命令,需要提供符號表檔案。上面的makefile vxWorks命令在生成vxWorks檔案的同時還生成了一個符號表檔案vxWorks.sym,這個檔案

可用於主機上的WDB進行除錯。首先要配置目標機,在tornado中選擇tools/target serves/config選單命令:

 

彈出如下對話方塊,可以新建一個目標機配置,在Core File and Symbols選項中指定vxWorks.sym檔案,另外需要指定後臺(目標機為後臺,主機為前臺)通訊方式為wdbrpc並設定IP地址: 

                     

設定完成,單擊OK。或者直接單擊Launch啟動,此時在windows的工作列會出現target-server的小圖示,雙擊它可以檢視詳細資訊:

連線成功後,在主介面上的下拉列表中選擇配置的target-server,並單擊->i圖示啟動shell,這時候就可以執行輸入的命令了。如下圖:

雖然使用tornado整合環境進行除錯有直觀的優勢,並且支援原始碼級除錯,一切看起來都很美。但是,目標機與主機之間的通訊通常比較耗時,有時候由於

種種原因還可能出現目標機連線不上的問題。在實際使用時,用得比較多的還是直接在目標機的控制檯中輸入命令進行除錯。這要求把符號表和程式碼一起

下載到目標機上,這裡又有兩種方式:一種是符號表檔案放在主機上,系統啟動時從主機同步符號表;另一種是直接將符號表編譯到vxWorks映象檔案中。

從主機同步符號表

這種方式需要修改配置檔案,在config.h中新增

#define INCLUDE_SYM_TBL_SYNC

當然最好還是加上那些show函式,否則只能打斷點卻不能檢視任務狀態等重要資訊,就像瞎子走路,只能邁動兩腿,卻不知身在何方,是很鬱悶的。新增如下選項:

#define INCLUDE_SHOW_ROUTINES

編譯之後,將vxWorks檔案和vxWorks.sym檔案都放到ftp目錄下。啟動虛擬機器,我們看到它自動將符號表同步了。然後我們就可以直接在控制檯輸入命令進行操作。

編譯vxWorks.st

最為直接的一種方式就是將符號表編譯到vxWork檔案中,這樣不需要連線主機就可以在控制檯上進行操作了。編譯方式也很簡單:

make vxWorks.st

這樣就搞定了。雖然直接將符號表嵌入到vxWorks檔案中,映象檔案的體積會增大,但是現在的硬體這麼便宜。有的嵌入式系統甚至配置了2G記憶體。

因此這個問題越來越容易解決了。