Adventures In MIPS Tools

I’m trying to compile a program that will run on my new MIPS-based subnotebook. I finally got a cross-compiling toolchain built and building a super-simple C program. But the program failed to run. When I tried to run my sample program, the shell complained about not knowing what to do with a ‘(‘ character. Puzzling.

This is the ‘file’ type of my compiled program:

ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, not stripped

I finally thought to extract a binary from the MIPS machine and check its file type:

ELF 32-bit LSB executable, MIPS, version 1 (SYSV), dynamically linked (uses shared libs), stripped

Okay, I think I’m getting wise to the discrepancy already. It turns out that I want a target called “mipsel” rather than just plain “mips” as the former specifies little endian (and because a MIPS CPU can be wired to run either endian — that’s how simple and reduced this reduced instruction set is).

So I rebuilt the toolchain using the ‘mipsel’ target (building the toolchain is surprisingly quick when you know how). Now the test program segfaults when I try to run it. That’s unfortunate, though I still perceive it to be a step up from the last position. This is the new type reported by ‘file’:

ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, not stripped

It’s MIPS-I version 1, vs. simply MIPS version 1, which is what the existing binaries are. I wonder if that’s the problem? I’m also struggling with a linker warning about the start location. That’s more likely to be the issue.

BTW, this is the C code I am testing with:

int main()
{
  return 77;
}

My thinking here is that I should be able to run the program followed by “echo $?” to get the last command’s exit status– 77 in this case.

8 thoughts on “Adventures In MIPS Tools

  1. Reimar

    The error clearly is in using 77 instead of 42 :-P
    Did you try disassembling this file (mipsel-…-objdump -d) and doing the same on one of the precompiled binaries?
    And what kind of warning about start location? Did you maybe compile for a system without virtual memory support (no idea if they exist/are supported, but for those linking something without an explicit load address would not make sense)?

  2. Reimar

    Oh, and you should try readelf -h
    e.g. for my linksys router I get:
    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: 0x4060f0
    Start of program headers: 52 (bytes into file)
    Start of section headers: 0 (bytes into file)
    Flags: 0x50001007, noreorder, pic, cpic, o32, mips32
    Size of this header: 52 (bytes)
    Size of program headers: 32 (bytes)
    Number of program headers: 7
    Size of section headers: 0 (bytes)
    Number of section headers: 0
    Section header string table index: 0

  3. Multimedia Mike Post author

    Good idea. I just did a slightly deeper comparison against several existing, working binaries from the machine. The main difference I find is that the working binaries have flags of pic and cpic (not surprising since I configured my toolchain without shared libraries for now). But the working binaries also specify a mips32 flag, while my binary only specifies mips1.

  4. Multimedia Mike Post author

    The mips32 target maps to mips642-unknown-gnu, and gcc complains about not knowing what to do with that.

    That interpreter thing might be a good guess. I’m going to do some more searching to see if anyone else has published data about cross compiling for these machines. I know people have done it; it’s just a matter of whether they have posted info about how they did it.

  5. Multimedia Mike Post author

    I rebuilt the toolchain for a target called mipsisa32el. This made my test program compile with a mips32 flag instead of mips1, and also the eabi32 flag. When I run the program compiled with this chain, I’m back to the error of “1: Syntax error: “(” unexpected” (original error when I compiled the MIPS-BE toolchain by default).

  6. Reimar

    -march=mips32 should probably fix that one.
    But I find it very suspicious that “file” does not tell for which MIPS architecture the binary uses.
    My “file” command says:
    busybox: ELF 32-bit LSB executable, MIPS, MIPS32 version 1 (SYSV), dynamically linked (uses shared libs)
    so it explicitly states MIPS32, I just hope it’s not some modified architecture where you’d have to patch binutils…
    readelf -e might be interesting, to, e.g. I get
    INTERP 0x000114 0x00400114 0x00400114 0x00014 0x00014 R 0x1
    [Requesting program interpreter: /lib/ld-uClibc.so.0]
    not that you end up linking against the wrong libc or something…

  7. Multimedia Mike Post author

    A little more digging indicates that the correct target might be mipsel-linux-gnu. Trying that now.

  8. Mans

    The “interpreter” of an ELF file is the dynamic linker. If you link with -static, you should avoid any issues with this. As for compiler flags, play around with the ones mentioned in the gcc info pages under GCC Command Options/Submodel Options/MIPS Options until the readelf -h is as close as possible to that from an executable from the machine.

    What kernel version is running on the machine? Can you get at its configuration, e.g. through /proc/config.gz?

    Also note that what you have is not a real MIPS processor. It is a, supposedly, ISA-compatible Chinese clone with very little information available.

Comments are closed.