openwrt 編譯node.js功能(解決Illegal instruction錯誤)

一、硬件平臺

    MT7620(A9內核)


二、軟件平臺

    1、Ubuntu 12.04 

    2、openwrt 官方15.05版本SDK開發包

三、功能說明

    本文章主要說明如何在openwrt 系統上,編譯node.js功能以及簡單的使用。對於node.js運行之後,產生的"Illegal instruction"如何處理的問題。

四、編譯步驟

    1、node.js功能在 “ Languages --> Node.js --> node”中。故進入到openwrt的SDK包目錄,執行“make menuconfig”命令,選中Languages 選項,如圖4-1所示。

圖4-1 menuconfig選項

    2、在Languages菜單中,選擇node,如圖4-2所示。

圖4-2 Languages菜單

    3、在node.js中,選擇node選項,如圖4-3所示。

圖4-3 node.js菜單

    4、選擇node完畢之後,保存內核配置,退出。執行編譯命令 “make V=s”,編譯出內核。

五、測試node.js功能

    5.1、查看版本號

    將編譯出的內核,燒錄到開發板上,運行“node -v”,查看版本號。

圖5-1 查看node版本號

    5.2、測試node.js語法功能

    在/tmp/目錄下,編寫一個測試程序, “vi /tmp/test.js”。測試程序的內容爲一個簡單的輸出信息,代碼如下。
console.log("hello world");
    保存完文件,用node運行該文件,結果如圖5-2所示,運行之後,錯誤提示“Illegal instruction”。

圖5-2 Illegal instruction錯誤報告
    

六、Illegal instruction 錯誤分析

    6.Illegal instruction 介紹

    對於“Illegal instruction”錯誤,即SIGILL, 是POSIX標準中提供的一類錯誤。 從名字上看,SIGILL是啓動的某個進程中的某一句不能被CPU識別成正確的指令。 此類錯誤是由操作系統發送給進程的,在進程試圖執行一些形式錯誤、未知或者特權指令時操作系統會使用SIGILL信號終止程序。 SIGILL對應的常數是4。

    6.2 錯誤原因彙總

    6.2.1 將不正確的數據寫入代碼段

    進程在代碼段中的數據是要被作爲一個指令執行的。 若不小心覆蓋了已有的代碼段,可能會得到錯誤格式的指令。這種錯誤尤其在Just-In-Time即時編譯器中最可能出現。
    同樣,如果不小心覆蓋了棧上活躍記錄中的返回地址,程序就可能根據這個錯誤地址,執行沒有意義的內存中的數據,進而操作。進一步可以認爲,任何導致數據錯誤的問題都可能帶來illegal instruction問題。比如硬盤發生故障。

    6.2.2 指令集的演進

    比如SIMD指令,自從奔騰4開始有MMX,X86的芯片就開始不停的增加和拓寬SIMD支持,SSE、SSE2、SSE3、SSE42、AVX、AVX2。 默認情況下,很多編譯器都在O2或者O3中開了自動向量化,這就導致很多在新體系結構中編譯的可執行程序,在老機器上運行時會有illegal instruction問題。

    6.2.3 工具鏈bug

    對於普通C語言通過編譯器生成的可執行程序。一般都已經通過嚴格的測試,不會隨便發生這種問題。 所以如果你遇到這種錯,並且試過了靜態鏈,而且程序中沒有嵌入式彙編,基本可以斷定是工具鏈出了問題。 編譯器、彙編器或者鏈接器。

    6.2.4 訪存對齊或浮點數格式問題

    根據Heiher的經驗,請注意出現錯誤的指令可能和訪存地址指令有關。 另外,浮點數的格式是否符合IEEE的標準也可能會有影響。

    6.3 錯誤分析

   (1)執行的test.js文件,爲一個簡單的打印信息,不涉及到任何的堆棧操作和錯誤格式的指令,故不可能爲“將不正確的數據寫入代碼段”錯誤。
   (2)node.js工具,採用gcc2.21編譯,而且與內核一起編譯,採用的同一個工具鏈,所以不可能爲“指令集的演進”錯誤。
   (3)採用的交叉工具鏈爲openwrt SDK開發包提供的標準工具鏈"gcc 2.21"版本,所以不可能爲“工具鏈bug”錯誤。
   (4)運行的程序爲訪問地址操作,所以不是“訪問內存對齊”的問題,只能爲“浮點數格式”問題。而且,經過查找SDK包的內核配置,發現確實沒有配置"MIPS FPU Emulator"選項。
    最終,得出結論,是內核配置中,沒有配置芯片的FPU,導致浮點運算有問題。

七、Illegal instruction 錯誤解決方案

    對於MIPS架構的FPU,配置路徑爲“kernel type --> MIPS FPU Emulator”。
    1、在openwrt的SDK目錄下,運行命令“make kernel_menuconfig”,選擇配置“kernel type”,如圖7-1所示。

圖7-1 內核配置菜單

    2、在"kernel type"中,選中"MIPS FPU Emulator",如圖7-2所示。
 
圖7-2 選擇MIPS FPU Emulator

    3、配置完畢之後,保存退出,並執行編譯命令“make V=s”,編譯出新的內核。
    4、將新的內核燒錄到開發板上,再次編寫測試程序,並運行,結果如圖7-3所示,成功的輸出了測試日誌“hello world”,說明問題得以解決。

圖7-3 測試node.js 功能

    
發佈了44 篇原創文章 · 獲贊 20 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章