How to distinguish between mips cpu types on linux when dpkg-architecture is absent?
Asked Answered
H

3

5

Short question: how can I reliably distinguish between mips, mipsel, mips64 and mips64el on any linux distribution?

Longer explanation:

We provide statically built/distribution independent binaries (for TeX) for many architectures. Installation script usually runs uname -s and uname -m to determine operating system and architecture. Binaries are then fetched from server based on that decision, so it needs to works reliably. And it does. Almost everywhere except for Mac OS X 10.6 and Debian. Mac would report i386 on OS that runs 64-bit applications, while Debian reports mips64 for 32-bit OS.

Debian on mips64 correctly reports processor type, but that doesn't help me for at least two reasons:

  1. OS is 32-bit, not 64-bit as the name might suggest.
  2. It is running in little-endian mode. Debian calls that mipsel, not mips. It can often be switched, but OS only runs in one mode and mips software is often incompatible with mipsel.

Here are some outputs from system commands:

$ file my_binary_name
my_binary_name: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, with unknown capability 0xf41 = 0x756e6700, with unknown capability 0x70100 = 0x1040000, stripped

$ dpkg-architecture 
DEB_BUILD_ARCH=mipsel
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_ARCH_CPU=mipsel
DEB_BUILD_ARCH_BITS=32
DEB_BUILD_ARCH_ENDIAN=little
DEB_BUILD_GNU_CPU=mipsel
DEB_BUILD_GNU_SYSTEM=linux-gnu
DEB_BUILD_GNU_TYPE=mipsel-linux-gnu
DEB_HOST_ARCH=mipsel
...

dpkg-architecture would be perfect for the task, except that it is not present on other Linux distributions.

The first problem was already addressed here: How to determine whether a given Linux is 32 bit or 64 bit?

The command

getconf LONG_BIT

properly reports 32 on my system.

But how do I determine whether it is big endian or little endian?

I figured out that config.guess can determine the difference, but it does so by running the compiler which may not be present on end user's computer. On top of that config.guess completely ignores the fact that operating system works in 32-bit mode and wrongly reports mips64el instead of mipsel.

Hygrograph answered 18/8, 2011 at 0:17 Comment(1)
Is something wrong with the answer I provided below? Please accept it if not.Granary
G
10

The file command tells you:

$ file my_binary_name

my_binary_name: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, with unknown capability 0xf41 = 0x756e6700, with unknown capability 0x70100 = 0x1040000, stripped

The LSB there stands for least-significant byte, meaning little endian. The output of file given a big-endian binary will be MSB, most-significant byte.

Note that MIPS has 3 ABIs (actually more), one of which is n32. n32 has native 64-bit integers but only 32-bit pointers (and requires a 64-bit kernel).

For n32 binaries file will still report 32-bit:

ELF 32-bit LSB executable, MIPS, N32 MIPS-III version 1 (SYSV)

o32 (what debian uses):

ELF 32-bit LSB executable, MIPS, MIPS-III version 1 (SYSV)

n64:

ELF 64-bit LSB executable, MIPS, MIPS-III version 1 (SYSV)

Granary answered 17/5, 2012 at 4:59 Comment(2)
So when compiler is not available the best bet is to simply do something like file $(which file) to check whether the system is 32 or 64-bit and LSB vs. HSB? On Mac OS X with fat binaries this would not work, but I guess that this is my only option in case of mips* linux. Thank you for explaining the extra bit about n32/o32. Are the binaries compiled for n32/o32 compatible with each other?Hygrograph
I don't know what file output looks like for fat binaries, so I can't say, but you already know that fat binaries on Mac OS X contain PowerPC (big endian) and x86 (little endian) code, so there's nothing particularly interesting about them in this case. Your question about MIPS ABI compatibility confuses me, since ABIs are more or less inherently incompatible. They can coexist on the same system, if that's your question. o32 libraries live in /lib, n32 in /lib32 and n64 in /lib64.Granary
T
3

lscpu should work.
For example:

# lscpu
Architecture:          mips
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
Thaxter answered 22/10, 2016 at 18:15 Comment(0)
G
-1

I realise this is an old question, but it's unanswered so here goes.

You already know the bit size, so surely you can check:

case "$var" in
mips64el | mipsel) endian=little;;
mips64 | mips) endian=big;;  # or: echo big;; if you need to capture it

(where $var holds your string as given: note you can pattern-match in case; see: the POSIX sh documentation.)

If not, you should be able to test for a define from autoconf; use the MIPSEL macro.

Gunas answered 31/1, 2012 at 10:6 Comment(1)
Are you trying to answer "how to set variable called endian based on architecture name"? Because I asked for the reverse. The problem is that I don't know what the proper architecture name should be and I would like to determine the name based on endianess. But I don't know how to determine endianess without running compiler.Hygrograph

© 2022 - 2024 — McMap. All rights reserved.