这里是我试图在embedded式Linux系统上运行的一些示例testing代码:
#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; }
embedded式系统是Microblaze,它是在Xilinx FPGA上运行的32位RISC软核处理器。 请不要因此而拖延,因为许多标准的Linux知识仍然适用。 处理器configuration为带有MMU的LSB,而我正在使用的Linux版本(由赛灵思提供的PetaLinux)预计会相同。 我正在使用提供的GNU编译器; Microblaze似乎在海湾合作委员会正式支持。
我遇到的问题是,当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编译器的小端版本。
我非常想debugging这个,或者至less看一个coredump,但是当segfault发生的时候,似乎没有coredump出现,而Microblaze Linux的构build中没有gdb
可执行文件。 也许我错过了什么?
感谢您抽出时间阅读本文。 有什么想法吗?
从经过一番研究后我可以看到, vivado
是硬件开发IDE,因为它们提供了一个试用期 – 所以这是他们总是要收费的硬件开发。
如果您使用Xilinx的标准SDK 板 ,则应该预先配置一切。 否则,硬件设计人员会生成一个硬件设计,其中包含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(eg):
在目标系统上:
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)