libbpf-bootstrap安卓aarch64适配交叉编译

1.为什么移植

疑惑

起初我也认为,像libbpf-bootstrap这样在ebpf程序开发中很常用的框架,理应支持不同架构的交叉编译。尤其是向内核态的ebpf程序本身就是直接通过clang的-target btf直接生成字节码,各个内核上的ebpf虚拟机大同小异,对于字节码大概率是兼容的。那么问题就落在用户态程序生成上面。

加载器

由于libbpf-bootstrap框架使用bpftools将xxx.bpf.c生成为xxx.skel.h再注入到用户态xx.c程序当中,因此,用户态程序本身就是字节码的加载器。基于安卓的ebpf开发也有不少前辈探索过,如下图

图源:eBPF on Android之stackplz从0到1 - SeeFlowerX ps:强推他的安卓package用户态程序堆栈追踪工具,我的不少灵感也来自于他的开发过程,在此谢过SeeFlowerX前辈了。

最终他选择的解决方案是golang的ebpf生态,交叉编译相当方便。但我面临的是性能的需要,我还是打算折腾一下纯C的开发生态,但是AOSP又实在太过庞大,且面临API变动会使我们很头疼。

2.使用方法

准备

  • Android NDK
  • gcc-aarch64-linux-gnu
  • Android phone with root and unlock BL

安装依赖

git clone https://github.com/JiaHuann/libbpf-bootstrap-android
cd libbpf-bootstrap-android
sudo apt install gcc-aarch64-linux-gnu llvm clang
wget https://dl.google.com/android/repository/android-ndk-r25c-linux.zip?hl=zh-cn android-ndk-r25c-linux.zip
unzip android-ndk-r25c-linux

设置环境变量

vim ~/.bashrc
export your android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin to PATH

编译和推送

cd examples/c && makeadb devices
adb remount     # may fail, you can leave with issure.
adb push examples/c/btf_file/* example/c/your_executable_file /data/local/tmp
adb shell    #into android kernel shell

安卓shell操作

cd /data/local/tmp && chmod +x your_excutable_file
./run
Congratulations!

运行效果如下:

 资料直通车:Linux内核源码技术学习路线+视频教程内核源码

学习直通车:Linux内核源码内存调优文件系统进程管理设备驱动/网络协议栈

3.针对安卓的特性

  • libelf,libz on aarch64 embedded.
  • x86 -> android13(aarch64) cross-compile you can directly write ebpf both kernel-program and user-program on x86 machine.
  • FlameGraph embedded to monitor performance.
  • For None BTF/vmlinux android-kernel(CONFIG_DEBUG_INFO_BTF not set) support.
  • adb debug (after compiling&linking, directly push into android-phone) embedded.

4.移植过程

寻找方案

于是我继续折腾libbpf-bootstrap的交叉编译,好巧不巧,在How to cross-compile programs from amd64 to arm64 · Issue #144 · libbpf/libbpf-bootstrap · GitHub这个issure中也发现了这个问题,显然,直到现在还是open状态,给出的maintainer给出的方案是

Yes, libbpf depends on libelf and libz, so you need declare where the libraries and header files can be found. such as,  make EXTRA_CFLAGS="-IXXX" EXTRA_LDFLAGS="-LXXX" ARCH=arm64. You can get a copy of these libraries from here for quickly verification if you don't want to cross-compile them yourself.

我寻思着也可行,但是几经折腾后我发现了很多问题:

  • Android NDK在r17已经宣称不支持gcc,在r18已经删掉,最新版的r25只有clang,在使用NDK交叉编译时会遇到一堆莫名其妙的问题。
  • 我的开发机并没有打开CONFIG_DEBUG_BTF_INFO,但是为了方便我想引入外部BTF file,但是有些目录在android kernel并不可写。

解决

最终我在本地几经尝试交叉编译出了libbpf依赖的libelf以及libz,很有趣的是在编译的过程中我使用aarch64-linux-gnu竟然编出来的依赖竟然可以用。在libbpf-bootstrap中,想到用户态程序可能也没有太多编译上的新特性,于是我继续使用aarch64-linux-gnu交叉编译,果然还是可行。最终,aarch64的可执行文件还是编译了出来。

为了优化大家的开发速度,和不再折腾这个过程,我将所有的细节,依赖都合并了起来,并且修改了libbpf源码加入了外部BTF文件路径,且在repo中放入了一个a13-5.10的btf 文件,我写定了路径为/data/local/tmp,push到这里就可以使用。关于这个btf版本问题,我的内核是5.4但是目前使用起来尚未发现问题。GitHub - JiaHuann/libbpf-bootstrap-android: Do something to fit android aarch64 to develop ebpf programs using libbpf-bootstrap framework

至此,可以ebpf程序源码可以无需任何改动就运行在安卓kernel(当然有一些kernel版本决定的特性和api还是会限制的,这个与是否交叉编译运行无关)

PS:当初为了验证是否可行,全是草率的静态链接的,生成的可执行文件可能会有点大,后续即将马上修改为动态链接。

当然,如果有条件还是使用arm虚拟机或者qemu开发吧,交叉编译确实不好折腾: (当我还在折腾的时候我同学的mac已经能run了

原文作者:Linux内核之旅

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/127424.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

音频——I2S DSP 模式(五)

I2S 基本概念飞利浦(I2S)标准模式左(MSB)对齐标准模式右(LSB)对齐标准模式DSP 模式TDM 模式 文章目录 DSP formatDSP A时序图逻辑分析仪抓包 DSP B时序图逻辑分析仪抓包 DSP format DSP/PCMmode 分为 Mode-A 和 Mode-B 共 2 种模式。不同芯⽚有的称为 PCM mode 有的称为 DSP m…

UG二次开发 向量叉乘 UF_VEC3_cross

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介: UG二次开发 向量叉乘 UF_VEC3_cross,xyz三个向量已知2个求另外1个。 效果: 代码: #include "me.hpp"void ufusr(char* param, int* retcode, int paramLe…

数据结构与算法学习(day4)——解决实际问题

前言 在本章的学习此前,需要复习前三章的内容,每个算法都动手敲一遍解题。宁愿学慢一点,也要对每个算法掌握基本的理解! 前面我们学习了简化版桶排序、冒泡排序和快速排序三种算法,今天我们来实践一下前面的三种算法。…

C# OpenVinoSharp PP-TinyPose 人体姿态识别

效果 项目 部分代码 using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;name…

机器学习——支持向量机(SVM)

机器学习——支持向量机(SVM) 文章目录 前言一、SVM算法原理1.1. SVM介绍1.2. 核函数(Kernel)介绍1.3. 算法和核函数的选择1.4. 算法步骤1.5. 分类和回归的选择 二、代码实现(SVM)1. SVR(回归&a…

【矩阵分解】PCA - 主成分分析中的数学原理

前言 本文主要对PCA主成分分析中的数学原理进行介绍,将不涉及或很少涉及代码实现或应用,阅读前请确保已了解基本的机器学习相关知识。 文章概述 PCA主成分分析属于矩阵分解算法中的入门算法,通过分解特征矩阵来实现降维。 本文主要内容&a…

硬件学习件Cadence day13 PCB设计中一些设置, 铜皮到钻孔的距离设置, 差分线的设置,板层信息表

1. 设置铺铜中铜皮到钻口,连线的距离。 1. 打开设置界面 2. 设计界面 调整到 铜皮设置界面 2. 高速线的设置 (差分对传输线的设置) 1. 打开设置界面 2. 来到 差分线设置界面 3. 把界面往右看, 设置差分线的之间距离,…

(二十四)大数据实战——Flume数据流监控之Ganglia的安装与部署

前言 本节内容我们主要介绍一下Flume数据流的监控工具Ganglia。Ganglia是一个开源的分布式系统性能监控工具。它被设计用于监视大规模的计算机群集(包括集群、网格和云环境),以便收集和展示系统和应用程序的性能数据。Ganglia 可以轻松地扩展…

【多线程】线程安全 问题

线程安全 问题 一. 线程不安全的典型例子二. 线程安全的概念三. 线程不安全的原因1. 线程调度的抢占式执行2. 修改共享数据3. 原子性4. 内存可见性5. 指令重排序 一. 线程不安全的典型例子 class ThreadDemo {static class Counter {public int count 0;void increase() {cou…

3D点云测量:计算三个平面的交点

文章目录 0. 测试效果1. 基本内容文章目录:3D视觉测量目录0. 测试效果 1. 基本内容 计算三个平面的交点需要找到满足所有三个平面方程的点。三个平面通常由它们的法向量和通过它们的点(或参数形式的方程)来定义。以下是计算三个平面的交点的一般步骤: 假设有三个平面,分别…

MyBatis-Plus排除不必要的字段

查询学生信息排除年龄列表 📚🔍 使用MyBatis-Plus排除某些字段。如果你想要进行查询,但又不需要包含某些字段,那么这个功能将非常适合你。🔍🎓📝 1. 学生信息查询-排除年龄列表 在使用 MyBat…

【Cisco Packet Tracer】管理方式,命令,接口trunk,VLAN

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

【Redis】为什么要学 Redis

文章目录 前言一、Redis 为什么快二、Redis 的特性2.1 将数据储存到内存中2.2 可编程性2.3 可扩展性2.4 持久性2.5 支持集群2.6 高可用性 三、Redis 的应用场景四、不能使用 Redis 的场景 前言 关于为什么要学 Redis 这个问题,一个字就可以回答,那就是&…

Vue3+Ts+Vite项目(第一篇)——使用Vite创建Vue3项目

概述 保姆级详解,带你使用 Vite 创建 Vue3 项目,全程cv即可 文章目录 概述一、 安装 Vite二、 创建项目2.1 运行上述命令后,会让我们输入项目名称。可以写一个 vue3-study2.2 选择项目模板,此处选择 Vue,然后回车确定…

mysql课堂笔记 mac

目录 启动mac上的mysql 进入mysql mac windows 创建数据库 创建表 修改字段数据类型 修改字段名 增加字段 删除字段 启动mac上的mysql sudo /usr/local/mysql/support-files/mysql.server start 直接输入你的开机密码即可。 编辑 进入mysql mac sudo /usr/local…

深入浅出AXI协议(6)——传输属性

一、前言 在之前的文章中,我们介绍的主要内容是AXI协议的数据读写结构和读写响应结构,主要讲述了当遇到各种特殊情况时,AXI如何完成数据的读写操作,最后介绍了读写响应的4种类型。 在本文中,我们将介绍AXI协议的传输属性。 二、传…

【C++】day3学习成果:类

1.自行封装一个栈的类,包含私有成员属性:栈的数组、记录栈顶的变量 成员函数完成:构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 头文件stack.h: #ifndef STACK_H #define STACK_H#include …

Linux常见指令

目录 前言 一、Linux下的基本指令 01. ls 指令 02. pwd 指令 03. cd 指令 04. touch 指令 05. mkdir 指令(重要) 06. rmdir 指令 && rm 指令(重要) 07. man 指令(重要) extra nano 08. cp 指…

并发聊天服务器编写

并发聊天服务器 package mainimport ("fmt""net""strings""time" )// 结构体 type Client struct {C chan string //用户发送数据的管道Name string //用户名Addr string //网络地址 }// 保存在线用户 cliAddr -->cli…

UNIX网络编程卷一 学习笔记 第三十一章 流

在大多数源自SVR 4的内核中,X/Open传输接口(X/Open Transport Interface,XTI,是独立于套接字API的另一个网络编程API)和网络协议通常就像终端IO系统那样也使用流系统(STREAMS system)实现。 我…