想在ARM64上使用一下SystemTap, 但是发现移植起来比较困难,网上也没有什么比较完整的博客,干脆自己折腾一遍,然后写出来分享一下。
参考 《奔跑吧linux内核》一书
文章目录
1 环境
ARM64交叉编译器: aarch64-linux-gnu-gcc 7.5.0
zlib-1.2.11
elfutils-0.186
systemtap-4.6
虚拟机: Ubuntu 20.04
2 工具下载
SystemTap 需要使用到zlib库和elfutils库, 因此需要先编译 zlib 和 elfutils, 最后才编译systemtap
1 下载 zlib
网址: http://www.zlib.net/
2 下载 elfutils
网址: https://sourceware.org/elfutils/
3 下载 systemtap
网址:https://sourceware.org/systemtap/wiki/SystemTapReleases
3 编译
因为在ARM64 平台上编译,因此需要编译ARM版本和PC版本(Ubuntu)
3.1 ARM平台版本编译
3.1.1 编译zlib
-
切换路径
cd zlib-1.2.11 -
配置
./configure --prefix=$PWD/_install
配置的安装路径为 /home/lcc/Tmp/SystemTap/zlib-1.2.11/_install -
修改Makefile , 把里面的cc 修改为 aarch64-linux-gnu-gcc
注:后面链接的时候用的是gcc 因此需要手动修改makefile
-
编译
make && make install
3.1.2 编译 elfutils
- 切换路径
cd elfutils-0.186 - 配置
LDFLAGS–>指明库的路径, zlib安装路径下的lib
–with-zlib=yes -->必须配置,否则报错
CPPFLAGS -->指明头文件记录,zlib安装路径下的include
CFLAGS -->链接zlib的库,否则会报错
–disable-libdebuginfod --disable-debuginfod -->根据报错信息添加的
配置的安装路径为 /home/lcc/Tmp/SystemTap/elfutils-0.186/_install
./configure --prefix=$PWD/_install --host=aarch64-linux-gnu --with-zlib=yes LDFLAGS=-L/home/lcc/Tmp/SystemTap/zlib-1.2.11/_install/lib CPPFLAGS=-I/home/lcc/Tmp/SystemTap/zlib-1.2.11/_install/include CFLAGS=-lz --disable-libdebuginfod --disable-debuginfod
- 编译
make && make install
3.1.3 编译 systemtap
报错记录1
解决方式:sudo apt-get install gettext
- 切换路径
cd systemtap-4.6 - 配置configure
–with-elfutils --> 前面elfutils-0.186 包的位置
CXXFLAGS=-static CFLAGS=-static --> 静态编译
LIBS --> 链接 libz库
CPPFLAGS= --> elfutils 头文件目录
LDFLAGS --> elfutils 和 zlib 库的路径
配置的安装路径为 /home/lcc/Tmp/SystemTap/systemtap-4.6/_install
./configure --prefix=$PWD/_install --host=aarch64-linux-gnu --with-elfutils=/home/lcc/Tmp/SystemTap/elfutils-0.186 CXXFLAGS=-static CFLAGS=-static LIBS=-lz --disable-docs --disable-refdocs --disable-grapher --without-rpm --disable-option-checking --disable-nls --enable-FEATURE=no --disable-ssp --without-nss --disable-translator CPPFLAGS=-I/home/lcc/Tmp/SystemTap/elfutils-0.186/_install/include LDFLAGS="-L/home/lcc/Tmp/SystemTap/zlib-1.2.11/_install/lib -L/home/lcc/Tmp/SystemTap/elfutils-0.186/_install/lib"
- 编译
make && make install
3.2 PC 平台版本编译
PC 平台版本只需要编译 systemtap 即可
-
安装一些基本的依赖库
sudo apt-get install elfutils
sudo apt-get install libdw-dev
sudo apt-get install build-essential
sudo apt-get install gettext -
切换路径
cd systemtap-4.6 -
清理之前的编译配置
make clean; make distclean -
配置
./configure --prefix=$PWD/pc_install --disable-docs
配置的安装路径为 /home/lcc/Tmp/SystemTap/systemtap-4.6/pc_install
安装路径要与前面ARM版本的不一样才行 -
编译
make && make install
3.3 内核编译
-
内核需要配置如下
CONFIG_RELAY
CONFIG_KPROBES -
内核需要编译一次
编译完后会产生Module.symvers, 如果没有就执行make modules
4 测试
4.1 编译测试demo
- 测试demo hello.stp 内容如下
probe begin
{
print ("hello system tap")
print ("\n")
exit ()
}
- 编译
2.1)切换到root, 编译需要root权限, 用sudo 可能会找不到交叉编译器
2.2) 在root用户下, 将交叉编译配置到环境中
2.3)把文件编译为ko
普通用户下执行的报错信息
使用sudo 的报错信息, 没找到交叉编译器, 因此这里才要求切换到root用户下去执行
/home/lcc/Tmp/SystemTap/systemtap-4.6/pc_install/bin/stap: 这是PC版本编译出来的
/home/lcc/Tmp/SystemTap/systemtap-4.6/pc_install/bin/stap -gv -a arm64 -r /home/lcc/Work/qemu_arm/ARM64/linux-5.16 -B CROSS_COMPILE=aarch64-linux-gnu- -m hello.ko hello.stp
编译后产生 hello.ko 文件
为方便,写一个简单的编译脚本, 后续编译直接执行 ./systemtap_make.sh hello.stp 即可
#!/bin/sh
set -x
if [ $# != 1 ] ; then
echo "USAGE: $0 xxx.stp"
exit 1
fi
echo "file name:$1"
source_file=`echo "$1" |awk -F "." '{print $1}'`
/home/lcc/Tmp/SystemTap/systemtap-4.6/pc_install/bin/stap -gv -a arm64 -r /home/lcc/Work/qemu_arm/ARM64/linux-5.16 -B CROSS_COMPILE=aarch64-linux-gnu- -m $source_file.ko $1
4.2 拷贝程序并运行
- 将 /home/lcc/Tmp/SystemTap/systemtap-4.6/_install 文件拷贝到ARM开发板上的相同路径, 否则程序无法正常运行
注: 必须建立相同路径,否则执行会报错 - 把 hello.ko 拷贝到ARM开发板上
- . 运行 ./staprun hello.ko
下面的内容全部是在开发板上运行的, 没有/home/lcc/Tmp/SystemTap/systemtap-4.6/ 目录就需要先创建一下