Ошибка кросс-компиляции MIPS: недопустимая инструкция

Я хочу выполнить кросс-компиляцию C src для машины MIPS, но компиляция не удалась. Выполнение кросс-скомпилированного бинарного файла на целевой машине выводит «недопустимую инструкцию». Не могли бы вы сообщить мне, как скомпилировать C src для машины MIPS?

Подробности следующие:

Выполнение «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

Для кросс-компиляции я использовал buildroot, который поддерживает кросс-компиляцию MIPS1.

Я ожидал, что 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 ([email protected]) (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 очень прост, я считаю, что проблем, связанных с используемыми библиотеками, не возникает.


person freddy    schedule 29.05.2014    source источник
comment
Попробуйте использовать что-то вроде gdb (возможно, на хосте с gdbserver на цели), чтобы увидеть, какая инструкция не работает.   -  person Chris Stratton    schedule 29.05.2014
comment
Поскольку на моей целевой машине нет gdbserver, использовать GDB невозможно. (Чтобы установить gdbserver на Target, мне нужно выполнить кросс-компиляцию двоичного файла для целевой машины, что означает, что моя проблема решена)   -  person freddy    schedule 29.05.2014
comment
Можете ли вы использовать cross objdump как для рабочих, так и для нерабочих двоичных файлов, чтобы увидеть, кажутся ли инструкции разумными? Ваш системный поставщик или дистрибьютор должен указать вам рабочий инструментарий для цели, а источники служебных программ должны включать флаги сборки.   -  person Chris Stratton    schedule 29.05.2014
comment
Не могли бы вы опубликовать дополнительную информацию? Возможно выход /proc/cpuinfo и /proc/version на цель? И пробовали ли вы сначала кросс-компилировать самую простую программу hello world, чтобы исключить проблемы с библиотеками? (Например) И, если возможно, командная строка gcc использовалась для компиляции и/или компоновки?   -  person 6EQUJ5    schedule 29.05.2014
comment
@ChrisStratton Я могу выполнить objdump для обоих двоичных файлов, но я мог найти необоснованные инструкции (может быть, из-за отсутствия знаний об инструкциях MIPS).   -  person freddy    schedule 29.05.2014
comment
@ 6EQUJ5 Я обновил то, что вы просили. Моя двоичная программа для Target очень проста (для целей тестирования), как вы сказали.   -  person freddy    schedule 29.05.2014
comment
Не могли бы вы посмотреть на dmesg? Он может содержать дополнительную информацию о незаконной инструкции.   -  person Christophe Vu-Brugier    schedule 29.05.2014
comment
@ChristopheVu-Brugier Извините, на моей целевой машине нет командной строки dmesg. Не могли бы вы сообщить мне какие-либо альтернативы?   -  person freddy    schedule 29.05.2014
comment
Альтернативой dmesg является cat /dev/kmsg   -  person Christophe Vu-Brugier    schedule 29.05.2014


Ответы (2)


Это может быть вызвано различными причинами; одна вещь, которую я вижу из вашего сообщения, заключается в том, что флаги ELF различаются между вашим двоичным файлом и их двоичным файлом. Ядро тоже очень старое, и вы также не указали версию gcc в своем собственном buildroot.

Отмечу, что этот чипсет (BCM5354) такой же, как и в DLINK DIR-320 и других, которые поддерживаются OpenWRT. Предполагая, что вы еще не используете OpenWRT в качестве buildroot, я бы попробовал еще раз, используя OpenWRT.

И наоборот, вы можете загрузить предоставленные DLink исходники GPL, которые должны включать buildroot, с веб-сайта поддержки DLINK и попробовать это. Учитывая возраст ядра и gcc, используемых для сборки вашего назначения, и новизну магистрали OpenWRT, вы можете попробовать найти самую старую версию OpenWRT, которая поддерживает этот маршрутизатор, или сначала попробовать корень сборки DLINK.

Если у вас есть пара компьютеров, вы можете попробовать обе сборки параллельно...

Если это не исправит, вам нужно будет опубликовать гораздо больше информации.

person 6EQUJ5    schedule 29.05.2014
comment
Не могли бы вы сообщить мне, почему разные флаги могут вызвать проблему? - person freddy; 29.05.2014
comment
Есть ли способ обобщить этот ответ? Это решает проблему ОП, но не дает никакого способа ее решить. - person redbeam_; 02.08.2015

Я скомпилировал вашу программу hello world, используя mipsel-linux-gcc (версия 4.5.3). Это вывод mipsel-linux-objdump -d -S при запуске вашей программы hello world. Программа прекрасно работала на машине Broadcom 7425 с прямым порядком байтов, которая стояла у меня на столе.

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

Вывод вашего дизассемблированного компилятора должен выглядеть примерно так. Если это не так, обновите свой вопрос.

person markgz    schedule 30.05.2014
comment
Спасибо!. Я нашел bal инструкцию в основной функции. Подходит ли он для набора инструкций mips1? - person freddy; 30.05.2014
comment
Я не могу найти никакой документации по MIPS 1 ISA, поэтому не могу ответить на этот вопрос. Вы можете попробовать исправить двоичный файл с помощью JAL вместо BAL, чтобы увидеть, устранит ли это проблему. - person markgz; 31.05.2014