MIPS交叉编译错误:非法指令
Posted
技术标签:
【中文标题】MIPS交叉编译错误:非法指令【英文标题】:MIPS cross compilation error: illegal instruction 【发布时间】:2014-07-18 10:34:29 【问题描述】:我想为 MIPS 机器交叉编译 C src,但编译失败。在目标机器上执行交叉编译的二进制文件会输出“非法指令”。你能告诉我如何为 MIPS 机器编译 C src 吗?
详情如下:
执行“readelf -h host.bin”(host.bin是在HOST机器上运行的二进制程序)输出:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x8048aac
Start of program headers: 52 (bytes into file)
Start of section headers: 8628 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 9
Size of section headers: 40 (bytes)
Number of section headers: 30
Section header string table index: 27
执行“readelf -h target.bin”(target.bin是在Target机器上运行的二进制程序)输出:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x403570
Start of program headers: 52 (bytes into file)
Start of section headers: 114040 (bytes into file)
Flags: 0x5, noreorder, cpic, mips1
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 6
Size of section headers: 40 (bytes)
Number of section headers: 23
Section header string table index: 22
执行“readelf -h cross_compiled.bin”输出(cross_compiled.bin 是(由我)为目标机器交叉编译的二进制文件):
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: MIPS R3000
Version: 0x1
Entry point address: 0x400170
Start of program headers: 52 (bytes into file)
Start of section headers: 16444 (bytes into file)
Flags: 0x1007, noreorder, pic, cpic, o32, mips1
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 5
Size of section headers: 40 (bytes)
Number of section headers: 21
Section header string table index: 20
对于交叉编译,我使用了支持 MIPS1 交叉编译的 buildroot。
我希望 cross_compiled.bin 在目标机器上正常执行。但是,当我在目标机器上执行“cross_compiled.bin”时,它会输出“非法指令”。
您能告诉我如何解决上述问题吗?由于我是交叉编译的新手,所以我找不到问题的确切原因。
任何 cmets 将不胜感激。
更新:
在目标上,执行“cat /proc/cpuinfo”输出:
system type : Broadcom BCM5354 chip rev 3
processor : 0
cpu model : BCM3302 V2.9
BogoMIPS : 237.56
wait instruction : no
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : no
hardware watchpoint : no
VCED exceptions : not available
VCEI exceptions : not available
unaligned_instructions : 1
dcache hits : 0
dcache misses : 0
icache hits : 0
icache misses : 0
instructions : 0
在目标上,执行“cat /proc/version”输出:
Linux version 2.4.20 (ronger@ronger-linux.sh.deltagroup.com) (gcc version 3.2.3 with Broadcom modifications) #1 Tue May 22 17:40:19 EDT 2007
我用于交叉编译的命令行(cross_compiled.bin):
mipsel-linux-gcc -static -o cross_compiled.bin cross_compiled.c
cross_compiled.c:
#include <stdio.h>
int main()
printf("Hello World\n");
return 0;
由于我的 cross_compiled.c 非常简单,我相信没有与使用的库相关的问题。
【问题讨论】:
尝试使用 gdb 之类的东西(可能在目标上使用 gdbserver 的主机上)来查看失败的指令。 由于我的目标机器没有gdbserver,所以无法使用gdb。 (要在Target上安装gdbserver,我需要为Target机器交叉编译二进制,这意味着我的问题解决了) 您能否在工作和非工作二进制文件上使用交叉 objdump 来查看指令是否合理?不过,您的系统供应商或分销商应该能够将您指向目标的工作工具链,并且那里的实用程序源应该包括构建标志。 您能发布更多信息吗?也许/proc/cpuinfo
和/proc/version
在目标上的输出?您是否首先尝试交叉编译最简单的“hello world”程序来排除库问题? (例如)如果可能的话,用于编译和/或链接的 gcc 命令行?
@ChrisStratton 我可以对这两个二进制文件进行 objdump,但我可以找到不合理的指令(可能是由于缺乏对 MIPS 指令的了解)。
【参考方案1】:
可能是各种原因造成的;我从您的帖子中可以看到的一件事是您的二进制文件和它们的二进制文件之间的 ELF 标志是不同的。内核也很老了,你自己的buildroot也没有报告gcc的版本。
我注意到该芯片组 (BCM5354) 与 DLINK DIR-320 和其他芯片组中使用的相同,而 OpenWRT 恰好支持这些芯片组。假设您还没有使用 OpenWRT 作为 buildroot,我会再次尝试使用 OpenWRT。
相反,您可以从 DLINK 支持网站下载 DLink 提供的 GPL 源代码,其中应包含 buildroot 并尝试。考虑到用于构建目的地的内核和 gcc 的年龄,以及主干 OpenWRT 的新颖性,您可能想尝试找到支持该路由器的 OpenWRT 的最旧版本,或者首先尝试 DLINK 构建根。
如果您有几台计算机,您可以同时尝试两个 buildroot...
如果这不能解决问题,您需要发布更多信息
【讨论】:
您能告诉我为什么不同的标志会导致问题吗? 有什么方法可以概括这个答案?它解决了 OP 的问题,但没有提供任何实际解决问题的方法。【参考方案2】:我使用mipsel-linux-gcc
(版本 4.5.3)编译了你的 hello world 程序。这是 mipsel-linux-objdump -d -S
在你的 hello world 程序上运行时的输出。该程序在我办公桌上的 Broadcom 7425 little endian 机器上运行良好。
004002a0 <main>:
4002a0: 27bdffe0 addiu sp,sp,-32
4002a4: afbf001c sw ra,28(sp)
4002a8: afbe0018 sw s8,24(sp)
4002ac: 03a0f021 move s8,sp
4002b0: 3c020040 lui v0,0x40
4002b4: 24444490 addiu a0,v0,17552
4002b8: 0c1000b8 jal 4002e0 <puts>
4002bc: 00000000 nop
4002c0: 00001021 move v0,zero
4002c4: 03c0e821 move sp,s8
4002c8: 8fbf001c lw ra,28(sp)
4002cc: 8fbe0018 lw s8,24(sp)
4002d0: 27bd0020 addiu sp,sp,32
4002d4: 03e00008 jr ra
4002d8: 00000000 nop
4002dc: 00000000 nop
您的反汇编编译器输出应该与此非常相似。如果不是,请更新您的问题。
【讨论】:
谢谢!我在主函数中找到了“bal”指令。对 mips1 指令集有效吗? 我在 MIPS 1 ISA 上找不到任何文档,所以我无法回答这个问题。您可以尝试使用JAL
而不是BAL
来修补二进制文件,看看是否可以解决问题。以上是关于MIPS交叉编译错误:非法指令的主要内容,如果未能解决你的问题,请参考以下文章
基于MIPS ARM架构平台, Ubuntu20.xx版本下交叉编译Qt5.12.xtslib-1.4
npm -v 和 node.js 在交叉编译的 nodejs0.12.2 上抛出非法指令
mips交叉编译 error: 'PTHREAD_MUTEX_ERRORCHECK_NP' was not declared in this scope