BTS Patch想法和實現
目的:
不重啓BTS(系統是VxWorks on PowerPC)動態調用一個新函數,替換原來的舊函數,以達到Patch的功能。如能實現至少能在debug的時候起作用,不用編譯整個應用程序,不用重新啓動系統,節省時間。
(在nortel交換機上有該功能,現想在基站、即BTS上實現)
原理:
在舊函數,即想被替換的函數的開始地址插入一個jump指令,無條件跳轉到新的函數起始位置,執行新函數,從而達到patch的功能。
Limitation:
static變量將會被重置爲0。
實現:
首先要啓用已經放棄多年的xdm ftp模塊,實現把新函數(編譯好的.o文件)上傳到BTS的功能,並把.o文件存放在BTS的flash儲存器裏面。
由於新函數可能要用到原來應用程序裏有的函數或者變量,所以在本機上編譯了.o文件以後,其應該被外加一個文件頭,裏面存有該新函數要用到的另外的symbol的地址(用nmppc工具在.o文件和.corefile文件裏提取)。
.o文件上傳以後應被與文件頭分離,程序把文件頭裏的symbol加入VxWorks裏的系統符號表裏,如此以後在執行新函數的時候就能正確得知這些symbol的位置。
分離了文件頭以後可以調用VxWorks的API,loadModule(),把新函數動態連接進內存。
如果連接成功,就可以改動舊函數的代碼段,插入一個jump指令,讓其跳轉到新函數,完成。
已解決的未預想到的問題:
1。flash儲存的寫入問題。
2。新函數不能正確找到所需symbol的地址。
3。把新symbol加入到系統符號表的問題。
問題:
1。代碼段內存寫保護,稍有改動就重啓,現並沒有解決辦法。
2。新函數儲存地址比較遠,普通24位offset的jump指令並不能正確尋址。
問題:
1. VxWorks代碼段內存保護,不能隨意改動舊函數的代碼段。這意味着不能加入jump指令跳轉到新函數。
2. jump指令。PowerPC沒有長跳轉的指令,如果要跳轉到一個遠地址必須把地址放入某特殊寄存器,然後跳轉。
3. 如果舊函數正在被某進程執行,而需要插入的指令大於一條。如不作判斷便更改代碼段將出現嚴重問題。
解決:
1. 經過查看VxWorks操作系統代碼,發現一個可用的內部函數“memProtectStateSet()”,可以將某個內存段的保護狀態修改,不需要重啓板子。執行這個函數後便可指定某個代碼段可寫。
2. 只能採用多條指令實現跳轉。並研究其指令二進制格式,把指令手工轉換成word32寫入代碼段。
3. demo裏決定不解決該問題。暫時想法是搜索所有進程,如有正在運行該代碼段將等待,如果超時則返回打補丁失敗。