如何针对 mips gcc 的解释器进行编译?

如何针对 mips gcc 的解释器进行编译?

我扔掉了曾经在这里的旧问题,因为由于下面以粗体列出的原因,它不再相关。问题本身仍然存在,只是我试图交叉编译的系统不再存在。老问题已复制到粘贴箱

我发现我可以从以下位置刷新 F@ST 2704N 的固件OpenWRT.org。我使用了 luci Web 界面的链接,现在我的路由器上有 OpenWRT。这个问题仍然有效,因为我想学习如何为我的路由器交叉编译程序,但现在它应该更容易,因为我不尝试针对内置固件工作。

如何编译我的程序以在运行 OpenWRT 的 Mips32 版本 1 处理器上运行?

直接使用解释器:

root@OpenWrt:~# /lib/ld-musl-mips-sf.so.1 hello
/lib/ld-musl-mips-sf.so.1: hello: Not a valid dynamic program

root@OpenWrt:~# ./hello
Segmentation fault

CPU信息:

root@OpenWrt:~# cat /proc/cpuinfo
system type     : bcm63xx/F@ST2704N (0x6318/0xB0)
machine         : Sagem F@ST2704N
processor       : 0
cpu model       : Broadcom BMIPS3300 V3.3
BogoMIPS        : 332.54
wait instruction    : yes
microsecond timers  : yes
tlb_entries     : 32
extra interrupt vector  : yes
hardware watchpoint : no
isa         : mips1 mips2 mips32r1
ASEs implemented    :
shadow register sets    : 1
kscratch registers  : 0
package         : 0
core            : 0
VCED exceptions     : not available
VCEI exceptions     : not available

Linux版本:

root@OpenWrt:~# cat /proc/version
Linux version 4.1.4 (thepeople@viasatpilot) (gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 r46566) ) #1 Fri Aug 7 05:54:20 CEST 2015

板载二进制:

Alexs-MacBook-Air:hello-world senor$ file ls
ls: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked, interpreter /lib/ld-musl-mips-sf.so.1, stripped

Alexs-MacBook-Air:hello-world senor$ /opt/cross/gcc-mips/bin/mips-netbsd-elf-readelf -h ls
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0x403990
  Start of program headers:          52 (bytes into file)
  Start of section headers:          427656 (bytes into file)
  Flags:                             0x50001005, noreorder, cpic, o32, mips32
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         7
  Size of section headers:           40 (bytes)
  Number of section headers:         29
  Section header string table index: 28

我的二进制文件:

Alexs-MacBook-Air:hello-world senor$ file hello
hello: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, with debug_info, not stripped

Alexs-MacBook-Air:hello-world senor$ /opt/cross/gcc-mips/bin/mips-netbsd-elf-readelf -h hello
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0xa0020004
  Start of program headers:          52 (bytes into file)
  Start of section headers:          200884 (bytes into file)
  Flags:                             0x50001001, noreorder, o32, mips32
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         29
  Section header string table index: 28

你好二进制源代码:

#include <stdio.h>
int main() {
  printf("Hello MIPS! \n");
  return 0;
}

我用来编译 hello 二进制文件的命令是/opt/cross/gcc-mips/bin/mips-netbsd-elf-gcc -mips32 -Tidt.ld -static hello.c -o hello.

我尝试使用命令编译程序/opt/cross/gcc-mips/bin/mips-netbsd-elf-gcc -mips32 -Tidt.ld -dynamic-linker=/lib/ld-musl-mips-sf.so.1 -static hello.c -o hello-inter,但它生成了很多文件并生成相同的二进制文件,就像我没有添加新的链接器选项一样。我想我需要从源代码链接二进制文件,但我可能是错的。

答案1

我发现OpenWRT.org 上的本指南这帮助我学习了如何安装 buildtools,我只是修改了说明以适合我的 OpenWRT 版本。

我检查了 git commit70255e3d624cd393612069aae0a859d1acbbeeae(标签:v18.06.1)我设置了设置:

system "Broadcom BCM63xx"
subtarget "generic"
profile "Sagem F@ST2704N"

我还将 PATH 环境变量设置为具有path/to/project/source/staging_dir/toolchain-mips_mips32_gcc-7.3.0_musl/bin并执行该命令mips-openwrt-linux-gcc hello.c -o hello

我应该提到我必须安装 gnu-getopt 和 gnu-time 因为我是在 OSX 上编译的。

另外,作为额外的好处,当我测试针对现有程序(例如 BusyBox)进行编译时,我能够使用命令编译 BusyBox LDFLAGS="--static" make CROSS_COMPILE="mips-openwrt-linux-"

编辑:

对于那些对 ELF 文件为何需要解释器感兴趣的人,解释器是在程序加载之前设置环境的。引文来自一篇博客文章克里斯蒂安·艾辛格的思想来自“内核中的程序加载”部分。

“静态链接的二进制文件可以不需要解释器;动态链接的程序总是需要 /lib/ld-linux.so 作为解释器,因为它包含一些启动代码,加载二进制文件所需的共享库,并执行重定位。”

我怀疑我的程序之所以一直显示“已杀死”(在原始 Sagemcom 固件上),即使我静态链接它也是如此,因为路由器的设计可能是为了迷惑试图运行该程序的用户,以防止未经授权的执行。我确实弄清楚了如何编译 uClibc 并让它在原始固件和一个单独的 Sagemcom 设备上工作(与本问题中询问的设备无关)。

相关内容