mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-14 12:18:06 +08:00
update 2026-10-19 17:31:01
This commit is contained in:
1 parent
6604b3420d
commit
313fe55d56
38 files changed
+982
-1508
No files matched your search
+246
@@ -0,0 +1,246 @@
|
||||
name: Build packages
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
openwrt_majors:
|
||||
description: 'OpenWrt major versions (space-separated, e.g. 24 25)'
|
||||
required: false
|
||||
default: '24 25'
|
||||
type: string
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
actions: write
|
||||
|
||||
env:
|
||||
OPENWRT_MAJORS: '24 25'
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare version and matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
release_tag: ${{ steps.meta.outputs.release_tag }}
|
||||
release_name: ${{ steps.meta.outputs.release_name }}
|
||||
sdks: ${{ steps.matrix.outputs.sdks }}
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Generate version metadata
|
||||
id: meta
|
||||
shell: bash
|
||||
run: |
|
||||
pkg_release=$(grep '^PKG_RELEASE:=' Makefile | head -n 1 | cut -d= -f2 | tr -d '[:space:]')
|
||||
date_tag=$(date +'%Y%m%d')
|
||||
short_sha=$(git rev-parse --short HEAD)
|
||||
|
||||
release_tag="vmlinux-btf_r${pkg_release}_${date_tag}_${short_sha}"
|
||||
release_name="vmlinux-btf r${pkg_release} (${date_tag})"
|
||||
|
||||
echo "release_tag=${release_tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "release_name=${release_name}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "Release tag: ${release_tag}"
|
||||
echo "Release name: ${release_name}"
|
||||
|
||||
- name: Resolve latest SDK releases
|
||||
id: matrix
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
raw_majors="${{ inputs.openwrt_majors }}"
|
||||
majors=$(echo "${raw_majors:-$OPENWRT_MAJORS}" | tr ',' ' ')
|
||||
echo "Target major versions: ${majors}"
|
||||
|
||||
tags=""
|
||||
for i in {1..3}; do
|
||||
tags=$(git ls-remote --tags --refs https://github.com/openwrt/openwrt.git 2>/dev/null | awk -F'/' '{print $NF}' | sed 's/^v//' || true)
|
||||
[ -n "$tags" ] && break
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ -z "$tags" ]; then
|
||||
echo "::error::Failed to fetch tags from https://github.com/openwrt/openwrt.git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sdks=()
|
||||
for major in $majors; do
|
||||
latest=$(echo "$tags" | grep -E "^${major}\.[0-9.]+$" | sort -V | tail -n 1 || true)
|
||||
[ -z "$latest" ] && latest=$(echo "$tags" | grep -E "^${major}\." | sort -V | tail -n 1 || true)
|
||||
|
||||
if [ -n "$latest" ]; then
|
||||
echo "OpenWrt ${major} -> ${latest}"
|
||||
sdks+=("$latest")
|
||||
else
|
||||
echo "::error::No OpenWrt release tag found for major: ${major}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "sdks=$(jq -nc --args '$ARGS.positional' -- "${sdks[@]}")" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
name: Build ${{ matrix.arch }}-openwrt-${{ matrix.sdk }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: prepare
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- aarch64_generic
|
||||
- aarch64_cortex-a53
|
||||
- aarch64_cortex-a72
|
||||
- aarch64_cortex-a76
|
||||
- x86_64
|
||||
sdk: ${{ fromJson(needs.prepare.outputs.sdks) }}
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Build packages with OpenWrt SDK
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p artifacts feed/vmlinux-btf
|
||||
cp -a Makefile src feed/vmlinux-btf/
|
||||
[ ! -f README.md ] || cp -a README.md feed/vmlinux-btf/
|
||||
|
||||
image="docker.io/openwrt/sdk:${{ matrix.arch }}-${{ matrix.sdk }}"
|
||||
echo "Pulling SDK image ${image}..."
|
||||
docker pull "${image}"
|
||||
|
||||
docker run --rm \
|
||||
--user root \
|
||||
-v "${{ github.workspace }}/feed:/feed:ro" \
|
||||
-v "${{ github.workspace }}/artifacts:/artifacts" \
|
||||
"${image}" \
|
||||
bash -c '
|
||||
set -e
|
||||
# Install host dwarves/pahole (Bullseye has dwarves; Bookworm/Alpine have dwarves/pahole)
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
if [ -f /etc/debian_version ] && grep -q '^11' /etc/debian_version; then
|
||||
printf "deb [check-valid-until=no trusted=yes] http://archive.debian.org/debian/ bullseye main\ndeb [check-valid-until=no trusted=yes] http://archive.debian.org/debian-security/ bullseye-security main\n" > /etc/apt/sources.list
|
||||
rm -rf /etc/apt/sources.list.d/*
|
||||
fi
|
||||
apt-get update -o Acquire::Check-Valid-Until=false || apt-get update
|
||||
apt-get install -y --no-install-recommends dwarves || apt-get install -y dwarves || apt-get install -y pahole
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
apk add --no-cache dwarves
|
||||
fi
|
||||
|
||||
# Verify pahole binary exists and is executable
|
||||
pahole_bin="$(command -v pahole || which pahole || true)"
|
||||
if [ -z "$pahole_bin" ] || [ ! -x "$pahole_bin" ]; then
|
||||
echo "::error::pahole binary not found after package installation"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using pahole binary: $pahole_bin ($("$pahole_bin" --version))"
|
||||
|
||||
# Ensure pahole is accessible within OpenWrt staging_dir host tools
|
||||
mkdir -p /builder/staging_dir/host/bin
|
||||
ln -sf "$pahole_bin" /builder/staging_dir/host/bin/pahole
|
||||
|
||||
# Fix permissions and compile as buildbot user
|
||||
chown -R 1000:1000 /builder /artifacts
|
||||
su -s /bin/bash buildbot -c '\''
|
||||
set -e
|
||||
[ ! -f setup.sh ] || bash setup.sh
|
||||
echo "src-link packages_ci /feed" > feeds.conf
|
||||
./scripts/feeds update packages_ci
|
||||
./scripts/feeds install -p packages_ci vmlinux-btf
|
||||
echo "CONFIG_PACKAGE_vmlinux-btf=m" >> .config
|
||||
make defconfig
|
||||
make package/vmlinux-btf/compile V=s
|
||||
mkdir -p /artifacts/bin
|
||||
cp -a bin/* /artifacts/bin/ 2>/dev/null || true
|
||||
'\''
|
||||
'
|
||||
|
||||
sudo chown -R "$USER:$USER" "${{ github.workspace }}/artifacts"
|
||||
|
||||
- name: Show built files
|
||||
shell: bash
|
||||
run: |
|
||||
echo "=== Built package files ==="
|
||||
find artifacts -type f | grep -E '\.(ipk|apk)$' || true
|
||||
echo "==========================="
|
||||
|
||||
- name: Prepare renamed artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p dist
|
||||
found=0
|
||||
while IFS= read -r f; do
|
||||
[ -n "$f" ] || continue
|
||||
found=1
|
||||
base="$(basename "$f")"
|
||||
ext="${base##*.}"
|
||||
name="${base%.*}"
|
||||
|
||||
if [[ "$name" == *"${{ matrix.arch }}"* ]] || [[ "$name" == *"all"* ]]; then
|
||||
new_name="${name}-openwrt-${{ matrix.sdk }}.${ext}"
|
||||
else
|
||||
new_name="${name}-${{ matrix.arch }}-openwrt-${{ matrix.sdk }}.${ext}"
|
||||
fi
|
||||
|
||||
cp "$f" "dist/${new_name}"
|
||||
done < <(find artifacts -type f \( -name "*.ipk" -o -name "*.apk" \) 2>/dev/null)
|
||||
|
||||
if [ "$found" -eq 0 ]; then
|
||||
echo "::error::No package files found in artifacts"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ls -lah dist
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.arch }}-openwrt-${{ matrix.sdk }}
|
||||
path: dist/*
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
retention-days: 3
|
||||
|
||||
release:
|
||||
name: Publish release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- prepare
|
||||
- build
|
||||
steps:
|
||||
- name: Download all build artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: release-dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: Create or update GitHub release
|
||||
uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
tag_name: ${{ needs.prepare.outputs.release_tag }}
|
||||
name: ${{ needs.prepare.outputs.release_name }}
|
||||
files: release-dist/*
|
||||
generate_release_notes: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Delete Old Releases
|
||||
uses: ophub/delete-releases-workflows@main
|
||||
with:
|
||||
delete_releases: true
|
||||
releases_keep_latest: 3
|
||||
delete_tags: true
|
||||
delete_workflows: true
|
||||
workflows_keep_day: 3
|
||||
gh_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
continue-on-error: true
|
||||
+60
-72
@@ -4,17 +4,17 @@
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
#
|
||||
|
||||
VMLINUX_BTF_DIR := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=vmlinux-btf
|
||||
PKG_VERSION:=$(LINUX_VERSION)
|
||||
PKG_RELEASE:=6
|
||||
PKG_RELEASE:=9
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
define Package/vmlinux-btf
|
||||
SECTION:=kernel
|
||||
CATEGORY:=Kernel
|
||||
@@ -22,100 +22,88 @@ define Package/vmlinux-btf
|
||||
endef
|
||||
|
||||
define Package/vmlinux-btf/description
|
||||
Supplies kernel BTF information to ensure CO-RE eBPF compatibility.
|
||||
This package builds a shadow kernel tree using the OpenWrt kernel source,
|
||||
applies the same patches/files, and generates detached BTF information
|
||||
without modifying the main kernel build directory.
|
||||
Generates detached kernel BTF from target kernel headers and config,
|
||||
enabling CO-RE eBPF programs on OpenWrt without rebuilding the kernel.
|
||||
endef
|
||||
|
||||
define Package/vmlinux-btf/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
ln -sf /usr/lib/debug/boot/vmlinux /usr/lib/debug/boot/vmlinux-$$(uname -r)
|
||||
fi
|
||||
[ -n "$${IPKG_INSTROOT}" ] || ln -sf vmlinux /usr/lib/debug/boot/vmlinux-$$(uname -r)
|
||||
endef
|
||||
|
||||
define Package/vmlinux-btf/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
rm -f /usr/lib/debug/boot/vmlinux-$$(uname -r)
|
||||
fi
|
||||
[ -n "$${IPKG_INSTROOT}" ] || rm -f /usr/lib/debug/boot/vmlinux-$$(uname -r)
|
||||
endef
|
||||
|
||||
# Toolchain and helpers
|
||||
BTF_CC ?= $(if $(TARGET_CC_NOCACHE),$(TARGET_CC_NOCACHE),$(TARGET_CROSS)gcc)
|
||||
BTF_PAHOLE ?= $(firstword \
|
||||
$(wildcard $(STAGING_DIR_HOST)/bin/pahole /usr/bin/pahole /usr/local/bin/pahole) \
|
||||
$(shell command -v pahole 2>/dev/null) \
|
||||
pahole)
|
||||
PAHOLE_JOBS := $(if $(filter -j%,$(PKG_JOBS)),$(patsubst -j%,%,$(filter -j%,$(PKG_JOBS))),1)
|
||||
KERNEL_RELEASE := $(if $(wildcard $(LINUX_DIR)/include/config/kernel.release),$(shell cat $(LINUX_DIR)/include/config/kernel.release),$(LINUX_VERSION))
|
||||
|
||||
BTF_CFLAGS := \
|
||||
-nostdinc \
|
||||
-isystem $(shell $(BTF_CC) -print-file-name=include) \
|
||||
-D__KERNEL__ \
|
||||
-include $(LINUX_DIR)/include/linux/kconfig.h \
|
||||
$(if $(wildcard $(LINUX_DIR)/include/linux/compiler-version.h),-include $(LINUX_DIR)/include/linux/compiler-version.h) \
|
||||
$(if $(wildcard $(LINUX_DIR)/include/linux/compiler_types.h),-include $(LINUX_DIR)/include/linux/compiler_types.h) \
|
||||
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include \
|
||||
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/generated \
|
||||
-I$(LINUX_DIR)/include \
|
||||
-I$(LINUX_DIR)/include/generated \
|
||||
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/uapi \
|
||||
-I$(LINUX_DIR)/arch/$(LINUX_KARCH)/include/generated/uapi \
|
||||
-I$(LINUX_DIR)/include/uapi \
|
||||
-I$(LINUX_DIR)/include/generated/uapi \
|
||||
-I$(LINUX_DIR) \
|
||||
$(filter -m% -march=% -mcpu=% -mtune=% -EB -EL,$(TARGET_CFLAGS)) \
|
||||
-std=gnu11 -funsigned-char -fshort-wchar -fno-common -fno-PIE \
|
||||
-O2 -g -gdwarf-4 -fno-eliminate-unused-debug-types \
|
||||
-Wno-error -Wno-unused-function -Wno-unused-variable
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
|
||||
$(TAR) -C $(PKG_BUILD_DIR) -xf $(DL_DIR)/$(LINUX_SOURCE)
|
||||
mv $(PKG_BUILD_DIR)/linux-$(LINUX_VERSION) $(PKG_BUILD_DIR)/shadow-kernel
|
||||
|
||||
cp $(LINUX_DIR)/.config $(PKG_BUILD_DIR)/shadow-kernel/.config
|
||||
$(CP) $(VMLINUX_BTF_DIR)/src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(PKG_BUILD_DIR)/shadow-kernel/scripts/config \
|
||||
--file $(PKG_BUILD_DIR)/shadow-kernel/.config \
|
||||
--disable WERROR \
|
||||
--enable CGROUPS \
|
||||
--enable CGROUP_BPF \
|
||||
--enable SOCK_CGROUP_DATA \
|
||||
--enable KALLSYMS \
|
||||
--enable PERF_EVENTS \
|
||||
--enable TRACEPOINTS \
|
||||
--enable KPROBES \
|
||||
--enable UPROBES \
|
||||
--enable BPF \
|
||||
--enable BPF_SYSCALL \
|
||||
--enable BPF_JIT \
|
||||
--enable BPF_JIT_DEFAULT_ON \
|
||||
--enable INET \
|
||||
--enable NET_INGRESS \
|
||||
--enable NET_EGRESS \
|
||||
--enable BPF_STREAM_PARSER \
|
||||
--enable XDP_SOCKETS \
|
||||
--enable NET_SCHED \
|
||||
--enable NET_SCH_INGRESS \
|
||||
--enable NET_CLS \
|
||||
--enable NET_CLS_ACT \
|
||||
--enable KPROBE_EVENTS \
|
||||
--enable UPROBE_EVENTS \
|
||||
--enable BPF_EVENTS \
|
||||
--enable DEBUG_KERNEL \
|
||||
--enable DEBUG_INFO \
|
||||
--disable DEBUG_INFO_NONE \
|
||||
--enable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT \
|
||||
--disable DEBUG_INFO_REDUCED \
|
||||
--disable DEBUG_INFO_SPLIT \
|
||||
--enable DEBUG_INFO_BTF \
|
||||
--set-str EXTRA_FIRMWARE "" \
|
||||
--set-str INITRAMFS_SOURCE ""
|
||||
@if [ ! -f "$(LINUX_DIR)/include/generated/autoconf.h" ]; then \
|
||||
echo "vmlinux-btf: kernel headers not found in $(LINUX_DIR)"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@if [ -z "$(BTF_PAHOLE)" ] || ! $(BTF_PAHOLE) --version >/dev/null 2>&1; then \
|
||||
echo "vmlinux-btf: pahole not found or not working (install dwarves/pahole on host)"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/shadow-kernel \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
KBUILD_HOSTLDFLAGS="$(KBUILD_HOSTLDFLAGS) -lz" \
|
||||
olddefconfig
|
||||
# Compile BTF stub sources
|
||||
$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_core.c -o $(PKG_BUILD_DIR)/shadow_btf_core.o
|
||||
-$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_modules.c -o $(PKG_BUILD_DIR)/shadow_btf_modules.o 2>/dev/null
|
||||
-$(BTF_CC) $(BTF_CFLAGS) -c $(PKG_BUILD_DIR)/shadow_btf_private.c -o $(PKG_BUILD_DIR)/shadow_btf_private.o 2>/dev/null
|
||||
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/shadow-kernel \
|
||||
$(KERNEL_MAKE_FLAGS) \
|
||||
$(PKG_JOBS) \
|
||||
KBUILD_HOSTLDFLAGS="-L$(STAGING_DIR_HOST)/lib -lz" \
|
||||
vmlinux
|
||||
# Link compiled objects into a single relocatable object
|
||||
objs="$(PKG_BUILD_DIR)/shadow_btf_core.o"; \
|
||||
[ ! -f "$(PKG_BUILD_DIR)/shadow_btf_modules.o" ] || objs="$$objs $(PKG_BUILD_DIR)/shadow_btf_modules.o"; \
|
||||
[ ! -f "$(PKG_BUILD_DIR)/shadow_btf_private.o" ] || objs="$$objs $(PKG_BUILD_DIR)/shadow_btf_private.o"; \
|
||||
$(TARGET_CROSS)ld -r -o $(PKG_BUILD_DIR)/shadow_btf.o $$objs
|
||||
|
||||
pahole \
|
||||
--jobs=$(PAHOLE_JOBS) \
|
||||
# Extract detached BTF
|
||||
$(BTF_PAHOLE) --jobs=$(PAHOLE_JOBS) \
|
||||
--btf_encode_detached=$(PKG_BUILD_DIR)/vmlinux-btf \
|
||||
$(PKG_BUILD_DIR)/shadow-kernel/vmlinux
|
||||
endef
|
||||
|
||||
define Build/Clean
|
||||
rm -rf $(PKG_BUILD_DIR)
|
||||
$(PKG_BUILD_DIR)/shadow_btf.o
|
||||
test -s $(PKG_BUILD_DIR)/vmlinux-btf
|
||||
$(BTF_PAHOLE) -C sk_buff $(PKG_BUILD_DIR)/shadow_btf.o >/dev/null
|
||||
endef
|
||||
|
||||
define Package/vmlinux-btf/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/debug/boot
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/vmlinux-btf $(1)/usr/lib/debug/boot/vmlinux
|
||||
$(LN) vmlinux $(1)/usr/lib/debug/boot/vmlinux-$(LINUX_VERSION)
|
||||
$(LN) vmlinux $(1)/usr/lib/debug/boot/vmlinux-$(KERNEL_RELEASE)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,vmlinux-btf))
|
||||
$(eval $(call BuildPackage,vmlinux-btf))
|
||||
+17
-92
@@ -1,117 +1,42 @@
|
||||
# vmlinux-btf
|
||||
|
||||
An OpenWrt package that builds a BTF-enabled `vmlinux` in a shadow kernel tree and installs it as a standalone file, enabling CO-RE (Compile Once – Run Everywhere) eBPF programs to run on OpenWrt without tainting or modifying the main kernel build.
|
||||
OpenWrt package that generates a detached BTF (`vmlinux`) file from kernel headers and `.config`, enabling CO-RE (Compile Once – Run Everywhere) eBPF programs on OpenWrt without rebuilding or replacing the running kernel.
|
||||
|
||||
---
|
||||
## Overview
|
||||
|
||||
## How It Works
|
||||
Official OpenWrt release kernels typically omit `CONFIG_DEBUG_INFO_BTF=y`. Without kernel BTF, modern eBPF tools that rely on CO-RE (such as `libbpf`-based loaders) cannot resolve kernel type layouts.
|
||||
|
||||
1. Downloads the upstream Linux kernel source that matches the current OpenWrt build environment.
|
||||
2. Extracts it into an isolated `shadow-kernel` directory inside the build tree.
|
||||
3. Applies the same generic and platform-specific patches that the main kernel receives, in the same order.
|
||||
4. Copies the main kernel's `.config` as a baseline, then enables the full set of BTF and BPF-related options on top of it.
|
||||
5. Compiles `vmlinux` with full DWARF debug info.
|
||||
6. Uses `pahole` to extract a detached BTF blob from the resulting `vmlinux`.
|
||||
7. Installs the blob to `/usr/lib/debug/boot/vmlinux` on the target device.
|
||||
Rather than recompiling the entire kernel tree, this package compiles lightweight stub sources (`src/shadow_btf_*.c`) against the prepared target kernel headers (`$(LINUX_DIR)`) using the target configuration and toolchain. `pahole` then extracts the detached BTF blob from the linked object.
|
||||
|
||||
This approach keeps the main kernel tree completely untouched — BTF information is generated entirely in the shadow build.
|
||||
## Requirements
|
||||
|
||||
---
|
||||
|
||||
## Host Build Dependencies
|
||||
|
||||
The following tools must be present on the **host machine** running the OpenWrt build system before compiling this package.
|
||||
|
||||
### Required by the OpenWrt build system itself
|
||||
|
||||
These are standard OpenWrt build prerequisites. If your environment already builds OpenWrt successfully, these should already be present.
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `gcc` / `binutils` | Cross-compilation toolchain |
|
||||
| `make` | Build orchestration |
|
||||
| `xz-utils` | Decompression of kernel source tarball (`xzcat`) |
|
||||
| `tar` | Extraction of kernel source |
|
||||
| `bc` | Kernel version arithmetic during `prepare` |
|
||||
| `flex`, `bison` | Kernel parser generation |
|
||||
| `libssl-dev` | Kernel certificate handling |
|
||||
| `libelf-dev` | ELF binary manipulation, required by kernel build |
|
||||
| `python3` | Kernel build scripts |
|
||||
|
||||
Install on Debian/Ubuntu:
|
||||
```bash
|
||||
sudo apt install build-essential libssl-dev libelf-dev \
|
||||
bc flex bison python3 xz-utils tar
|
||||
```
|
||||
|
||||
Install on Fedora/RHEL:
|
||||
```bash
|
||||
sudo dnf install gcc binutils openssl-devel elfutils-libelf-devel \
|
||||
bc flex bison python3 xz tar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Required specifically by this package
|
||||
|
||||
#### `dwarves` (provides `pahole`)
|
||||
|
||||
`pahole` is used to extract the detached BTF blob from the compiled `vmlinux`. This is the only tool required by this package that is **not** a standard OpenWrt build dependency.
|
||||
|
||||
Install on Debian/Ubuntu:
|
||||
```bash
|
||||
sudo apt install dwarves
|
||||
```
|
||||
|
||||
Install on Fedora/RHEL:
|
||||
```bash
|
||||
sudo dnf install dwarves
|
||||
```
|
||||
|
||||
> **Note:** A host `pahole` version of **1.16 or newer** is required for `--btf_encode_detached` support. The version bundled with the OpenWrt `dwarves/host` feed satisfies this requirement. If you install `pahole` manually from your system package manager, verify the version with `pahole --version`.
|
||||
|
||||
---
|
||||
- OpenWrt buildroot or SDK environment.
|
||||
- Host `pahole` >= 1.22 (from the `dwarves` package).
|
||||
|
||||
## Building
|
||||
|
||||
Add this package to your OpenWrt build configuration:
|
||||
### In OpenWrt SDK
|
||||
|
||||
```bash
|
||||
# From the OpenWrt build root
|
||||
make menuconfig
|
||||
# Navigate to: Kernel → vmlinux-btf
|
||||
# Select with <M> or <*>
|
||||
|
||||
git clone https://github.com/QiuSimons/vmlinux-btf.git package/vmlinux-btf
|
||||
make package/vmlinux-btf/compile V=s
|
||||
```
|
||||
|
||||
Or build the IPK directly:
|
||||
### In OpenWrt Buildroot
|
||||
|
||||
Select `vmlinux-btf` under `Kernel` in `make menuconfig`, then build:
|
||||
|
||||
```bash
|
||||
make package/vmlinux-btf/{clean,compile} V=s
|
||||
make package/vmlinux-btf/compile V=s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installed Files
|
||||
|
||||
| Path | Description |
|
||||
|------|-------------|
|
||||
| `/usr/lib/debug/boot/vmlinux` | Detached BTF blob |
|
||||
| `/usr/lib/debug/boot/vmlinux-<kernel-version>` | Symlink created by `postinst` |
|
||||
- `/usr/lib/debug/boot/vmlinux`: Detached BTF file.
|
||||
- `/usr/lib/debug/boot/vmlinux-<release>`: Symlink targeting `vmlinux` (linked to `uname -r` on target installation).
|
||||
|
||||
The symlink is created at install time using the running kernel version (`uname -r`) and removed automatically on package removal.
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Build time is significant.** This package compiles a complete kernel from source. Expect 20–60 minutes depending on your hardware and target architecture.
|
||||
- **Kernel version must match.** The shadow kernel is built from the same source version as the OpenWrt target kernel (`$(LINUX_VERSION)`). Installing this package on a device running a different kernel version will likely result in BTF type mismatches and broken CO-RE lookups.
|
||||
- **Architecture-specific JIT support** (`HAVE_EBPF_JIT`) is set automatically by the kernel build system based on the target architecture and does not need to be configured manually.
|
||||
|
||||
---
|
||||
Standard loaders such as `libbpf` look for BTF at `/usr/lib/debug/boot/vmlinux-$(uname -r)` and `/usr/lib/debug/boot/vmlinux` by default.
|
||||
|
||||
## License
|
||||
|
||||
GPL-3.0-or-later — see [https://www.gnu.org/licenses/gpl-3.0.html](https://www.gnu.org/licenses/gpl-3.0.html)
|
||||
GPL-3.0-or-later
|
||||
@@ -0,0 +1,76 @@
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#ifndef KBUILD_MODNAME
|
||||
#define KBUILD_MODNAME "shadow_btf_core"
|
||||
#endif
|
||||
#ifndef KBUILD_BASENAME
|
||||
#define KBUILD_BASENAME "shadow_btf_core"
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/icmp.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/bpf_perf_event.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_sock.h>
|
||||
#include <net/inet_connection_sock.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/dst.h>
|
||||
#include <net/neighbour.h>
|
||||
#include <net/xdp.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
#if __has_include(<net/netdev_rx_queue.h>)
|
||||
#include <net/netdev_rx_queue.h>
|
||||
#endif
|
||||
|
||||
#if __has_include(<linux/bpf_iter.h>)
|
||||
#include <linux/bpf_iter.h>
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CGROUPS)
|
||||
#include <linux/cgroup.h>
|
||||
#endif
|
||||
|
||||
#define BTF_KEEP(name, type) \
|
||||
static type * __attribute__((used, section(".discard.btf_keep"))) \
|
||||
__btf_keep_##name
|
||||
|
||||
BTF_KEEP(pt_regs, struct pt_regs);
|
||||
BTF_KEEP(task_struct, struct task_struct);
|
||||
BTF_KEEP(mm_struct, struct mm_struct);
|
||||
BTF_KEEP(file, struct file);
|
||||
BTF_KEEP(dentry, struct dentry);
|
||||
BTF_KEEP(inode, struct inode);
|
||||
BTF_KEEP(cred, struct cred);
|
||||
BTF_KEEP(module, struct module);
|
||||
BTF_KEEP(sk_buff, struct sk_buff);
|
||||
BTF_KEEP(net_device, struct net_device);
|
||||
BTF_KEEP(netdev_queue, struct netdev_queue);
|
||||
BTF_KEEP(netdev_rx_queue, struct netdev_rx_queue);
|
||||
BTF_KEEP(sock, struct sock);
|
||||
BTF_KEEP(inet_sock, struct inet_sock);
|
||||
BTF_KEEP(inet_connection_sock, struct inet_connection_sock);
|
||||
BTF_KEEP(tcp_sock, struct tcp_sock);
|
||||
BTF_KEEP(udp_sock, struct udp_sock);
|
||||
BTF_KEEP(net, struct net);
|
||||
BTF_KEEP(dst_entry, struct dst_entry);
|
||||
BTF_KEEP(neighbour, struct neighbour);
|
||||
BTF_KEEP(xdp_buff, struct xdp_buff);
|
||||
BTF_KEEP(bpf_perf_event_data, struct bpf_perf_event_data);
|
||||
#if IS_ENABLED(CONFIG_CGROUPS)
|
||||
BTF_KEEP(cgroup, struct cgroup);
|
||||
#endif
|
||||
@@ -0,0 +1,79 @@
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#ifndef KBUILD_MODNAME
|
||||
#define KBUILD_MODNAME "shadow_btf_modules"
|
||||
#endif
|
||||
#ifndef KBUILD_BASENAME
|
||||
#define KBUILD_BASENAME "shadow_btf_modules"
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define BTF_KEEP(name, type) \
|
||||
static type * __attribute__((used, section(".discard.btf_keep"))) \
|
||||
__btf_keep_##name
|
||||
|
||||
#if IS_ENABLED(CONFIG_INET)
|
||||
#include <net/route.h>
|
||||
#include <net/ip_fib.h>
|
||||
BTF_KEEP(rtable, struct rtable);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
#include <net/ipv6.h>
|
||||
#include <net/if_inet6.h>
|
||||
BTF_KEEP(ipv6_pinfo, struct ipv6_pinfo);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NETFILTER)
|
||||
#include <linux/netfilter.h>
|
||||
BTF_KEEP(nf_hook_state, struct nf_hook_state);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_conntrack_tuple.h>
|
||||
BTF_KEEP(nf_conn, struct nf_conn);
|
||||
BTF_KEEP(nf_conntrack_tuple, struct nf_conntrack_tuple);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_NAT) && __has_include(<net/netfilter/nf_nat.h>)
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
BTF_KEEP(nf_conn_nat, struct nf_conn_nat);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_TABLES) && __has_include(<net/netfilter/nf_tables.h>)
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
BTF_KEEP(nft_pktinfo, struct nft_pktinfo);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_FLOW_TABLE) && __has_include(<net/netfilter/nf_flow_table.h>)
|
||||
#include <net/netfilter/nf_flow_table.h>
|
||||
BTF_KEEP(flow_offload, struct flow_offload);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NETFILTER_XTABLES)
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
BTF_KEEP(xt_table, struct xt_table);
|
||||
BTF_KEEP(xt_action_param, struct xt_action_param);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_SCHED)
|
||||
#include <net/sch_generic.h>
|
||||
#include <net/pkt_sched.h>
|
||||
BTF_KEEP(qdisc, struct Qdisc);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_CLS) && __has_include(<net/pkt_cls.h>)
|
||||
#include <net/pkt_cls.h>
|
||||
BTF_KEEP(tcf_result, struct tcf_result);
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_NET_CLS_ACT) && __has_include(<net/act_api.h>)
|
||||
#include <net/act_api.h>
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_XDP_SOCKETS) && __has_include(<net/xdp_sock.h>)
|
||||
#include <net/xdp_sock.h>
|
||||
BTF_KEEP(xdp_sock, struct xdp_sock);
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#ifndef KBUILD_MODNAME
|
||||
#define KBUILD_MODNAME "shadow_btf_private"
|
||||
#endif
|
||||
#ifndef KBUILD_BASENAME
|
||||
#define KBUILD_BASENAME "shadow_btf_private"
|
||||
#endif
|
||||
|
||||
#define BTF_KEEP(name, type) \
|
||||
static type * __attribute__((used, section(".discard.btf_keep"))) \
|
||||
__btf_keep_##name
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE) && __has_include("net/bridge/br_private.h")
|
||||
#include "net/bridge/br_private.h"
|
||||
BTF_KEEP(net_bridge, struct net_bridge);
|
||||
BTF_KEEP(net_bridge_port, struct net_bridge_port);
|
||||
#endif
|
||||
|
||||
#if __has_include("fs/mount.h")
|
||||
#include "fs/mount.h"
|
||||
BTF_KEEP(mount, struct mount);
|
||||
#endif
|
||||
Reference in new issue
Block a user