一. 背景
手上已有的iperf工具在新设备上无法使用:
# iperf
/system/bin/sh: /system/bin/iperf: not executable: 64-bit ELF file
使用readelf查看iperf程序,该二进制程序是ELF64,ARM系统架构的;
$ readelf -a iperf
ELF 头:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
类别: ELF64
数据: 2 补码,小端序 (little endian)
版本: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: DYN (共享目标文件)
系统架构: ARM
版本: 0x1
...
那我们在确认一下设备的处理器架构:aarch64
# cat /proc/cpuinfo
Processor : AArch64 Processor rev 14 (aarch64)
架构不一致,自然是无法运行了。
那么只有自己动手丰衣足食了,在该设备环境下编译出对应的iperf文件了。
二. iperf移植/编译
1. 下载iperf工具, 这里使用的版本是:iperf-3.1.3
2. 将iperf源码解压到/external/下,源码目录如下:
aclocal.m4
bootstrap.sh*
config/
config.log
config.status*
configure*
configure.ac
contrib/
docs/
examples/
.gitignore
INSTALL
iperf3.spec
iperf3.spec.in
libtool*
LICENSE
Makefile
Makefile.am
Makefile.in
make_release*
README.md
RELEASE_NOTES
src/
test_commands.sh*
3. 参照Makefile文件以及其他库的Android.mk(如external/tcpdump/Android.mk)编写Android.mk文件。
编译过程中会遇到一些问题,多次回头修改mk文件。
最终success的Android.mk文件如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
src/cjson.c \
src/iperf_client_api.c \
src/iperf_locale.c \
src/iperf_server_api.c \
src/iperf_udp.c \
src/main.c \
src/tcp_info.c \
src/timer.c \
src/t_units.c \
src/units.c \
src/iperf_api.c \
src/iperf_error.c \
src/iperf_sctp.c \
src/iperf_tcp.c \
src/iperf_util.c \
src/net.c \
src/tcp_window_size.c \
src/t_timer.c \
src/t_uuid.c
LOCAL_CFLAGS += -D_BSD_SOURCE
LOCAL_CFLAGS += -DHAVE_CONFIG_H
LOCAL_CFLAGS += -D_U_="__attribute__((unused))"
LOCAL_CFLAGS += -Werror
LOCAL_CFLAGS += -Wno-address-of-packed-member
LOCAL_CFLAGS += -Wno-sign-compare
LOCAL_CFLAGS += -Wno-incompatible-pointer-types-discards-qualifiers
LOCAL_CFLAGS += -Wno-unused-parameter
LOCAL_CFLAGS += -Wno-unused-result
LOCAL_CFLAGS += -Wno-unused-variable
LOCAL_CFLAGS += -Wno-pointer-sign
LOCAL_CFLAGS += -Wno-unused-function
LOCAL_CFLAGS += -Wno-implicit-function-declaration
LOCAL_CFLAGS += -DHAVE_CONFIG_H
#LOCAL_LDLIBS += -lpthread
LOCAL_SHARED_LIBRARIES := libc libcutils libm libnetutils
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := iperf
include $(BUILD_EXECUTABLE)
4. 执行配置脚本
./configure
5. 在该项目编译环境下直接执行 mm 进行编译, 编译出/system/xbin/iperf
6. 看一下属性, AArch64,没毛病
$ readelf -a out/target/product/xxxx/system/xbin/iperf
ELF 头:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
类别: ELF64
数据: 2 补码,小端序 (little endian)
版本: 1 (current)
OS/ABI: UNIX - System V
ABI 版本: 0
类型: DYN (共享目标文件)
系统架构: AArch64
版本: 0x1
7. push进设备验证, 可以运行。 但是这个错误是什么情况呢?
# iperf -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.43.8, port 38818
iperf3: error - unable to create a new stream: No such file or directory
8. 调查代码发现iperf_api.c在“/tmp/iperf3.XXXXXX” 下分配空间有问题。
根目录下不允许写文件操作,我们把路径改到/data/local/tmp/iperf3.XXXXXX下。
编译、验证。OK。