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 功能

    

猜你喜欢

转载自blog.csdn.net/xhoufei2010/article/details/51627417