日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VxWorks动态加载

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VxWorks动态加载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注:最近在做熱補丁的功能,看到一篇gateway寫的文章,覺得很通俗易懂的,就將搜集到的資料又整理了一下,供大家參考。

??????? 使用動態加載目標模塊的方式有很多好處,比如可以在不破壞原來的環境下增加調試定位功能,相當于給系統打“補丁”,不需要編譯原來的代碼(甚至可以不用原來的代碼)而只需要關注正在調試的代碼,這樣能減少編譯時間和減少映像的加載量。

? 實現目標模塊的動態加載有很多種方法,如在主機環境的界面上通過在目標模塊上單擊鼠標右鍵,選擇“Download 文件名”;也可以通過wShell和GDB命令行窗口實現。本文通過tshell下使用ld()、loadModule()、loadModuleAt()中一個函數來實現,當然在代碼中也可以自如地調用它們。

? ld命令是由用戶接口子程序庫usrLib提供的一個加載命令。使用ld的前提是在config.h中定義INCLUDE_LOADER。這樣,在usrRoot()函數中就會自動調用加載模塊初始化函數moduleLibInit();同時,根據CPU類型,自動決定目標模塊的格式。如果CPU是MIPS、PPC、ARM、I80X86、COLDFIRE、SIMSPARCSOLARIS、SH等,加載的目標模塊格式是elf類型,就會調用loadElfInit();如果CPU是I960、AM29XXX等,加載的目標模塊的格式則是coff類型,就會調用loadCoffInit()函數。

? 在ARM和PPC下,Tornado編譯器生成的.o或.out都是elf類型,打開目標文件都會看到文件頭有ELF(45,4C,46)標記。這時可以通過ftp工具把它加載到文件系統(如使用copy命令加載到RAM盤)中,再調用ld()或loadModule()函數加載到內存中運行。

? ld的函數原型是:MODULE_ID ld( int syms, BOOL noAbort, char *name )。參數syms決定目標文件的符號怎么處理:0,添加全局符號到系統符號表中;1,添加全局和局部符號到系統符號表中;-1,符號不添加到系統符號表中。一般選1,便于在shell下使用其中的符號。參數noAbort表明是否可以忽略加載期間出現的錯誤,為TRUE則忽略,FALSE則不忽略。name則為加載的文件名,包含文件路徑。注意:ld是一條shell命令,也就是它是為在shell下調用而設計的一個函數,所以盡量不要用在代碼內部,因為在之后的vxworks版本中直接調用ld可能會不支持。

? loadModule的函數原型是:MODULE_ID loadModule( int fd, int loadFlag )。fd為文件描述符號,需要先打開文件獲取fd;參數loadFlag含義有LOAD_NO_SYMBOLS(2)、LOAD_LOCAL_SYMBOLS(4)、LOAD_GLOBAL_SYMBOLS(8)、LOAD_ALL_SYMBOLS(0xC)三種。

? 假如已經將需要加載的文件demo.o放到ram盤中,則加載到內存中的方式有以下幾種:

(1)-> ld(1,0,”/tffs0/demo.o”)

(2)-> ld </tffs0/demo.o

(3)-> fd = open(“/tffs0/demo.o”,O_RDONLY);

? -> loadModule(fd,0xC);

? ->close(fd);

加載函數返回的是MODULE_ID,這是該加載模塊的標識,使用卸載unldByModuleId時可以模塊ID。查看加載模塊的具體信息的函數是moduleShow()。

? 對于某些應用,使用ld或loadModule會出現以下錯誤:

Relocation value does not fit in 24 bits.

ld error: error loading file (errno = 0x3d0001).

這個問題主要在內存空間大于32M,當往目標機上downloading編譯好的模塊時出現。

原因:

? VxWorks和GNU/Wind River(diab)compiler要遵循EABI(Embedded Application Binary Interface),這是PowerPC架構的一個標準。這個標準對函數的調用是branching而不是jumping,而branching在 PowerPC架構下面是限制在32M以內的。(The PowerPC relative branch instruction is limited to jumps between +/- 32MB (24 bits = +/- 4M instructions, 4 bytes per instruction = +/- 32MB) of the current instruction. If an instruction cannot be resolved within a 24 bit range, it will print out the error above.)

一般來說,如果通過主機往目標機download,是不會出現這個問題的,因為這個時候的目標文件(比如.out文件)是download到了 WDB POOL里面,而WDB POOL是緊挨著VxWorks映像的,所以只要WDB POOL有足夠大的空間就不會出現上述問題。

?而通過目標機download(比如tshell)時,目標文件是download到系統內存池的最后,這個時候如果你的內存大于32M,就會出現上述問題。

? 為了規避這個問題,可以使用長跳轉來完成函數的調用。可以通過在C/C++ compiler下加入編譯選項解決。對于GNU,該選項是-mlongcall;對于diab,該選項是-Xcode-absolute-far。

? 當然也可以使用loadModuleAt()解決這個問題,將目標模塊加載到指定地址,使所需要的函數在跳轉地址以內。其原型是:MODULE_ID loadModuleAt( int fd, int loadFlag, void **ppText, void **ppData, void **ppBss)。ppText、ppData、ppBss分別是加載后的text段、data段和bss段所指向的地址。假如加載demo.o到1M空間處(保證這個空間沒有被占用):

-> fd = open(“/tffs0/demo.o”,O_RDONLY);

-> pText = 0x100000; pData = pBss = 0xffffffff; /* (LD_NO_ADDRESS) */

->?loadModuleAt( fd, 8, &pText, &pData, &pBss);close(fd);

? 加載完成后,在shell下就可以執行最新的目標文件中的函數了。如果函數以前有的,按照最后加載的函數為準。可見,加載的目標模塊都經過重定位、符號解析和添加的過程。

? 如果目標模塊中使用的全局變量或函數在本模塊和以前的程序中都沒有定義,則加載時會出現類似undefined symbol的錯誤。

? 有時候從主機上下載的目標模塊中的函數符號不會出現在目標機的shell中,反過來也一樣,目標機的shell中生成的符號對主機wShell也不可見。出現這種情況的主要原因是目標機和主機的符號沒有同步化,需要在編譯映像時定義INCLUDE_SYM_TBL_SYNC.

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的VxWorks动态加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。