您好,欢迎访问三七文档
分类:LINUX原文地址:ARM(S3C2440)下解决的非法指令问题(Illegalinstruction)作者:mxcai2005最近在学习和做项目的时候需要搭建s3c2440的环境,遇到了一些问题(非法指令)和大家分享一下修正错误的过程。一、我先介绍一下我们的实验环境:内核版本:kernel-2.6.27-android_ok编绎器:arm-2010q1-202-arm-none-linux-gnueabi硬件:(S3C2440)支持armv4t指令,busybox版本:busybox-1.17.0我们这次实验的kernel相对来说版本不算老,编译可就是非常新的了。他支持ARMV7,就是cortex-A8,A9系列的。而我们的硬件s3c2440只有armv4t的指令集。二、问题的出现:我们用新的编译器编译出来的uboot,kernel均能正常执行。当我们用它来编译busybox,并且生成静态busybox的时候,有时候执行正常,有时候执行就不正常。不正常的时候出现如下提示:Illegalinstruction这个错误表明我们的程序执行了不正确的指令。一般这种情况是因为我们编译起编译出了较高版本的ARM指令造成的。三、排错排错1:让编译器编译出支持s3c2440的armv4t,在网络上查询得知增加“-march=armv4t”选项即可。于是在busyboxmakemenuconfig中编译选项中加入了上述参数,见下图增加-march=armv4t残酷的事实验证后,结果发现还是不行。这是为什么,我们该怎么做?有两个问题困扰着我:1.出现的非法指令是在哪,是什么指令?2.所加入的参数到底有没有起作用?排错二:现来寻找上述第一个问题的答案,由于在交叉编译过程中产生了非法指令,故在执行过程中会产生异常,我们进入到内核的非法指令异常去看看。于是到内核(arch/arm/kernel/traps.c)中找到相关的异常处理函数(do_undefinstr)其中部分代码为:#ifdefCONFIG_DEBUG_USERif(user_debug&UDBG_UNDEFINED){printk(KERN_INFO%s(%d):undefinedinstruction:pc=%p\n,current-comm,task_pid_nr(current),pc);dump_instr(regs);}#endif通过上面的代码我们如果CONFIG_DEBUG_USER定义了,并且user_debug设置了参数,应该可以看到系统打印是哪个程序产生了异常。通过kernel的.config文件发现CONFIG_DEBUG_USER已经定义了。user_debug是一个命令行参数。好了我们可以通过uboot打开:打开的方法为在U-bootbootargs添加user_debug=1;(egs:setenvbootargsconsole=ttySAC0,115200user_debug=1saveenv);在LINUX再次执行程序,发现在原先的出现“指令错误”的上方多出了两条具体的错误信息。打印出非法指令信息以上图片中,是执行mdev(mdev,是busybox的子程序)时出错。pc=000ca8b4,是指mdev的ca8b4处有个非法指令。接下来从busybox中找出次指令:进入busybox目录,输入命令(arm-none-linux-gnueabi-objdump-Dbusyboxbu.S意思为将生的目标文件的汇编代码dump到bu.S文件中),打开bu.S(命令:vimbu.S)文件,根据出现“指令错误”上面两条具体指令错误位置信息可以找到非法指令指置,我们查到该位置为clz指令:在ARM官方网上息查询得知clz指令相关信息:(=/com.arm.doc.dui0204ic/Cihjgjed.html)clz指令体系结构:此ARM指令可用于ARMv5及更高版本。此32位Thumb指令可用于ARMv6T2及更高版本。此指令无16位Thumb版本。我们最终找到出现非法指令的位置,以及是什么指令。好,接下来,我们需要第二步,回到busybox本身:我们想把编译过程中的参数给打印出来,通过查看busybox中的Makefile,得知由quiet_决定,我们在编译busybox时加入选项参数V=1(egs:makeV=1);通过编译过程所打印的信息知所加的选项参数在编译的时候起了作用,但在链接生成静态库的时候并没有起到作用。虽然知道在makemenuconfig加了相关参数(-march=armv4t),编译器并没有去执行这条语句,可能的原因是:我们所加的参数的格式不正确,或其它原因等)。于是我们就想找一种能解决此问题的方法。下面给出一种针对上述问题的解决的方案:为了以防万一,我们手动将编译链接的地方都增加了(-march=armv4t)我们可在busybox中的Makefile.flags中找到静态链接的位置以及编译的位置:将:ifeq($(CONFIG_STATIC),y)CFLAGS_busybox+=-staticendif修改为:ifeq($(CONFIG_STATIC),y)CFLAGS_busybox+=-static-march=armv4tendif将:CPPFLAGS+=$(callcc-option,-std=gnu99,)修改为:CPPFLAGS+=$(callcc-option,-std=gnu99-march=armv4t,)再进行编译就生成了我们所需指令版本的目标文件了。相关软件下载地址:交叉编译器:arm-2010q1-202-arm-none-linux-gnueabi下载地址:具体为RecommendedPackagesbusybox-1.17.0下载地址:以上错误由第一小组共同完成,由aka522整理。E-mail:aka522@foxmail.com参与人员有:lili,aka522,dubo,fengximing
本文标题:ARM(S3C2440-)下解决的非法指令问题(Illegal-instruction)
链接地址:https://www.777doc.com/doc-4594815 .html