# EBPF **Repository Path**: xu-ke-123/ebpf ## Basic Information - **Project Name**: EBPF - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-12-23 - **Last Updated**: 2026-03-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SimpleLogo eBPF 程序 一个简单的 Android eBPF 程序,用于监控内存分配事件(kmalloc)并输出自定义 ASCII 艺术 logo。 ## 📁 目录结构 ``` ebpf_test/ ├── src/ # 源码目录(所有源代码) │ ├── SimpleLogo.c # eBPF 程序源码(监控kmalloc,输出前5次事件) │ ├── Android.bp # Soong 构建文件 │ ├── attach_tracepoint.cpp # Tracepoint 附加工具 │ ├── read_map.cpp # Map 读取工具 │ └── show_logo.cpp # Logo 和详细信息输出工具 ├── build.sh # 编译和推送脚本 ├── test.sh # 测试脚本 └── README.md # 本文档 ``` ## 🎯 设计理念 ### 保持 AOSP 源码纯洁性 - ✅ **源码集中管理**:所有源代码都在 `ebpf_test/src/` 目录中 - ✅ **临时复制编译**:编译时将源码复制到 `system/bpf/progs/simple_logo/` - ✅ **自动清理**:编译完成后自动删除临时文件,保持 AOSP 源码干净 - ✅ **不影响 AOSP**:不会在 AOSP 源码树中留下任何痕迹 ### 架构设计 - **eBPF 程序(内核态)**:监控 `kmem/kmalloc` tracepoint(内存分配),捕获前5次事件并提取详细信息 - **用户态程序**:读取事件信息,输出完整的 ASCII 艺术 logo 和内存分配详细信息 - **优势**:内存分配比CPU调度更频繁、更稳定,不依赖 `trace_pipe`,不受 BPF 栈限制,输出稳定可靠 ## 🚀 使用方法 ### 1. 编译和推送 ```bash cd /home/haodong/data/aosp15/cursor_output/ebpf_test ./build.sh ``` 脚本会自动: 1. 临时重命名 `src/Android.bp`(避免Soong扫描冲突) 2. 复制源码到 AOSP 目录 3. 初始化构建环境 4. 编译 eBPF 程序和工具 5. 推送到设备 6. **自动清理临时文件**(保持 AOSP 源码干净) 7. 恢复 `src/Android.bp` ### 2. 重启设备 ```bash adb reboot adb wait-for-device # 建议等待10-20秒让系统完全启动 sleep 15 ``` ### 3. 运行测试 ```bash ./test.sh ``` 测试脚本会: 1. 检查程序是否已加载 2. 检查 map 是否存在 3. 读取 map 值 4. 附加 tracepoint 5. 触发内存分配 6. 验证程序执行 7. **输出 ASCII 艺术 logo 和内存分配详细信息** ### 4. 手动查看 Logo 和详细信息 ```bash # 直接输出logo和详细信息(如果程序已执行) adb shell 'su 0 /system/bin/show_logo' ``` ## 📋 工作原理 ### eBPF 程序执行流程 ``` 1. 内存分配事件发生(kmem/kmalloc) ↓ 2. eBPF程序被触发执行 ↓ 3. 检查是否已捕获5次事件 ↓ 4. 提取事件详细信息: - 调用地址(call_site) - 分配指针(ptr) - 请求大小(bytes_req) - 实际分配大小(bytes_alloc) - GFP标志(gfp_flags) - 进程ID(pid) ↓ 5. 存储到event_info_map(ARRAY map,key=0-4) ↓ 6. 更新event_count_map计数器 ↓ 7. 用户态程序读取map并输出logo和详细信息 ``` ### 为什么选择监控内存分配而不是CPU调度? 1. **更稳定**: - 内存分配事件比CPU调度更频繁、更可预测 - 系统几乎时刻都在进行内存分配 - 不需要大量触发操作就能看到效果 2. **更可靠**: - `kmalloc` tracepoint 是内核标准接口 - 事件频率高,map值更新快 - 测试更容易通过 ### 为什么不在 eBPF 里直接打印 logo? 1. **技术限制**: - `bpf_trace_printk` 输出到 `trace_pipe`,容易被消费 - BPF 栈限制,无法打印完整 ASCII logo - 每次事件都打印会太频繁 2. **架构职责**: - eBPF:监控事件、收集数据、发送信号 - 用户态:展示、格式化、控制输出时机 3. **工程实践**: - 这是标准的 eBPF 使用模式 - 与你朋友的"打印函数数据"方式完全兼容 ## 🔧 文件说明 ### 源码文件(`src/` 目录) - **SimpleLogo.c**:eBPF 程序,监控内存分配事件(kmalloc),捕获前5次事件并提取详细信息 - **Android.bp**:Soong 构建文件,定义模块 - **attach_tracepoint.cpp**:手动附加 tracepoint 的工具 - **read_map.cpp**:读取 map 值的工具 - **show_logo.cpp**:输出 ASCII 艺术 logo 和内存分配详细信息的工具 ### 脚本文件 - **build.sh**:编译和推送脚本,自动管理源码复制和清理 - **test.sh**:测试脚本,验证程序执行并输出 logo ## ✅ 当前状态 - ✅ **程序编译成功** - SimpleLogo.o 已编译 - ✅ **程序加载成功** - 程序已加载到内核 - ✅ **程序执行成功** - Map 值已更新(已验证) - ✅ **Logo 输出成功** - ASCII 艺术 logo 正常输出 - ✅ **详细信息输出成功** - 内存分配详细信息正常输出 - ✅ **AOSP 源码干净** - 编译后自动清理临时文件 ## 💡 功能特性 1. **保持 AOSP 源码纯洁性**: - 源码在 `ebpf_test/src/` 集中管理 - 编译时临时复制,编译后自动清理 - 不会在 AOSP 源码树中留下任何痕迹 2. **可靠的 Logo 输出**: - 不依赖 `trace_pipe` - 不受 BPF 栈限制 - 用户态可控输出 3. **详细的内存分配信息**: - 输出前5次内存分配事件 - 每次输出完整的 ASCII logo - 显示详细的分配信息: - 函数名:kmalloc() - 调用地址 - 分配指针 - 请求大小和实际分配大小 - 分配效率 - GFP标志 - 进程ID 4. **标准 eBPF 架构**: - 内核态监控事件 - 用户态展示结果 - 与你朋友的用法完全兼容 ## 📝 注意事项 1. **设备重启**:推送 `.o` 文件后需要重启设备,让 `bpfloader` 加载程序 2. **权限要求**:需要 root 权限(`adb root`) 3. **系统分区**:需要 remount `/system` 分区为可写(`adb remount`) 4. **源码管理**:所有源码修改都在 `src/` 目录中进行,不要直接修改 AOSP 目录 5. **事件限制**:程序只捕获前5次内存分配事件,之后不再处理 ## 🎓 学习要点 这个项目展示了: 1. **eBPF 的标准用法**:监控内核事件,用户态展示 2. **Android eBPF 开发**:使用 Soong 构建系统 3. **Tracepoint 参数访问**:如何访问 tracepoint 的上下文数据 4. **Map 数据传递**:使用 ARRAY map 在 eBPF 和用户态之间传递数据 5. **工程实践**:保持源码树干净,集中管理源码 6. **架构设计**:内核态和用户态的职责分离 ## 📚 参考资源 - [Android eBPF 官方文档](https://source.android.google.cn/docs/core/architecture/kernel/bpf?hl=zh-cn) - [eBPF on Android 博客](https://weishu.me/2022/06/12/eBPF-on-Android/)