3

我想为 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 是目标机器上运行的二进制程序)输出:

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”时,它会输出“非法指令”。

你能告诉我如何解决上述问题吗?由于我是交叉编译的新手,我无法找到问题的确切原因。

任何意见将不胜感激。

更新:

在目标上,执行“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 非常简单,我相信没有与使用的库相关的问题。

4

2 回答 2

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

您的反汇编编译器输出应该与此非常相似。如果没有,请更新您的问题。

于 2014-05-30T00:35:54.147 回答
2

各种事情可能会导致这种情况;我从您的帖子中可以看到的一件事是您的二进制文件和它们的二进制文件之间的 ELF 标志是不同的。内核也很旧,而且您还没有在自己的 buildroot 中报告 gcc 的版本。

我注意到该芯片组 (BCM5354) 与 DLINK DIR-320 和其他芯片组中使用的相同,恰好受 OpenWRT 支持。假设您还没有使用 OpenWRT 作为 buildroot,我会再次尝试使用 OpenWRT。

相反,您可以从 DLINK 支持网站下载 DLink 提供的 GPL 源代码,其中应包含 buildroot 并尝试。考虑到用于构建目的地的内核和 gcc 的年龄,以及主干 OpenWRT 的新颖性,您可能想尝试找到支持该路由器的 OpenWRT 的最旧版本,或者首先尝试 DLINK 构建根。

如果您有几台计算机,则可以同时尝试两个 buildroots ...

如果这不能解决它,您需要发布更多信息

于 2014-05-29T05:34:52.583 回答