给Android交叉编译ethtool工具

/ 0评 / 11

缘由

在测试一款Android系统的Amlogic机顶盒的时候,发现机顶盒的标配千兆网卡RTL8211F只能在协商成百兆的情况下正常运行,千兆状态下无法正常运行,于是想通过ethtool对以太网卡进行一些设置,但是标准的Android下并没有带有ethtool,想想也正常,一个用户使用的系统很难有这些调试工具的,于是就自己编译一个,这里做一些记录

原理

实际Android系统当中的大部分软件是跑在Java虚拟机下面的,但Android本质上还是一个以Gnu/Linux为底层架构的移动操作系统,也有Kernel,所以实际上普通的Linux软件通过相关工具链SDK重新编译移植,同样可以运行在ARM处理器下的Android,本例以网络管理工具ethtool为例,其他工具同理。

过程

1、准备编译环境

目标CPU:Amlogic S922x
目标系统:Android 9.0 armv7a,别问我为什么是armv7,因为Amlogic的处理器都是跑的armv7架构的系统。

任意Linux系统安装
因为是传统的Linux交叉编译,实际上只需要对应架构的SDK即可,系统并没有太大关系,此处使用ubuntu18.04.3 LTS为例。

下载编译工具链
gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi.tar.xz

这里为什么使用6.3版本的gcc,原因是Amlogic的Release Info文档上要求的,我并没有尝试别的版本的SDK工具链,实际上对于轻型应用应当也是可以的。

下载完成后如下安装,实际上就是解压并放在PATH路径下方便调用

cd /opt/toolchains/
#先进入放置SDK的目录
tar-xvf arm-linux-gnueabi/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi.tar.xz
#解压SDK到opt/toolchains
export PATH=/opt/toolchains/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi/bin:$PATH
#将SDK的bin目录加入PATH方便调用

完成之后在SSH会话任意目录下面执行arm...按tab键应该能补全上述目录下的SDK执行文件,实际上就是gcc,那就算成功。

2、准备ethtool源码

这个也非常简单,直接找到ethtool官网的release下载即可

ethtool官网:https://mirrors.edge.kernel.org/pub/software/network/ethtool/
下载后解压到任意目录即可

3、编译程序

创建一下脚本成sh文件

#!/bin/sh
ARM_TOOLCHAIN_DIR=/opt/toolchains/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi/bin
export CROSS_COMPILE="opt/toolchains/gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabi/bin/arm-linux-gnueabi-"
export AR="${CROSS_COMPILE}ar"
export AS="${CROSS_COMPILE}as"
export LD="${CROSS_COMPILE}ld"
export NM="${CROSS_COMPILE}nm"
export CC="${CROSS_COMPILE}gcc"

export FC="${CROSS_COMPILE}gfortran "
export RANLIB="${CROSS_COMPILE}ranlib"
export STRIP="${CROSS_COMPILE}strip"
export OBJCOPY="${CROSS_COMPILE}objcopy"  
export CFLAGS="-Os -pipe -O2 -static"

./configure --target=arm-none-eabi --host=arm-none-eabi

其实不用脚本也行,用这个就是可以偷懒不用每次都写configure,总之最终运行一下这个脚本,然后再make,最终会在同目录下生成ethtool的bin文件,复制到Android当中即可运行。

当然你可以提前运行下面这个命令,看一下编译的目标是否正确,有时候如果toolchain目录错误会自动调用当前的gcc进行编译,那么编译的目标系统就不对,当然就无法运行。

file ethtool

ethtool: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=64fe3d89345fd998a0ed9c96c47db3228c0e0b05, with debug_info, not stripped

4、一些问题

- 如何确定目标系统的规格
直接在目标系统找到任意一个bin文件,file xxx之后,就可以知道目标系统的情况,据此编译即可

- ./configure当中的tartget和host如何填写
在工具链加入PATH后,任意目录输入arm,按下tab补全后运行gcc -v即可查询到编译工具链所对应的target,也是需要填写到配置当中的target和host,例如本文的SDK版本就是运行如下命令

arm-none-eabi-gcc -v

Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-none-eabi/6.3.1/lto-wrapper
Target: arm-none-eabi
Configured with: ../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/lib/include' --mandir='/usr/lib/share/man' --infodir='/usr/lib/share/info' --sysconfdir=/etc --localstatedir=/var
…………
gcc version 6.3.1 20170620 (15:6.3.1+svn253039-1build1)

输出当中所示Target即当前SDK对应的目标系统。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据