当前位置:首页 » 编程软件 » zynq交叉编译

zynq交叉编译

发布时间: 2022-09-19 12:25:09

㈠ opencv不用把库放到开发板上吗

由于我本机PC端测试使用的opencv的版本为opencv2.4.6.1.故而我想要移植这个版本的opencv到zedboard板卡上。参考Xilinx出版的《Zynq开发实战》的第13章以及几个人的博客进行配置编译的时候,总是会出现如下的错误:
In file included from /usr/include/math.h:409:0,
from /opt/opencv-2.4.6.1/moles/core/include/opencv2/core/types_c.h:94,
from /opt/opencv-2.4.6.1/moles/core/include/opencv2/core/core.hpp:49,
from /opt/opencv-2.4.6.1_forArm/moles/core/precomp.hpp:50:
/usr/include/bits/mathinline.h: In function 'void cv::randnScale_8u(const float*, uchar*, int, int, const float*, const float*, bool)':
/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'
/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'
/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'
/usr/include/bits/mathinline.h: In function 'void cv::randShuffle_(cv::Mat&, cv::RNG&, double) [with T = unsigned char]':
/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'
/usr/include/bits/mathinline.h: In function 'void cv::randShuffle_(cv::Mat&, cv:
......
在用交叉编译工具链编译opencv时候,我本来已经将交叉编译工具链写入了环境变量,那它搜索的时候,应该是遍历交叉编译工具链下的头文件,但是 opencv却默认遍历到gcc头文件下,故而出现这样的错误,为何会这样呢?试了多种方式均不能编译通过,故而弃用书上编译opencv的方式,转向下 面的方式:
我们采用图形化的cmake进行配置,这样就可以指定交叉编译工具链的头文件目录,下载cmake安装包(ps:不要下载源代码),下载地址如下:
http://www.cmake.org/cmake/resources/software.html我使用的系统为32位Centos6.4,故而我选择的平台为linux i386,下载其后面的压缩包。
下载完成后,解压缩cmake-2.8.12.2-Linux-i386.tar.gz到/usr/local下,使用下面的命令:
tar xvzf cmake-2.8.12.2-Linux-i386.tar.gz -C /usr/local
export PATH=$PATH:/usr/local/cmake-2.8.12.2-Linux-i386/bin
接下来,我们利用cmake-gui进行opencv的配置,创建zedopencv目录,解压缩opencv代码到此目录下,在opencv的源代码下创建zed_install,然后进入此目录。命令如下:
tar xvzf opencv-2.4.6.1.tar.gz -C ./zedopencv
cd ./zedopencv/opencv-2.4.6.1
mkdir zed_install
cd zed_install
cmake-gui
出现如下的界面:

其中,按照提示选择要编译的opencv源代码的路径以及安装编译路径,这里如图所示。然后点击Configure,出现如下的配置界面:

这里一定要注意,选择Unix Makefile选项,在下面选择指定编译器选项,然后点击next进入下面的界面,按照提示,填入如下的信息:

指定交叉编译环境的头文件目录是/opt/xlinx-arm-gcc/arm-xilinx-linux-gnueabi/libc/usr/,选择C 与C++的编译器,还有平台,这里一定要注意Library mode的选项,这里一定要选择在根目录与本地系统下均搜索,如上图所示,点击Finish完成配置。第三方库,尽量不用选,如下图所示:

然后点击Generate,完成配置,然后执行make,开始编译,编译的过程中会出现下面的一个错误:
Linking CXX executable ../../bin/opencv_createsamples
../../lib/libcxcore.so: undefined reference to `clock_gettime'
../../lib/libcxcore.so: undefined reference to `pthread_key_create'
../../lib/libcxcore.so: undefined reference to `pthread_getspecific'
../../lib/libcxcore.so: undefined reference to `pthread_setspecific'
按照错误的提示,是缺少线程链接,我们需要对此目录下的CmakeCache.txt进行修改,修改的位置如下:
178 //Flags used by the linker.
179 CMAKE_EXE_LINKER_FLAGS:STRING=-lpthread -lrt
然后保存退出,继续编译就可以完成所有的编译。完成后,在此目录下的lib下发现已经编译好了所有的库文件,创建zed-lib-opencv文件夹,拷贝所用的.so文件到此目录下。
为了便于制作镜像文件,在此目录下创建ramdisk文件夹。我写了个shell脚本,也就是图中所示的fs.sh,为了便于操作其中的参数$1代表要制作的镜像的名称,$2代表要制作镜像的文件夹,$3代表镜像的大小,脚本的具体内容如下:
#!/bin/bash
dd if=/dev/zero of=$1.image bs=1M count=$3

mke2fs -F $1.image -L "ramdisk" -b 1024 -m 0
tune2fs $1.image -i 0

chmod 777 $1.image

#mkdir ramdisk

mount -o loop $1.image ./ramdisk

cp -R ./$2/* ./ramdisk

umount ./ramdisk
由于ramdisk文件系统的大小为8M,而Opencv的库文件显然大于8M,其接近于25M,故而8M是满足不了的,SD卡有4G的空间,制作库文件的镜像,拷贝到SD卡上,把SD卡挂载到Linux系统,就可以解决空间不够用的问题。我们进行如下的操作:
首先进入filesys,在usr目录下创建lib,再进入etc/init.d,对rcS文件进行修改。添加下面几行代码:
echo "mount otherlib....."
mount /dev/mmcblk0p1 /mnt
mount /mnt/opencvlib.image /usr/lib

export PATH=$PATH:/usr/local/bin
export LD_LIBRARY_PATH=/usr/local/lib:/lib
然后,我们进行镜像的制作:
./fs.sh ramdisk8M filesys 8
./fs.sh opecv_lib zed-lib-opencv 80
制作了两个镜像文件ramdisk8M.image opecv_lib.image大小分别为8M与80M.
然后对ramdisk进行压缩:
gzip -9 ramdisk8M.image
然后将新生成的ramdisk8M.image.gz与opencv_lib.image拷 贝到SD卡启动zedboard即可发现,/usr/lib目录下已经有了opencv库文件,至此opencv移植到zedboard工作彻底完成!此 方法也可以用于一般的arm开发板opencv的移植。
要支持第三方库,可以参照这个博客:ffmpeg支持,在编译完第三方库之后,需要重新编译opencv库!

㈡ 如何使用oprofile对软件做profiling

一. Oprofile简介

Profiling是对不同性能特征的数据的形式化总结或分析,它通常以图形和表的形式出现。它提供为特定的处理器事件收集的采样百分数或数量,比如cache miss rate、TLB miss rate等等。一般来说,主要目的是为了找出软件中的性能瓶颈,然后有针对性的优化以提升软件的整体性能。

Oprofile 是用于 Linux 的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括ARM, PowerPC, MIPS, IA32, IA64 和 AMD Athlon等等。它的开销很小,从Linux 2.6 版起,它被包含进了Linux内核中。

Oprofile可以收集有关处理器事件的信息,帮助用户识别诸如循环的展开、cache的使用率低、低效的类型转换和冗余操作、错误预测转移等问题。Oprofile是一种细粒度的工具,可以为指令集或者为函数、系统调用或中断处理例程收集采样。Oprofile 通过取样来工作。使用收集到的评测数据,用户可以很容易地找出性能问题。

通过监察CPU的hardware events,oprofile可以在运行状态下对整个Linux系统进行profiling。Profiling的对象可以是Linux kernel (包括moles和interrupt handlers), shared libraries或者应用程序。

从0.9.8版本开始,oprofile支持Perf_events profiling mode模式。应用程序operf被用来控制profiling过程;而在legacy mode下,是通过opcontrol脚本和oprofiled daemon来完成的。Operf不再象legacy mode那样需要OProfile kernel driver,它直接和Linux Kernel Performance Events Subsystem打交道。使用operf,就可以用普通用户的身份来profiling用户的应用程序了,当然如果需要对整个系统来profiling的时候还是需要root权限的。

如果硬件不支持OProfile使用performance counters,OProfile就只能工作在Timer Mode下了。Timer Mode只能在legacy profiling mode下使用,即只能通过opcontrol脚本来控制。
Oprofile的优势:
Ÿ 比较低的运行开销
Ÿ 对被profiling的对象影响很小
Ÿ 可以profiling中断服务程序(interrupt handlers)
Ÿ 可以profiling应用程序和shared libraries
Ÿ 可以profiling dynamically compiled (JIT) code
Ÿ 可以对整个系统做profiling
Ÿ 可以观察CPU内部的细节,例如cache miss rate
Ÿ 可以多源代码做annotation
Ÿ 可以支持instruction-level的profiling
Ÿ 可以生成call-graph profiles

不过OProfile也不是万能的,它也有自己的局限性:
Ÿ 只能在x86, ARM, 和PowerPC架构上生成call graph profiles
Ÿ 不支持100%精确的instruction-level profiling
Ÿ 对dynamically compiled (JIT) code profiling的支持还不完善。

无论如何,Oprofile的功能都比gprof要强很多,代价是配置起来会比较麻烦。


二. 编译Oprofile

首先最好在Linux kernel里面选中Oprofile driver,以获得全面的支持。因为笔者使用的是Xilinx Linux pre-built 14.7,所以这里下载的是linux-xlnx-xilinx-v14.7.tar.gz

解压缩后,用以下命令调出Linux kernel的配置界面:
export ARCH=arm
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
make xilinx_zynq_defconfig
make xconfig 或者make menuconfig

在配置界面上将以下两项勾上:
General setup --->
[*] Profiling support
<*> OProfile system profiling

然后make uImage即可生成新的uImage,用来替换Xilinx Linux pre-built 14.7中的Linux kernel image。同时我们也需要vmlinux来检查profiling的结果。


Oprofile需要popt, bfd, liberty库,要在嵌入式单板上使用这些库,需要手工完成交叉编译。

针对popt 1.7,用以下命令完成编译:
./configure --prefix=/home/wave/xilinx/oprofileprj/rootfs --host=arm-xilinx-linux-gnueabi --with-kernel-support --disable-nls && make && make install

针对binutils 2.24,用以下命令完成编译:
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --enable-install-libbfd --enable-install-libiberty --enable-shared && make && make install
不过--enable-install-libiberty没有效果,所以需要手工把libiberty.a和libiberty.h拷贝到相应的位置。

针对oprofile 0.9.9,用以下命令完成编译:
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --with-kernel-support --with-binutils=/home/wave/xilinx/oprofileprj/rootfs && make && make install
配置过程结束后可能会有以下提示,因为没有打算用GUI和profile JITed code,所以直接忽视之。
config.status: executing libtool commands
Warning: QT version 3 was requested but not found. No GUI will be built.
Warning: The user account 'oprofile:oprofile' does not exist on the system.
To profile JITed code, this special user account must exist.
Please ask your system administrator to add the following user and group:
user name : 'oprofile'
group name: 'oprofile'
The 'oprofile' group must be the default group for the 'oprofile' user.

将编译完成的uImage,vmlinux,oprofile binary,重新编译的没有-pg的libjpeg binary以及tool chain的libc打包放到SD卡中,准备在ZC706开发板上尝试profile djpeg。

三. 运行Oprofile

正常启动嵌入式Linux后,在开发板的console上一次输入以下命令:

mount /dev/mmcblk0p1 /mnt

mkdir -p /home/root/work
cd /home/root/work
tar zxvf /mnt/jpeg-bin-nopg.tar.gz
cd jpeg-bin/bin
cp /mnt/park-2880x1800.jpg .
export LD_LIBRARY_PATH=/home/root/work/jpeg-bin/lib

cd /home/root/work
tar zxvf /mnt/rootfs.tar.gz
cd rootfs
chown root:root -R *
cp -R bin/* /usr/bin
cp -R lib/* /lib
cp /bin/which /usr/bin
cp /bin/dirname /usr/bin
mkdir -p /home/wave/xilinx/oprofileprj/rootfs/share
cp -R ./rootfs/* /home/wave/xilinx/oprofileprj/rootfs

cd /home/root/work
tar zxvf /mnt/libc.tar.gz
cp ./lib/libstdc*.* /lib

mkdir -p /home/wave/xilinx/libjpeg
cd /home/wave/xilinx/libjpeg
tar zxvf /mnt/jpeg-9.tar.gz

cp /mnt/vmlinux /home/root/work

cd /home/root/work/jpeg-bin/bin

opcontrol --init
opcontrol --vmlinux=/home/root/work/vmlinux
opcontrol --setup --event=CPU_CYCLES:100000::0:1 --session-dir=/home/root/

operf --vmlinux /home/root/work/vmlinux ./djpeg -bmp park-2880x1800.jpg > result.bmp
opreport -l ./djpeg

完成这一步后,我们就可以看到profiling的结果了,在笔者的平台上看到的内容的主要部分如下:
root@zynq:~/work/jpeg-bin/bin# opreport -l ./djpeg
Using /home/root/work/jpeg-bin/bin/oprofile_data/samples/ for samples directory.
CPU: ARM Cortex-A9, speed 666667 MHz (estimated)
Counted CPU_CYCLES events (CPU cycle) with a unit mask of 0x00 (No unit mask) count 100000
samples % image name symbol name
15293 58.6253 libc-2.17.so /lib/libc-2.17.so
2044

㈢ 在ARM上运行交叉编译后的opencv文件,没有输出

一、交叉编译opencv
构造:

下载:各个库的下载可以直接搜名字到官网下载
几个关键解释:
“--prefix=” 后边跟make install时的位置,本例中,libz在make install时将安装到/usr/arm-linux-gnueabihf中
“--host=” 后边跟arm-linux表明使用的是ARM环境
有configure的才能进行configure配置
4)所有的makefile修改类似
Libz的交叉编译
第一步:# ./configure --prefix=/usr/arm-linux-gnueabihf --shared
第二步:修改makefile,主要有下边几个,修改的时候通篇参照即可
CC=arm-linux-gnueabihf-gcc
AR=arm-linux-gnueabihf-ar rc
RANLIB=arm-linux-gnueabihf-ranlib
STRIP = arm-linux-gnueabihf-strip
如果有ARCH的话,ARCH=ARM
第三步:#sudo make
#sudo make install
Libjpeg的交叉编译
第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static CC=arm-linux-gnueabihf-gcc
第二步:参考1)中方法修改makefile
第三步:#sudo make
#sudo make install
Libpng的交叉编译
第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static CC=arm-linux-gnueabihf-gcc
第二步:参考1)中方法修改makefile
第三步:#sudo make
#sudo make install
Yasm的交叉编译
第一步:#./configure --host=arm-linux --prefix=/usr/arm-linux-gnueabihf --enable-shared --enable-static
第二步:修改makefile
第三步:#sudo make
#sudo make install
Libx264的交叉编译
第一步:#CC=arm-linux-gnueabihf-gcc ./configure --enable-shared --host=arm-linux --disable-asm --prefix=/usr/arm-linux-gnueabihf
第二步:修改config.mak里的参数,因为makefile要调用config.mak,所以修改方法同makefile
第三步:#sudo make
#sudo make install
Libxvid的交叉编译
第一步:首先切换目录 #cd build/generic
第二步:#./configure --prefix=/usr/arm-linux-gnueabihf --host=arm-linux --disable-assembly
第三步:#sudo make
#sudo make install
ffmpeg的交叉编译
第一步:
./configure --enable-cross-compile --target-os=linux --cc=arm-linux-gnueabihf-gcc --arch=arm --enable-shared --disable-static --enable-gpl --enable-nonfree --enable-ffmpeg --disable-ffplay --enable-ffserver --enable-swscale --enable-pthreads --disable-yasm --disable-stripping --enable-libx264 --enable-libxvid --extra-cflags=-I/usr/arm-linux-gnueabihf/include --extra-ldflags=-L/usr/arm-linux-gnueabihf/lib --prefix=/usr/arm-linux-gnueabihf
第二步:修改makefile文件
第三步:#sudo make
#sudo make install
第四步:将ffmpeg加入pkg-config
执行#sudo gedit /etc/bash.bashrc,在末尾加入
export LD_LIBRARY_PATH=/usr/arm-linux-gnueabihf/lib/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/arm-linux-gnueabihf /lib/pkgconfig
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_LIBDIR:/usr/arm-linux-gnueabihf /lib/
完毕后使用命令:#source /etc/bash.bashrc
或者单独使用三个export,不过寿命只在一个终端中,终端关闭时就失效。
几个关键解释:--extra-flags指向xvid的安装路径,--extra-ldflags指向x264的路径
安装cmake-gui
执行:#sudo apt-get install cmake-qt-gui
Opencv的交叉编译
第一步:修改opencv/platflrms/linux/目录下的arm-gnueabi.toolchain.cmake,将其所有删掉,写入:
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )
set( CMAKE_C_COMPILER arm-linux-gnueabihf-gcc )
set( CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++ )
第二步:在opencv目录下新建build目录,进入build目录,执行命令:
#cmake -DCMAKE_TOOLCHAIN_FILE=../platforms/linux/arm-gnueabi.toolchain.cmake ../
这时,要保证出现:

第三步:使用cmake-gui打开CMakeCache.txt,去掉所有的无关项,修改CMAKE_INSTALL_PREFIX,来确定make install的目录
第四步:#sudo make
#sudo make install
可能出现的错误:
opencv编译不通过,出现skip之类的,说明ffmpeg没编译好,或者其编译好了,但是pkg-config没有设置好,一定要设置好其环境
前边几步不通过的话,看看命令有没有少,或者有没有修改好makefile
在arm上使用时,一种方法时直接将编译好的opencv目录下的lib文件拷贝到开发板对应的/lib目录下,其他或者拷贝到自己指定的目录,并设置好环境变量即可使用

㈣ 如何使用oprofile对软件做profiling

下载的是linux-xlnx-xilinx-v14.7.tar.gz

解压缩后,用以下命令调出Linux kernel的配置界面:
export ARCH=arm
export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
make xilinx_zynq_defconfig
make xconfig 或者make menuconfig

在配置界面上将以下两项勾上:
General setup --->
[*] Profiling support
<*> OProfile system profiling

然后make uImage即可生成新的uImage,用来替换Xilinx Linux pre-built 14.7中的Linux kernel image。同时我们也需要vmlinux来检查profiling的结果。


Oprofile需要popt, bfd, liberty库,要在嵌入式单板上使用这些库,需要手工完成交叉编译。

针对popt 1.7,用以下命令完成编译:
./configure --prefix=/home/wave/xilinx/oprofileprj/rootfs --host=arm-xilinx-linux-gnueabi --with-kernel-support --disable-nls && make && make install

针对binutils 2.24,用以下命令完成编译:
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --enable-install-libbfd --enable-install-libiberty --enable-shared && make && make install
不过--enable-install-libiberty没有效果,所以需要手工把libiberty.a和libiberty.h拷贝到相应的位置。

针对oprofile 0.9.9,用以下命令完成编译:
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --with-kernel-support --with-binutils=/home/wave/xilinx/oprofileprj/rootfs && make && make install
配置过程结束后可能会有以下提示,因为没有打算用GUI和profile JITed code,所以直接忽视之。
config.status: executing libtool commands
Warning: QT version 3 was requested but not found. No GUI will be built.
Warning: The user account 'oprofile:oprofile' does not exist on the system.
To profile JITed code, this special user account must exist.
Please ask your system administrator to add the following user and group:
user name : 'oprofile'
group name: 'oprofile'
The 'oprofile' group must be the default group for the 'oprofile' user.

将编译完成的uImage,vmlinux,oprofile binary,重新编译的没有-pg的libjpeg binary以及tool chain的libc打包放到SD卡中,准备在ZC706开发板上尝试profile djpeg。

三. 运行Oprofile

正常启动嵌入式Linux后,在开发板的console上一次输入以下命令:

mount /dev/mmcblk0p1 /mnt

mkdir -p /home/root/work
cd /home/root/work
tar zxvf /mnt/jpeg-bin-nopg.tar.gz
cd jpeg-bin/bin
cp /mnt/park-2880x1800.jpg .
export LD_LIBRARY_PATH=/home/root/work/jpeg-bin/lib

cd /home/root/work
tar zxvf /mnt/rootfs.tar.gz
cd rootfs
chown root:root -R *
cp -R bin/* /usr/bin
cp -R lib/* /lib
cp /bin/which /usr/bin
cp /bin/dirname /usr/bin
mkdir -p /home/wave/xilinx/oprofileprj/rootfs/share
cp -R ./rootfs/* /home/wave/xilinx/oprofileprj/rootfs

cd /home/root/work
tar zxvf /mnt/libc.tar.gz
cp ./lib/libstdc*.* /lib

mkdir -p /home/wave/xilinx/libjpeg
cd /home/wave/xilinx/libjpeg
tar zxvf /mnt/jpeg-9.tar.gz

cp /mnt/vmlinux /home/root/work

cd /home/root/work/jpeg-bin/bin

opcontrol --init
opcontrol --vmlinux=/home/root/work/vmlinux
opcontrol --setup --event=CPU_CYCLES:100000::0:1 --session-dir=/home/root/

operf --vmlinux /home/root/work/vmlinux ./djpeg -bmp park-2880x1800.jpg > result.bmp
opreport -l ./djpeg

完成这一步后,我们就可以看到profiling的结果了,在笔者的平台上看到的内容的主要部分如下:
root@zynq:~/work/jpeg-bin/bin# opreport -l ./djpeg
Using /home/root/work/jpeg-bin/bin/oprofile_data/samples/ for samples directory.
CPU: ARM Cortex-A9, speed 666667 MHz (estimated)
Counted CPU_CYCLES events (CPU cycle) with a unit mask of 0x00 (No unit mask) count 100000
samples % image name symbol name
15293 58.6253 libc-2.17.so /lib/libc-2.17.so
2044

㈤ 如何使用oprofile对软件做profiling

关于Xilinx Zynq-7000带来的新的系统设计思路,以及Profiling的对象libjpeg,前文已经描述过了,再此不再赘述。

一. Oprofile简介

Profiling是对不同性能特征的数据的形式化总结或分析,它通常以图形和表的形式出现。它提供为特定的处理器事件收集的采样百分数或数 量,比如cache miss rate、TLB miss rate等等。一般来说,主要目的是为了找出软件中的性能瓶颈,然后有针对性的优化以提升软件的整体性能。

Oprofile 是用于 Linux 的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括ARM, PowerPC, MIPS, IA32, IA64 和 AMD Athlon等等。它的开销很小,从Linux 2.6 版起,它被包含进了Linux内核中。

Oprofile可以收集有关处理器事件的信息,帮助用户识别诸如循环的展开、cache的使用率低、低效的类型转换和冗余操作、错误预测转移 等问题。Oprofile是一种细粒度的工具,可以为指令集或者为函数、系统调用或中断处理例程收集采样。Oprofile 通过取样来工作。使用收集到的评测数据,用户可以很容易地找出性能问题。

通过监察CPU的hardware events,oprofile可以在运行状态下对整个Linux系统进行profiling。Profiling的对象可以是Linux kernel (包括moles和interrupt handlers), shared libraries或者应用程序。

从0.9.8版本开始,oprofile支持Perf_events profiling mode模式。应用程序operf被用来控制profiling过程;而在legacy mode下,是通过opcontrol脚本和oprofiled daemon来完成的。Operf不再象legacy mode那样需要OProfile kernel driver,它直接和Linux Kernel Performance Events Subsystem打交道。使用operf,就可以用普通用户的身份来profiling用户的应用程序了,当然如果需要对整个系统来profiling 的时候还是需要root权限的。

如果硬件不支持OProfile使用performance counters,OProfile就只能工作在Timer Mode下了。Timer Mode只能在legacy profiling mode下使用,即只能通过opcontrol脚本来控制。

Oprofile的website为:http://oprofile.sourceforge.net/

可以支持的处理器的hardware event类型:http://oprofile.sourceforge.net/docs/

对于Zynq-7000来说,http://oprofile.sourceforge.net/docs/armv7-ca9- events.php 列出了ARM Cortex-A9内核PMU(Performance Monitor Unit)所支持的所有hardware event种类,可以看出oprofile可以支持很多深入处理器内部的分析。

http://oprofile.sourceforge.net/examples/ 提供了一些oprofile生成的结果,可以方便开发者在开始使用之前了解oprofile能够做到哪些事情。

Oprofile的详细使用文档:http://oprofile.sourceforge.net/doc/index.html

Oprofile的优势:

? 比较低的运行开销

? 对被profiling的对象影响很小

? 可以profiling中断服务程序(interrupt handlers)

? 可以profiling应用程序和shared libraries

? 可以profiling dynamically compiled (JIT) code

? 可以对整个系统做profiling

? 可以观察CPU内部的细节,例如cache miss rate

? 可以多源代码做annotation

? 可以支持instruction-level的profiling

? 可以生成call-graph profiles

不过OProfile也不是万能的,它也有自己的局限性:

? 只能在x86, ARM, 和PowerPC架构上生成call graph profiles

? 不支持100%精确的instruction-level profiling

? 对dynamically compiled (JIT) code profiling的支持还不完善。

无论如何,Oprofile的功能都比gprof要强很多,代价是配置起来会比较麻烦。

二. 编译Oprofile

首先最好在Linux kernel里面选中Oprofile driver,以获得全面的支持。

下载Linux kernel Source:从https://github.com/Xilinx/linux-xlnx 可以下载到Xilinx提供的验证好的内核。如果不方便使用Linux下的git工具,可以单击页面上的releases找到相应的版本下载tar ball。下载的时候最好选tar.gz格式的,而不是zip格式的,因为后者在处理symbol link的时候有可能会出问题。

因为笔者使用的是Xilinx Linux pre-built 14.7,所以这里下载的是linux-xlnx-xilinx-v14.7.tar.gz

解压缩后,用以下命令调出Linux kernel的配置界面:

export ARCH=arm

export CROSS_COMPILE=arm-xilinx-linux-gnueabi-

make xilinx_zynq_defconfig

make xconfig 或者make menuconfig

在配置界面上将以下两项勾上:

General setup --->

[*] Profiling support

<*> OProfile system profiling

然后make uImage即可生成新的uImage,用来替换Xilinx Linux pre-built 14.7中的Linux kernel image。同时我们也需要vmlinux来检查profiling的结果。

Oprofile需要popt, bfd, liberty库,要在嵌入式单板上使用这些库,需要手工完成交叉编译。

针对popt 1.7,用以下命令完成编译:

./configure --prefix=/home/wave/xilinx/oprofileprj/rootfs --host=arm-xilinx-linux-gnueabi --with-kernel-support --disable-nls && make && make install

针对binutils 2.24,用以下命令完成编译:

./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --enable-install-libbfd --enable-install-libiberty --enable-shared && make && make install

不过--enable-install-libiberty没有效果,所以需要手工把libiberty.a和libiberty.h拷贝到相应的位置。

针对oprofile 0.9.9,用以下命令完成编译:

./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --with-kernel-support --with-binutils=/home/wave/xilinx/oprofileprj/rootfs && make && make install

配置过程结束后可能会有以下提示,因为没有打算用GUI和profile JITed code,所以直接忽视之。

config.status: executing libtool commands

Warning: QT version 3 was requested but not found. No GUI will be built.

Warning: The user account 'oprofile:oprofile' does not exist on the system.

To profile JITed code, this special user account must exist.

Please ask your system administrator to add the following user and group:

user name : 'oprofile'

group name: 'oprofile'

The 'oprofile' group must be the default group for the 'oprofile' user.

将编译完成的uImage,vmlinux,oprofile binary,重新编译的没有-pg的libjpeg binary以及tool chain的libc打包放到SD卡中,准备在ZC706开发板上尝试profile djpeg。

三. 运行Oprofile

正常启动嵌入式Linux后,在开发板的console上一次输入以下命令:

mount /dev/mmcblk0p1 /mnt

mkdir -p /home/root/work

cd /home/root/work

tar zxvf /mnt/jpeg-bin-nopg.tar.gz

cd jpeg-bin/bin

cp /mnt/park-2880x1800.jpg .

export LD_LIBRARY_PATH=/home/root/work/jpeg-bin/lib

cd /home/root/work

tar zxvf /mnt/rootfs.tar.gz

cd rootfs

chown root:root -R *

cp -R bin/* /usr/bin

cp -R lib/* /lib

cp /bin/which /usr/bin

cp /bin/dirname /usr/bin

mkdir -p /home/wave/xilinx/oprofileprj/rootfs/share

cp -R ./rootfs/* /home/wave/xilinx/oprofileprj/rootfs

cd /home/root/work

tar zxvf /mnt/libc.tar.gz

cp ./lib/libstdc*.* /lib

mkdir -p /home/wave/xilinx/libjpeg

cd /home/wave/xilinx/libjpeg

tar zxvf /mnt/jpeg-9.tar.gz

cp /mnt/vmlinux /home/root/work

cd /home/root/work/jpeg-bin/bin

opcontrol --init

opcontrol --vmlinux=/home/root/work/vmlinux

opcontrol --setup --event=CPU_CYCLES:100000::0:1 --session-dir=/home/root/

operf --vmlinux /home/root/work/vmlinux ./djpeg -bmp park-2880x1800.jpg > result.bmp

opreport -l ./djpeg

完成这一步后,我们就可以看到profiling的结果了,在笔者的平台上看到的内容的主要部分如下:

root@zynq:~/work/jpeg-bin/bin# opreport -l ./djpeg

Using /home/root/work/jpeg-bin/bin/oprofile_data/samples/ for samples directory.

CPU: ARM Cortex-A9, speed 666667 MHz (estimated)

Counted CPU_CYCLES events (CPU cycle) with a unit mask of 0x00 (No unit mask) count 100000

samples % image name symbol name

15293 58.6253 libc-2.17.so /lib/libc-2.17.so

2044 7.8356 libjpeg.so.9.0.0 ycc_rgb_convert

1964 7.5289 libjpeg.so.9.0.0 jpeg_idct_16x16

1918 7.3526 libjpeg.so.9.0.0 decode_mcu

1570 6.0186 libjpeg.so.9.0.0 jpeg_idct_islow

1567 6.0071 djpeg finish_output_bmp

528 2.0241 libjpeg.so.9.0.0 jpeg_fill_bit_buffer

397 1.5219 djpeg put_pixel_rows

73 0.2798 vmlinux ___from_user

70 0.2683 libjpeg.so.9.0.0 decompress_onepass

65 0.2492 libjpeg.so.9.0.0 jpeg_huff_decode

56 0.2147 vmlinux get_page_from_freelist

50 0.1917 vmlinux __memzero

45 0.1725 vmlinux ___to_user_std

41 0.1572 vmlinux _raw_spin_unlock_irqrestore

15 0.0575 vmlinux do_page_fault

14 0.0537 vmlinux __generic_file_aio_write

13 0.0498 vmlinux _raw_spin_unlock_irq

11 0.0422 vmlinux free_hot_cold_page

11 0.0422 vmlinux vector_swi

10 0.0383 vmlinux handle_pte_fault

从结果中我们可以看到libjpeg.so.9.0.0, djpeg和vmlinux中的symbol name已经可以被正确的解析出来了,和gprof的结果基本一致。相比gprof,oprofile可以在更大的范围内完成profiling。

我们还可以用以下命令观察源代码中特定行的执行时间,进一步缩小优化的范围,达到事半功倍的效果。

opannotate --source ./djpeg > opannotate.txt

四. 小结

通过实验,我们可以看到Oprofile可以提供更丰富的profiling结果,可以更好的帮助开发者找到瓶颈,通过有针对性的优化提升软件 性能;profiling的结果也可以帮助开发者将性能瓶颈代码通过Xilinx HLS工具用硬件加速器来实现,从而为进一步提升整个嵌入式系统的性能打开了大门。

㈥ zynq linux 移植过程中编译u-boot出现问题

明显是提示没有库文件吧。 libmpfr.so.1: cannot open shared object file: No such file or directory

热点内容
aspnet插入数据库数据 发布:2025-04-16 08:28:20 浏览:518
区块链供应链应用开发智能存储 发布:2025-04-16 08:12:37 浏览:798
x86架构存储 发布:2025-04-16 08:12:27 浏览:902
将电脑的文件上传到服务器 发布:2025-04-16 08:10:05 浏览:334
sql中between 发布:2025-04-16 07:56:28 浏览:769
安卓手机多功能键在哪里 发布:2025-04-16 07:56:27 浏览:55
pythondict中文 发布:2025-04-16 07:55:42 浏览:466
存储管理常见问题 发布:2025-04-16 07:53:36 浏览:348
python内存大小 发布:2025-04-16 07:37:51 浏览:283
安卓还有什么登录器 发布:2025-04-16 07:37:49 浏览:790