Вот пример тестового кода, который я пытаюсь запустить на встроенной системе Linux:
#include <iostream>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
std::cout << "Hello World from C++" << std::endl;
std::cout << "c=" << c << std::endl;
std::cout << "i=" << i << std::endl;
}
Встроенная система представляет собой Microblaze, 32-битный программный процессор RISC, работающий на Xilinx FPGA. Пожалуйста, не отчаивайтесь, так как многие ваши стандартные знания Linux все еще будут применяться. Процессор настроен как LSB с MMU, и сборка Linux, которую я использую (PetaLinux, поставляется Xilinx), ожидает того же. Я использую прилагаемый компилятор GNU; Microblaze официально поддерживается в GCC.
У меня проблема в том, что когда stdlib должен взаимодействовать с целым числом, он segfaults. Вот вывод:
Hello World from C++
c=A
Segmentation fault
Обратите внимание, что символ обрабатывается нормально. C-эквивалент этого кода также отлично работает:
#include <stdio.h>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
printf("Hello World from C\n");
printf("c=%c\n", c);
printf("i=%i\n", i);
return 0;
}
…
Hello World from C
c=A
i=7
Это заставляет меня подозревать проблему с общей библиотекой libstdc++.so.6.0.20
, Эта библиотека поставляется Xilinx, поэтому она должна быть правильной. file
вывод этой библиотеки:
libstdc++.so.6.0.20: ELF 32-bit LSB shared object, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, not stripped
file
вывод моего двоичного файла:
cpptest: ELF 32-bit LSB executable, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped
Я также пытался статически связать мой бинарный файл, используя -static
флаг, но результат был тот же.
Вот наиболее важные настройки компилятора и компоновщика, которые я использую, но я попытался изменить их безрезультатно.
CC=microblazeel-xilinx-linux-gnu-gcc
CXX=microblazeel-xilinx-linux-gnu-g++
CFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
CPPFLAGS?=
CXXFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
LDFLAGS=-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed
To compile:
@$(CCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$@"
To link:
@$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
Обратите внимание, что microblazeel
относится к младшей порядковой версии компилятора microblaze.
Я бы очень хотел отладить это или, по крайней мере, взглянуть на coredump, но кажется, что coredump не создается, когда происходит segfault, и нет gdb
исполняемый файл в сборке Microblaze Linux. Может я что-то упустил?
Спасибо, что нашли время, чтобы прочитать это. Какие-нибудь мысли?
Из того, что я увидел после небольшого исследования, vivado
это IDE разработки HW [потому что они предлагают пробный период — так что это HW devel, за который они всегда хотят взимать плату].
Если вы используете стандартный SDK доска от Xilinx все должно быть предварительно настроено. В противном случае, конструктор HW производит конструкцию HW, в которой есть Microblaze.
Исходя из этого, вам, возможно, придется использовать petalinux для создания нового образа загрузки, ядра и т. Д., Который совместим.
Вы может нужно восстановить libstdc++
из источника, но я бы сделал это в крайнем случае. Например, не беспокойтесь, пока не получите gdb
работают и имеют результаты испытаний.
Вот некоторые файлы Petalinux PDF:
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug977-petalinux-getting-started.pdf
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug981-petalinux-application-development-debug.pdf
Руководство по разработке показывает, как вызвать GDB (например):
В целевой системе:
gdbserver host:1534 /bin/myapp
По системе разработки:
petalinux-utils --gdb myapp
с последующим target remote 192.168.0.10:1534
Я сделал некоторые изменения в вашем Makefile с аннотациями. Я закомментировал некоторые несущественные варианты. Обратите внимание, что я использую +=
оператор построить CFLAGS/CXXFLAGS
постепенно
Основная идея здесь — сделать сборку с минимальными отклонениями от «стандартного». Добавляйте только проверенные основные опции. Сборка и тестирование. Добавляйте опции по одному [перестраивайте и тестируйте каждый раз], пока не найдете вариант, вызывающий проблему.
У меня, однако, есть сильное подозрение о -fno-common
быть источником проблем. Кроме того, в меньшей степени, я немного подозрительно -Wl,--as-needed
Должны ли эти варианты работать? Конечно, но xilinx / microblaze не x86 …
Я добавил две переменные make командной строки:
DEBUG
— генерировать для отладки с помощью GDB
VERBOSE
— показать все о процессе сборки
Например, попробуйте make <whatever> DEBUG=1 VERBOSE=1
CC = microblazeel-xilinx-linux-gnu-gcc
CXX = microblazeel-xilinx-linux-gnu-g++
CPPFLAGS ?=
CMFLAGS += -Wall -Werror
CMFLAGS += -fmessage-length=0
# compile for gdb session
# NOTES:
# (1) -gdwarf-2 may or may not be the the right option for microblaze
# (2) based on doc for -feliminate-unused-debug* petalinux/microblaze may want
# stabs format
ifdef DEBUG
CMFLAGS += -gdwarf-2
CMFLAGS += -O0
# compile for normal build
#else
CMFLAGS += -O2
CMFLAGS += -feliminate-unused-debug-types
endif
# NOTE: I used to use "@" on commands, but now I leave it off -- debug or not
# sure it's "ugly" but you can get used to it pretty quickly--YMMV
ifndef VERBOSE
Q :=
else
###Q := @
Q :=
endif
# let compiler/linker tell you _everything_:
# (1) configure options when tool was built
# (2) library search paths
# (3) linker scripts being used
ifdef VERBOSE
CMFLAGS += -v
LDFLAGS += -Wl,--verbose=2
endif
CMFLAGS += -fno-builtin
# NOTE: I'd _really_ leave this off as it may confuse c++ std as "<<" calls
# _M_insert (which is in the library, which is almost certainly _not_ using
# -fno-common)
###CMFLAGS += -fno-common
# NOTE: I'm also suspicious of this a little bit because the c++ lib may have
# some "weak" symbols that the c library doesn't
###LDFLAGS += -Wl,--as-needed
# NOTE: this seems harmless enough, but you can comment it out to see if it
# helps
LDFLAGS += -Wl,--hash-style=gnu
# NOTE: an optimization only
ifndef DEBUG
LDFLAGS += -Wl,-O1
endif
CFLAGS += $(CMFLAGS)
CXXFLAGS += $(CMFLAGS)
# NOTES:
# (1) leave this off for now -- doesn't save _that_ much and adds complexity
# to the build
# (2) IMO, I _never_ use it and I erase/uninstall it on any system I
# administrate (or just ensure the build doesn't use it by removing it
# from $PATH)--YMMV
###XCCACHE = $(CCACHE)
# to compile
$(Q)$(XCCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$@"
# to link
$(Q)$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
Других решений пока нет …