From 03861a3e53daec15d1adb65cb6f9b343d226377e Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 8 Apr 2025 09:09:54 -0700 Subject: [PATCH 1/3] Add scripts to generate fresh vmlinux.h Add script/gen-vmlinux-headers.sh (adapted from retsnoop [1]), that can build a Linux Kernel for various architectures and generate corresponding vmlinux.h header. Add kconfigs directory with common and per-arch configurations that can be used to produce vmlinux.h In gen-vmlinux-header.sh if an explicit config is not specified, append kconfigs/config.common and kconfigs/config.${ARCH} to build the Linux Kernel. [1] https://github.com/anakryiko/retsnoop/blob/master/scripts/gen-vmlinux-headers.sh Signed-off-by: Ihor Solodrai --- kconfigs/config.aarch64 | 1 + kconfigs/config.common | 18 +++++++ kconfigs/config.loongarch64 | 1 + kconfigs/config.ppc64le | 1 + kconfigs/config.riscv64 | 1 + kconfigs/config.s390x | 1 + kconfigs/config.x86_64 | 1 + scripts/gen-vmlinux-header.sh | 92 +++++++++++++++++++++++++++++++++++ scripts/helpers.sh | 28 +++++++++++ 9 files changed, 144 insertions(+) create mode 100644 kconfigs/config.aarch64 create mode 100644 kconfigs/config.common create mode 100644 kconfigs/config.loongarch64 create mode 100644 kconfigs/config.ppc64le create mode 100644 kconfigs/config.riscv64 create mode 100644 kconfigs/config.s390x create mode 100644 kconfigs/config.x86_64 create mode 100755 scripts/gen-vmlinux-header.sh create mode 100644 scripts/helpers.sh diff --git a/kconfigs/config.aarch64 b/kconfigs/config.aarch64 new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.aarch64 @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/kconfigs/config.common b/kconfigs/config.common new file mode 100644 index 0000000..1fcc21e --- /dev/null +++ b/kconfigs/config.common @@ -0,0 +1,18 @@ +CONFIG_BPF=y +CONFIG_BPF_EVENTS=y +CONFIG_BPF_JIT=y +CONFIG_BPF_SYSCALL=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_BTF=y +CONFIG_DEBUG_INFO_DWARF4=y +CONFIG_FPROBE=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_KPROBES=y +CONFIG_KPROBE_EVENTS=y +CONFIG_MMU=y +CONFIG_MODULES=y +CONFIG_PERF_EVENTS=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACING=y +CONFIG_UPROBE_EVENTS=y diff --git a/kconfigs/config.loongarch64 b/kconfigs/config.loongarch64 new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.loongarch64 @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/kconfigs/config.ppc64le b/kconfigs/config.ppc64le new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.ppc64le @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/kconfigs/config.riscv64 b/kconfigs/config.riscv64 new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.riscv64 @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/kconfigs/config.s390x b/kconfigs/config.s390x new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.s390x @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/kconfigs/config.x86_64 b/kconfigs/config.x86_64 new file mode 100644 index 0000000..06a94e4 --- /dev/null +++ b/kconfigs/config.x86_64 @@ -0,0 +1 @@ +CONFIG_64BIT=y diff --git a/scripts/gen-vmlinux-header.sh b/scripts/gen-vmlinux-header.sh new file mode 100755 index 0000000..90f1c8c --- /dev/null +++ b/scripts/gen-vmlinux-header.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +usage () { + echo "USAGE: ./gen-vmlinux-headers.sh [ ]" + exit 1 +} + +set -eu + +source $(dirname "$0")/helpers.sh + +WORKSPACE=$(pwd) +BUILD_DIR="${BUILD_DIR:-$WORKSPACE/build}" +GCC_VERSION=${GCC_VERSION:-"13"} +OUTPUT_DIR="${OUTPUT_DIR:-$WORKSPACE/vmlinux.h}" + +TARGET_ARCH=$1 +LINUX_REPO=${2:-$WORKSPACE/linux} +KCONFIG=${3:-} + +if [ -z "${TARGET_ARCH}" ]; then + echo "Error: Target architecture is not set" + usage +fi + +if [ ! -d "${LINUX_REPO}" ]; then + echo "Error: Linux repo path is not found, LINUX_REPO=$LINUX_REPO" + usage +fi + +if [ ! -f "${KCONFIG}" ]; then + KCONFIG=$(mktemp /tmp/kconfig.XXXX) + cp $WORKSPACE/kconfigs/config.common $KCONFIG + arch_conf="$WORKSPACE/kconfigs/config.${TARGET_ARCH}" + if [ -f "$arch_conf" ]; then + cat "$arch_conf" >> $KCONFIG + fi + echo "==== Using KCONFIG=$KCONFIG for kernel build" + cat $KCONFIG + echo "==== end of KCONFIG=$KCONFIG" +fi + +mkdir -p "$BUILD_DIR" +LINUX_REPO=$(realpath "$LINUX_REPO") +KCONFIG=$(realpath "$KCONFIG") + +# Install the cross-compiler +if [ "${TARGET_ARCH}" != "x86_64" ]; then + compiler_id=$(arch_compiler_id "$TARGET_ARCH") + sudo apt install -y \ + "gcc-${GCC_VERSION}-${compiler_id}" \ + "binutils-${compiler_id}" + sudo update-alternatives --install \ + /usr/bin/${compiler_id}-gcc \ + ${compiler_id}-gcc \ + /usr/bin/${compiler_id}-gcc-${GCC_VERSION} 100 + sudo update-alternatives --set \ + ${compiler_id}-gcc \ + /usr/bin/${compiler_id}-gcc-${GCC_VERSION} +fi + +build_arch(){ + local arch="$1" + local kbuild_output="$(realpath $BUILD_DIR/$arch)" + mkdir -p "$kbuild_output" + local arch_slug=$(arch_slug "$arch") + local compiler_id=$(arch_compiler_id "$arch") + + echo "Building $arch ($arch_slug) into $kbuild_output..." + ( + cd "$LINUX_REPO" + make O="$kbuild_output" \ + ARCH=$arch_slug CROSS_COMPILE="${compiler_id}-" \ + tinyconfig + "$LINUX_REPO/scripts/kconfig/merge_config.sh" -m \ + -O "$kbuild_output" \ + "$kbuild_output/.config" "${KCONFIG}" + make O="$kbuild_output" \ + ARCH=$arch_slug CROSS_COMPILE="${compiler_id}-" \ + olddefconfig + + make O="$kbuild_output" \ + ARCH=$arch_slug CROSS_COMPILE="${compiler_id}-" \ + -j$(nproc) all + + mkdir -p "$OUTPUT_DIR/$arch" + bpftool btf dump file "$kbuild_output/vmlinux" format c \ + > "$OUTPUT_DIR/$arch/vmlinux.h" + ) +} + +build_arch $TARGET_ARCH diff --git a/scripts/helpers.sh b/scripts/helpers.sh new file mode 100644 index 0000000..f41dfe8 --- /dev/null +++ b/scripts/helpers.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +arch_slug() { + printf "$arch" \ + | sed 's/x86_64/x86/' \ + | sed 's/i686/x86/' \ + | sed 's/aarch64/arm64/' \ + | sed 's/ppc64le/powerpc/' \ + | sed 's/riscv64/riscv/' \ + | sed 's/s390x/s390/' \ + | sed 's/loongarch64/loongarch/' +} + +arch_compiler_id() { + local arch="$1" + case "$arch" in + arm) + echo "arm-linux-gnueabi" + ;; + ppc64le) + echo "powerpc64le-linux-gnu" + ;; + *) + echo "${arch}-linux-gnu" + ;; + esac +} + From a31d57f6c00eb53bac8c7ee7bd6b5c4c632f5ede Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 8 Apr 2025 09:13:33 -0700 Subject: [PATCH 2/3] Add scripts that enable vmlinux.h generation from scratch * download-latest-linux-release.sh finds and fetches latest linux release from kernel.org * install-bpftool.sh builds and installs bpftool from source in the provided Linux tree * install-pahole.sh downloads and builds pahole from source * install-dependencies.sh assumes a clean ubuntu/debian environment and set ups packages necessary to build the kernel All these can be used to run vmlinux.h gen on Github Actions. Signed-off-by: Ihor Solodrai --- scripts/download-latest-linux-release.sh | 16 ++++++++++++++++ scripts/install-bpftool.sh | 16 ++++++++++++++++ scripts/install-dependencies.sh | 10 ++++++++++ scripts/install-pahole.sh | 22 ++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100755 scripts/download-latest-linux-release.sh create mode 100755 scripts/install-bpftool.sh create mode 100755 scripts/install-dependencies.sh create mode 100755 scripts/install-pahole.sh diff --git a/scripts/download-latest-linux-release.sh b/scripts/download-latest-linux-release.sh new file mode 100755 index 0000000..b0edd90 --- /dev/null +++ b/scripts/download-latest-linux-release.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -eux + +sudo apt install -y curl jq tar xz-utils + +url=$(curl -s https://www.kernel.org/releases.json \ + | jq -r '.releases[] | select(.moniker == "mainline") | .source') + +curl -LO "$url" +tar -xf $(basename "$url") + +dir=$(basename "$url" | sed 's/\.tar\.[gx]z$//') +mv $dir linux + +rm $(basename "$url") diff --git a/scripts/install-bpftool.sh b/scripts/install-bpftool.sh new file mode 100755 index 0000000..651617d --- /dev/null +++ b/scripts/install-bpftool.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -eux + +LINUX_REPO=${1:-"./linux"} + +if [ ! -d "${LINUX_REPO}" ]; then + echo "Error: Linux repo path is not found, LINUX_REPO=$LINUX_REPO" + exit 1 +fi + +sudo apt install -y llvm libcap-dev libbfd-dev zlib1g-dev + +cd "$LINUX_REPO/tools/bpf/bpftool" +make -j$(nproc) +sudo make install diff --git a/scripts/install-dependencies.sh b/scripts/install-dependencies.sh new file mode 100755 index 0000000..4fa2837 --- /dev/null +++ b/scripts/install-dependencies.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -eu + +# Assume Ubuntu/Debian x86_64 + +sudo apt update -y +DEBIAN_FRONTEND=noninteractive sudo -E apt install -y tzdata +sudo apt install -y bc bison build-essential elfutils flex libdw-dev libelf-dev make ncurses-dev python3-docutils zstd + diff --git a/scripts/install-pahole.sh b/scripts/install-pahole.sh new file mode 100755 index 0000000..ee62e4a --- /dev/null +++ b/scripts/install-pahole.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -eux + +PAHOLE_ORIGIN=${PAHOLE_ORIGIN:-https://git.kernel.org/pub/scm/devel/pahole/pahole.git} +PAHOLE_REVISION=${PAHOLE_REVISION:-next} + +sudo apt -y install cmake git libdw-dev libelf-dev + +WORKSPACE=$(mktemp -d -t pahole.XXXXXX) +pushd "$WORKSPACE" +git clone ${PAHOLE_ORIGIN} \ + --branch "${PAHOLE_REVISION}" \ + --depth=1 \ + --single-branch +cd pahole +mkdir -p build +cmake -B=build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr +make -C build -j$(nproc) +sudo make -C build install +popd +rm -rf "$WORKSPACE" From f844b115cdeefe5a0c4a99ee0301cc9fc36bfc18 Mon Sep 17 00:00:00 2001 From: Ihor Solodrai Date: Tue, 8 Apr 2025 09:14:30 -0700 Subject: [PATCH 3/3] Add vmlinux.h Github Actions workflow Define a workflow job that uses ./scripts to generate vmlinux.h from the latest Linux mainline release for various architectures. Kernel build and vmlinux.h generation execute in a separate step for each target architecture, while common dependencies are installed at the beginning. Signed-off-by: Ihor Solodrai --- .github/workflows/vmlinux.h.yml | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 .github/workflows/vmlinux.h.yml diff --git a/.github/workflows/vmlinux.h.yml b/.github/workflows/vmlinux.h.yml new file mode 100644 index 0000000..cdd8eec --- /dev/null +++ b/.github/workflows/vmlinux.h.yml @@ -0,0 +1,63 @@ +name: vmlinux.h + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +jobs: + gen-headers: + name: Generate vmlinux.h + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v4 + + - name: Download Linux source + shell: bash + run: ./scripts/download-latest-linux-release.sh + + - name: Install dependencies + shell: bash + run: | + ./scripts/install-dependencies.sh + ./scripts/install-pahole.sh + ./scripts/install-bpftool.sh + + - name: x86_64/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh x86_64 + + - name: aarch64/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh aarch64 + + - name: arm/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh arm + + - name: loongarch64/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh loongarch64 + + - name: ppc64le/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh ppc64le + + - name: riscv64/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh riscv64 + + - name: s390x/vmlinux.h + shell: bash + run: ./scripts/gen-vmlinux-header.sh s390x + + - name: Upload headers + uses: actions/upload-artifact@v4 + with: + name: vmlinux.h + if-no-files-found: error + path: ./vmlinux.h