qemu搭建虚拟的aarch64环境开发ebpf

一、背景

        需求在嵌入式环境下进行交叉编译,学习ebpf相关技术,所以想搭建一个不依赖硬件环境的学习环境。

本文使用的环境版本:

宿主机: Ubuntu24.02

libbpf-bootstrap源码:

https://github.com/libbpf/libbpf-bootstrap

Linux内核源码:Linux 5.4.123  

下载地址:

Index of /kernel/linux/kernel/v5.x/icon-default.png?t=O83Ahttps://mirror.bjtu.edu.cn/kernel/linux/kernel/v5.x/

交叉编译链:gcc-linaro-7.5.0-2019.12-x86_64_aarch64

Linaro Releases

Buildroot版本:buildroot-2024.02.9

下载地址:

Buildroot - Making Embedded Linux Easy

Qemu安装:

qemu-system-aarch64启动Linux内核 - PolarisZg - 博客园

二、调试环境搭建

2.1 内核支持ebpf配置

ws@ws-pc:~/qemu/aarch64/linux-5.4.123$ make ARCH=arm64 menuconfig

除了上述配置,还需要开启kprobe、uprobe、tracing、debugfs、bfp相关配置。最终好用的config如上传的附件。

如果内核配置模块未启用,会导致类似如下报错。

上述报错在源码中debug定位,最后会发现失败在相关 syscall中,补全就好。

2.2 buildroot编译rootfs文件系统

        制作rootfs根文件系统的方式目前流行的有三种,一种是直接使用busybox直接制作,这种系统占用内存小,适合嵌入式系统上运行,但是缺少很多工具,不便于学习;第二种是使用buildroot直接源码编译制作,简单可定制化;第三种是基于ubuntu等开源系统的最小包,在此基础上追加制作。本文选择使用buildroot的方式,编译出来的roofs提供给qemu使用,由于是虚拟板子没有串口,所以bulidroot一定要选择支持ssh 或者 telent的方式登陆,这样后面才可以有多个终端登陆。

制作教程资料很多,本文在制作时,没有制作内核,交叉编译链使用的系统自带的:

基于Linux的Buildroot 制作根文件系统(rootfs)_buildroot制作根文件系统-CSDN博客

基本配置:

设置root权限的登陆密码:

取消内核编译:

open SSH相关需要打开,打开server,这样可以ssh登陆:

文件系统选择的ext4:

还需要执行,在busybox添加一下telnet:

make busybox-menuconfig

2.3 qemu安装启动内核

命令行直接安装qemu: 教程也很多,就直接安装就好了

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager -y

注意网络net使用 tap的方式,可以让qemu出现网卡:

宿主机上需要进行如下网络配置,开发板可以直接访问公网,但是DHCP没有自动获取到IP,所以板子启动之后还需要手动设置以下IP:

qemu aarch64虚拟机创建好后,使用NAT连接网络 - wswang - 博客园

Documentation/Networking/NAT - QEMU

#!/bin/sh
#-initrd /home/ws/qemu/aarch64/rootfs.cpio.gz \
#        -kernel /home/ws/qemu/aarch64/rootfs/kernel_5.4_rootfs/Image \

qemu-system-aarch64 \
        -machine virt,virtualization=true,gic-version=3 \
        -nographic \
        -m size=4096M \
        -cpu cortex-a76 \
        -net tap -net nic \
        -smp 4 \
        -kernel /home/ws/qemu/aarch64/linux-5.4.123/arch/arm64/boot/Image \
        -drive file=/home/ws/qemu/aarch64/rootfs/kernel_5.4_rootfs/rootfs.ext4,if=none,format=raw,id=hd0 \
        -device virtio-blk-device,drive=hd0 \
        -append "rootwait root=/dev/vda rw console=ttyAMA0 rdinit=/linuxrc"
#! /bin/sh
ifconfig eth0 192.168.53.10 netmask 255.255.255.0 up
mount -t nfs -o nolock,vers=3 192.168.53.1:/home/ws/qemu /mnt

有了网络之后,就可以设置虚拟开发板和宿主机之间的nfs,教程如下:

Qemu - 百问网嵌入式Linux wiki

2.4 gdbserver远程debug

      由于环境搭建过程中遇到很多奇奇怪怪的错误,但是提示报错的原因又很少不准确,所以需求搭建一个vscode+gdb的远程调试工具,来debug libbpf-bootstrap工程。

一开始是使用交叉编译环境,使用源码编译的方式来搭建,但是发现高版本的又需要交叉编译库,低版本的编译出来gdbserver在开发版上执行报错,所以还了一种简单的方式来搭建。

宿主机安装 gdb-multiarch:

sudo apt-get update
sudo apt-get install gdb-multiarch

which gdb-multiarch

目标机直接下载其他人编译好的版本:(下载可能需要梯子)

https://github.com/skyedai910/gdbserver-all-in-one/releases

设置vscode相关设置:

指定要debug的进程minimal_legacy,在指定使用的gdb工具,使用witch可以看到安装路径。在指定远程调试的gdb地址和端口号。

将gdbserver拷贝到目标开发板的nfs路径下,远程执行。

打开内核的编译优化,两处地方加上-O0,否则单步调试的时候会乱跳:

2.5 libbpf-bootstrap编译

bilibili有位up主讲的非常好,这里引用一下:

libbpf-bootstrap交叉编译_libbpf-bootstrap arm-CSDN博客

这里同时分享以下我的编译脚本:

gcc_7.5.sh

#! /bin/sh
export PATH=/home/ws/chain_tools/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

2.5.1  zlib-1.3.1 zlib编译

make_zlib.sh

cd zlib-1.3.1
source ~/env/gcc_7.5.sh
#export PATH=$PATH:/usr/bin/
export CC=aarch64-linux-gnu-gcc
./configure --prefix=$PWD/_install
make -j16
make install

2.5.2 elfutils-0.192 编译

make_elfutils.sh

cd elfutils-0.192
# 参考当前目录下的 INSTALL 文档 和 网上资料
source ~/env/gcc_7.5.sh
export CFLAGS="-fPIC -I /home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/include"
export LDFLAGS="-L /home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/lib -Wl,-rpath-link,/home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/lib"
./configure --prefix=$PWD/_install --build=x86_64-linux-gnu \
        --host=aarch64-linux-gnu \
    CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ \
    --disable-nls --disable-rpath --disable-libdebuginfod --disable-debuginfod \
    --with-zlib=/home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/lib
make -j16
make install

2.5.3 libbpf的example编译

在这个example的编译Makefile和cMake最好需要了解以下原理,这里推进一个up主的视频:

03-09-libbpf样例程序Makefile脚本解读_哔哩哔哩_bilibili

make_libbpf.sh

#!/bin/sh
cd ./libbpf-bootstrap/examples/c

source ~/env/gcc_7.5.sh
export ARCH=arm64

export CROSS_COMPILE=aarch64-linux-gnu-
export EXTRA_CFLAGS="-fPIC -I /home/ws/qemu/ebpf_arm64/elfutils-0.192/_install/include -I /home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/include"
export EXTRA_LDFLAGS="-L /home/ws/qemu/ebpf_arm64/elfutils-0.192/_install/lib -Wl,-rpath-link,/home/ws/qemu/ebpf_arm64/elfutils-0.192/_install/lib -L /home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/lib -Wl,-rpath-link,/home/ws/qemu/ebpf_arm64/zlib-1.3.1/_install/lib"

#make -j16 V=1
make minimal_legacy  V=1

make_libbpf_clean.sh

#!/bin/sh
cd /home/ws/qemu/ebpf_arm64/libbpf-bootstrap/examples/c
make clean

cd /home/ws/qemu/ebpf_arm64/libbpf-bootstrap/libbpf/src
make clean

cd /home/ws/qemu/ebpf_arm64/libbpf-bootstrap/bpftool/src
make clean

三、遇到的问题

3.1 高版本内核编译时生成BTF失败

Linux 5.19在编译的时候,生成BTF文件失败,但是Linux 5.4.123内核的时候能够成功。

BTF: .tmp_vmlinux.btf: pahole (pahole) is not available Failed to generate BTF for vmlinux Try to disable CONFIG_DEBUG_INFO_BTF make: *** [Makefile:1100:vmlinux] 错误 1

原因:Ubuntu 24.04 apt-get install默认安装的pohole 版本过高,需要降低到v1.22版本

源码编译安装:下载对应版本的源码编译安装,注意tag版本

https://github.com/acmel/dwarves/tree/v1.22

git clone --recurse-submodules https://github.com/acmel/dwarves.git

git checkout tags/v1.22

git switch -c v1.22

cd dwarves
mkdir build
cd build
cmake -D__LIB=lib -DBUILD_SHARED_LIBS=OFF ..
sudo make install

安装完成之后需要更新一下动态库,如果安装错了,需要卸载:

#!/bin/bash

# 定义要删除的文件和目录列表
files=(
    "/usr/local/bin/codiff"
    "/usr/local/bin/ctracer"
    "/usr/local/bin/dtagnames"
    "/usr/local/bin/pahole"
    "/usr/local/bin/pdwtags"
    "/usr/local/bin/pfunct"
    "/usr/local/bin/pglobal"
    "/usr/local/bin/prefcnt"
    "/usr/local/bin/scncopy"
    "/usr/local/bin/syscse"
    "/usr/local/lib/libdwarves.so.1.0.0"
    "/usr/local/lib/libdwarves.so.1"
    "/usr/local/lib/libdwarves.so"
    "/usr/local/lib/libdwarves_emit.so.1.0.0"
    "/usr/local/lib/libdwarves_emit.so.1"
    "/usr/local/lib/libdwarves_emit.so"
    "/usr/local/lib/libdwarves_reorganize.so.1.0.0"
    "/usr/local/lib/libdwarves_reorganize.so.1"
    "/usr/local/lib/libdwarves_reorganize.so"
    "/usr/local/include/dwarves/dwarves.h"
    "/usr/local/include/dwarves/dwarves_emit.h"
    "/usr/local/include/dwarves/dwarves_reorganize.h"
    "/usr/local/include/dwarves/dutil.h"
    "/usr/local/include/dwarves/gobuffer.h"
    "/usr/local/include/dwarves/list.h"
    "/usr/local/include/dwarves/rbtree.h"
    "/usr/local/include/dwarves/btf_encoder.h"
    "/usr/local/include/dwarves/config.h"
    "/usr/local/include/dwarves/ctf.h"
    "/usr/local/include/dwarves/elfcreator.h"
    "/usr/local/include/dwarves/elf_symtab.h"
    "/usr/local/include/dwarves/hash.h"
    "/usr/local/include/dwarves/libctf.h"
    "/usr/local/share/man/man1/pahole.1"
    "/usr/local/bin/ostra-cg"
    "/usr/local/share/dwarves/runtime/python/ostra.py"
    "/usr/local/bin/btfdiff"
    "/usr/local/bin/fullcircle"
    "/usr/local/share/dwarves/runtime/Makefile"
    "/usr/local/share/dwarves/runtime/ctracer_relay.c"
    "/usr/local/share/dwarves/runtime/ctracer_relay.h"
    "/usr/local/share/dwarves/runtime/linux.blacklist.cu"
)

# 循环删除文件和目录
for file in "${files[@]}"; do
    if [ -f "$file" ]; then
        echo "Deleting file: $file"
        rm -f "$file"
    elif [ -d "$file" ]; then
        echo "Deleting directory: $file"
        rm -rf "$file"
    fi
done

# 清理动态库缓存
echo "Updating dynamic library cache..."
sudo /sbin/ldconfig

echo "Uninstallation complete."

3.2 执行时报错 object 'minimal_legacy_': failed (-22) to create BPF token from '/sys/fs/bpf', skipping optional step

一开始不确定是否是该原因导致无法加载,后面是将libbpf和bpftool仓库都降低了版本之后编译解决。

Tags · libbpf/bpftool · GitHub

Tags · libbpf/libbpf · GitHub

切换到指定版本的方式:

git checkout tags/v7.3.0

git switch -c v7.3.0

# bpftool下面有子仓库,使用下面命令能够自动更新子仓库
git submodule update --init

3.3 编译libbpf example程序的时候,报错编译链存在问题

需要将两处cc改为gcc,否则使用的编译链是cc结尾,本人安装的交叉编译链下没有这个。

3.4 报错/sys/fs/bpf failed (-22) to create BPF token from '/sys/fs/bpf', skipping optional step...

内核配置里面有相关的模块没有使能

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习从入门到实战——卷积神经网络原理解析及其应用

卷积神经网络CNN 卷积神经网络前言卷积神经网络卷积的填充方式卷积原理展示卷积计算量公式卷积核输出的大小计算感受野池化自适应均值化空洞卷积经典卷积神经网络参考 卷积神经网络 前言 为什么要使用卷积神经网络呢? 首先传统的MLP的有什么问题呢? - …

2015年西部数学奥林匹克几何试题

2015/G1 圆 ω 1 \omega_1 ω1​ 与圆 ω 2 \omega_2 ω2​ 内切于点 T T T. M M M, N N N 是圆 ω 1 \omega_1 ω1​ 上不同于 T T T 的不同两点. 圆 ω 2 \omega_2 ω2​ 的两条弦 A B AB AB, C D CD CD 分别过 M M M, N N N. 证明: 若线段 A C AC AC, B D BD …

《Spring Framework实战》14:4.1.4.5.自动装配合作者

欢迎观看《Spring Framework实战》视频教程 自动装配合作者 Spring容器可以自动连接协作bean之间的关系。您可以通过检查ApplicationContext的内容,让Spring自动为您的bean解析协作者(其他bean)。自动装配具有以下优点: 自动装配…

JVM之垃圾回收器概述(续)的详细解析

ParNew(并行) Par 是 Parallel 并行的缩写,New 是只能处理的是新生代 并行垃圾收集器在串行垃圾收集器的基础之上做了改进,采用复制算法,将单线程改为了多线程进行垃圾回收,可以缩短垃圾回收的时间 对于其他的行为(…

有一台服务器可以做哪些很酷的事情

有一台服务器可以做哪些很酷的事情 今天我也来简单分享一下,这几年来,我用云服务器做了哪些有趣的事情。 服务器推荐 1. 个人博客 拥有个人服务器,你可以完全掌控自己的网站或博客。 与使用第三方托管平台相比,你能自由选择网站…

灌区闸门自动化控制系统-精准渠道量测水-灌区现代化建设

项目背景 本项目聚焦于黑龙江某一灌区的现代化改造工程,该灌区覆盖广阔,灌溉面积高达7.5万亩,地域上跨越6个乡镇及涵盖17个村庄。项目核心在于通过全面的信息化建设,强力推动节水灌溉措施的实施,旨在显著提升农业用水的…

3.flask蓝图使用

构建一个目录结构 user_oper.py from flask import Blueprint, request, session, redirect, render_template import functools # 创建蓝图 user Blueprint(xkj, __name__)DATA_DICT {1: {"name": "张三", "age": 22, "gender": …

vue3学习日记1 - Pinia

最近发现职场前端用的框架大多为vue,所以最近也跟着黑马程序员vue3的课程进行学习,以下是我的学习记录 视频网址: Day2-02.Pinia-counter基础使用_哔哩哔哩_bilibili 学习日记: vue3学习日记1 - 环境搭建-CSDN博客 vue3学习日…

IP 地址与蜜罐技术

基于IP的地址的蜜罐技术是一种主动防御策略,它能够通过在网络上布置的一些看似正常没问题的IP地址来吸引恶意者的注意,将恶意者引导到预先布置好的伪装的目标之中。 如何实现蜜罐技术 当恶意攻击者在网络中四处扫描,寻找可入侵的目标时&…

Leetocde516. 最长回文子序列 动态规划

原题链接&#xff1a;Leetocde516. 最长回文子序列 class Solution { public:int longestPalindromeSubseq(string s) {int n s.size();vector<vector<int>> dp(n, vector<int>(n, 1));for (int i 0; i < n; i) {dp[i][i] 1;if (i 1 < n &&…

Linux物理地址到虚拟地址的映射

相关理论&#xff1a; Linux中用户空间是无法直操作寄存器的&#xff0c;需要先将寄存器对应的物理地址通过转换成虚拟地址然后在进行操作。 高性能处理器一般会提供一个内存管理单元&#xff08;MMU&#xff09;,该单元辅助操作系统进行内存管理&#xff0c;提供虚拟地址和物理…

openCvSharp 计算机视觉图片找茬

一、安装包 <PackageReference Include"OpenCvSharp4" Version"4.10.0.20241108" /> <PackageReference Include"OpenCvSharp4.runtime.win" Version"4.10.0.20241108" /> 二、准备两张图片 三、编写代码 using OpenCv…

数字孪生助力智慧机场全方位管理

智慧机场利用图扑可视化技术&#xff0c;实现航班动态、乘客流量和行李追踪的实时监控与分析&#xff0c;优化资源配置&#xff0c;提高运营效率&#xff0c;为旅客提供更加便捷的出行体验。

景联文科技提供高质量多模态数据处理服务,驱动AI新时代

在当今快速发展的AI时代&#xff0c;多模态数据标注成为推动人工智能技术进步的关键环节。景联文科技作为行业领先的AI数据服务提供商&#xff0c;专注于为客户提供高质量、高精度的多模态数据标注服务&#xff0c;涵盖图像、语音、文本、视频及3D点云等多种类型的数据。通过专…

【Docker】入门教程

目录 一、Docker的安装 二、Docker的命令 Docker命令实验 1.下载镜像 2.启动容器 3.修改页面 4.保存镜像 5.分享社区 三、Docker存储 1.目录挂载 2.卷映射 四、Docker网络 1.容器间相互访问 2.Redis主从同步集群 3.启动MySQL 五、Docker Compose 1.命令式安装 …

vscode使用Marscode编程助手

下载 vscode 在插件里下载Marscode编程助手 插件完成 在这里点击安装&#xff0c;点击后这里出现AI编程插件。

使用网页版Jupyter Notebook和VScode打开.ipynb文件

目录 正文 1、网页版Jupyter Notebook查看 2、VScode查看 因为总是忘记查看文件的网址&#xff0c;收藏了但分类众多每次都找不到……当个记录吧&#xff08;/捂脸哭&#xff09;&#xff01; 正文 此处以gitub中的某个仓库为例&#xff1a; https://github.com/INM-6/mu…

腾讯云AI代码助手编程挑战赛-知识百科AI

作品简介 知识百科AI这一编程主要用于对于小朋友的探索力的开发&#xff0c;让小朋友在一开始就对学习具有探索精神。在信息化时代下&#xff0c;会主动去学习自己认知以外的知识&#xff0c;同时丰富了眼界&#xff0c;开拓了新的知识。同时催生了在大数据时代下的信息共享化…

Flutter项目适配鸿蒙

Flutter项目适配鸿蒙 前言Flutter项目适配鸿蒙新工程直接支持ohos构建新项目编译运行 适配已有的Flutter项目 前言 目前市面上使用Flutter技术站的app不在少数&#xff0c;对于Flutter的项目&#xff0c;可能更多的是想直接兼容Harmonyos&#xff0c;而不是直接在重新开发一个…

我的128天创作之路:回顾与展望

大家好呀&#xff01;今天来和你们分享一下我的创作历程&#x1f601;。 一、机缘 最开始创作呢&#xff0c;是因为在学习 C 的 STL 时&#xff0c;像 string、list、vector 这些模板可把我折腾得够呛&#xff0c;但也让我学到了超多东西&#xff01;我就想&#xff0c;要是把我…