Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:

- name: build via top-level Makefile (default target)
# KDIR defaults to /lib/modules/$(uname -r)/build when there's no
# .kernel-cache/current, so this exercises the full prepare-build +
# kernel-cache/current, so this exercises the full prepare-build +
# KCFLAGS pipeline against a real (the runner's) kernel.
run: make modules

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
lab.local.env

# Per-target synced kernel headers, source, vmlinux.
.kernel-cache/
kernel-cache/

# Generated GDB init files (regenerated by scripts/04 on every F5).
.gdb/
Expand Down
33 changes: 17 additions & 16 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,30 @@
],
"includePath": [
"${workspaceFolder}/module/**",
"${workspaceFolder}/.kernel-cache/current/build/include",
"${workspaceFolder}/.kernel-cache/current/build/include/uapi",
"${workspaceFolder}/.kernel-cache/current/build/include/generated",
"${workspaceFolder}/.kernel-cache/current/build/include/generated/uapi",
"${workspaceFolder}/.kernel-cache/current/build/ubuntu/include",
"${workspaceFolder}/.kernel-cache/current/build/arch/x86/include",
"${workspaceFolder}/.kernel-cache/current/build/arch/x86/include/uapi",
"${workspaceFolder}/.kernel-cache/current/build/arch/x86/include/generated",
"${workspaceFolder}/.kernel-cache/current/build/arch/x86/include/generated/uapi"
"${workspaceFolder}/kernel-cache/current/build/include",
"${workspaceFolder}/kernel-cache/current/build/include/uapi",
"${workspaceFolder}/kernel-cache/current/build/include/generated",
"${workspaceFolder}/kernel-cache/current/build/include/generated/uapi",
"${workspaceFolder}/kernel-cache/current/build/ubuntu/include",
"${workspaceFolder}/kernel-cache/current/build/arch/x86/include",
"${workspaceFolder}/kernel-cache/current/build/arch/x86/include/uapi",
"${workspaceFolder}/kernel-cache/current/build/arch/x86/include/generated",
"${workspaceFolder}/kernel-cache/current/build/arch/x86/include/generated/uapi"
],
"browse": {
"path": [
"${workspaceFolder}/module",
"${workspaceFolder}/.kernel-cache/current/build/ubuntu/include",
"${workspaceFolder}/.kernel-cache/current/build/include",
"${workspaceFolder}/.kernel-cache/current/build/arch/x86/include"
"${workspaceFolder}/kernel-cache/current/source",
"${workspaceFolder}/kernel-cache/current/build/ubuntu/include",
"${workspaceFolder}/kernel-cache/current/build/include",
"${workspaceFolder}/kernel-cache/current/build/arch/x86/include"
],
"limitSymbolsToIncludedHeaders": true
"limitSymbolsToIncludedHeaders": false
},
"forcedInclude": [
"${workspaceFolder}/.kernel-cache/current/build/include/linux/compiler-version.h",
"${workspaceFolder}/.kernel-cache/current/build/include/linux/kconfig.h",
"${workspaceFolder}/.kernel-cache/current/build/include/linux/compiler_types.h"
"${workspaceFolder}/kernel-cache/current/build/include/linux/compiler-version.h",
"${workspaceFolder}/kernel-cache/current/build/include/linux/kconfig.h",
"${workspaceFolder}/kernel-cache/current/build/include/linux/compiler_types.h"
]
}
]
Expand Down
2 changes: 0 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"C_Cpp.default.configurationProvider": "",
"C_Cpp.default.configurationName": "Linux kernel module - current",
"C_Cpp.errorSquiggles": "enabled",
"files.associations": {
Expand All @@ -8,7 +7,6 @@
"Kbuild": "makefile"
},
"files.exclude": {
".kernel-cache": true,
".gdb": true,
"build": true
}
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Top-level wrapper for the user's module under module/.
#
# Builds out-of-tree against a target-specific kernel header tree under
# .kernel-cache/<target>/. Sources are staged into
# kernel-cache/<target>/. Sources are staged into
# build/intermediate/<target>/<kernel>/ before Kbuild runs from there,
# and `-ffile-prefix-map=$(INTERMEDIATE_DIR)=$(MODULE_DIR)` is injected
# via KCFLAGS so DWARF paths and `__FILE__` resolve back to module/ —
Expand All @@ -12,7 +12,7 @@
# with no knowledge of the staging.

HOST_KERNEL := $(shell uname -r)
CURRENT_CACHE := $(CURDIR)/.kernel-cache/current
CURRENT_CACHE := $(CURDIR)/kernel-cache/current
CURRENT_TARGET := $(shell if [ -e "$(CURRENT_CACHE)" ]; then basename "$$(readlink -f "$(CURRENT_CACHE)")"; else printf local; fi)
CURRENT_KERNEL := $(shell if [ -f "$(CURRENT_CACHE)/kernel.release" ]; then cat "$(CURRENT_CACHE)/kernel.release"; else printf '$(HOST_KERNEL)'; fi)

Expand Down Expand Up @@ -45,7 +45,7 @@ help:
@echo " use-example NAME=chuck_norise copy an example into module/"
@echo " clean-module reset module/ to just README.md"
@echo ""
@echo "Vars (auto-resolved when .kernel-cache/current points at a target):"
@echo "Vars (auto-resolved when kernel-cache/current points at a target):"
@echo " MODULE_DIR $(MODULE_DIR)"
@echo " KDIR $(KDIR)"
@echo " BUILD_ID $(BUILD_ID)"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ $EDITOR lab.local.env # TARGET_SSH_*, endp
./scripts/01-provision-target.sh server qemu --debug-symbols
# ...reboot the target VM so new GRUB args take effect...

# 2. host setup: sync everything to .kernel-cache/server/ (one-time)
# 2. host setup: sync everything to kernel-cache/server/ (one-time)
./scripts/02-setup-host-build.sh server

# 3. try the example (or skip and drop your own module under module/)
Expand Down Expand Up @@ -73,12 +73,12 @@ examples/chuck_norise/ worked example; `make use-example` copies i
scripts/00-check-target.sh preflight: ssh / sudo / headers / vmlinux / endpoint
scripts/01-provision-target.sh target-side: headers, vmlinux dbg, kernel source, GRUB args
(`--uninstall` to undo the GRUB args)
scripts/02-setup-host-build.sh dev-host: sync headers + vmlinux + source into .kernel-cache/
scripts/02-setup-host-build.sh dev-host: sync headers + vmlinux + source into kernel-cache/
scripts/03-build-module.sh dev-host: build module/ against the synced headers
scripts/04-deploy-and-prep-gdb.sh dev-host: upload, insmod, write .gdb/<target>-<method>.gdb (does NOT attach gdb)
scripts/lib/common.sh shared helpers (lab_ssh, lab_ssh_sudo, lab_rsync_from, ...)

.kernel-cache/<target>/ synced build/source/vmlinux (gitignored)
kernel-cache/<target>/ synced build/source/vmlinux (gitignored)
build/ per-target intermediate + final .ko (gitignored)
.gdb/ generated GDB init files (gitignored, regenerated each F5)

Expand Down
2 changes: 1 addition & 1 deletion scripts/00-check-target.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ esac
live_kernel="$(lab_ssh 'uname -r' 2>/dev/null || echo unknown)"
ok "kernel: $live_kernel"

cache_dir="$repo_root/.kernel-cache/$target"
cache_dir="$repo_root/kernel-cache/$target"
cached_kernel="$(cat "$cache_dir/kernel.release" 2>/dev/null || echo)"
if [[ -n "$cached_kernel" && "$cached_kernel" != "$live_kernel" ]]; then
warn "cached kernel ($cached_kernel) differs from live; re-run scripts/02-setup-host-build.sh $target"
Expand Down
8 changes: 4 additions & 4 deletions scripts/02-setup-host-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# Sync the target's kernel build tree to the host so an out-of-tree module
# can be cross-built against the target's exact kernel.
#
# Populates .kernel-cache/<target>/ with:
# Populates kernel-cache/<target>/ with:
# build/ -> synced linux-headers tree
# source/ -> synced linux-source tree (if --debug-symbols was used in 01)
# vmlinux -> debug-symbol vmlinux from the target (if available)
# kernel.release -> running kernel release
# remote.{build,header}.* -> bookkeeping
# Also updates .kernel-cache/current -> <target> so plain `make` and the
# Also updates kernel-cache/current -> <target> so plain `make` and the
# IntelliSense config track the most recently synced target.
set -euo pipefail

Expand Down Expand Up @@ -55,7 +55,7 @@ lab_check_connection
kernel="$(lab_ssh 'uname -r')"
echo " target $target is running $kernel"

cache_dir="$repo_root/.kernel-cache/$target"
cache_dir="$repo_root/kernel-cache/$target"
usr_src_dir="$cache_dir/usr-src"
build_dir="$cache_dir/build"
remote_vmlinux="/usr/lib/debug/boot/vmlinux-$kernel"
Expand Down Expand Up @@ -236,7 +236,7 @@ fi
printf '%s\n' "$kernel" > "$cache_dir/kernel.release"
printf '%s\n' "$build_real" > "$cache_dir/remote.build.path"
printf '%s\n' "${remote_header_dirs[@]}" > "$cache_dir/remote.header.paths"
ln -sfn "$target" "$repo_root/.kernel-cache/current"
ln -sfn "$target" "$repo_root/kernel-cache/current"

echo
echo "synced $target kernel $kernel"
Expand Down
2 changes: 1 addition & 1 deletion scripts/03-build-module.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "$repo_root/scripts/lib/common.sh"
validate_target "$target" "usage: $0 <target>"

cache_dir="$repo_root/.kernel-cache/$target"
cache_dir="$repo_root/kernel-cache/$target"
kernel_file="$cache_dir/kernel.release"
kdir="$cache_dir/build"

Expand Down
25 changes: 18 additions & 7 deletions scripts/04-deploy-and-prep-gdb.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
# 1. Best-effort kill of any local gdb holding the debug-endpoint TCP
# port (KGDB serial bridge and QEMU gdbstub each serve one client).
# 2. Upload module/<name>.ko, verify size matches.
# 3. Insmod in the background; poll /sys/module/<name>/sections/ for the
# runtime load addresses and emit an `add-symbol-file ...` line.
# 3. Insmod; poll /sys/module/<name>/sections/ for runtime addresses,
# stage a section-relocated copy of the .ko, and add-symbol-file it.
# 4. Emit .gdb/<target>-<method>.gdb (+ -attached variant) and the
# current-* symlinks the IDE launch configs point at.
#
Expand Down Expand Up @@ -41,7 +41,7 @@ insmod_wait_secs="${INSMOD_WAIT_SECS:-30}"

# --- Locate artifact + vmlinux, verify target is on the cached kernel ----

cache_dir="$repo_root/.kernel-cache/$target"
cache_dir="$repo_root/kernel-cache/$target"
kernel_file="$cache_dir/kernel.release"
vmlinux="$cache_dir/vmlinux"

Expand Down Expand Up @@ -171,12 +171,23 @@ load_and_discover_symbols() {
local text_addr
text_addr="$(awk '$1 == ".text" { print $2 }' "$tmp")"
if [[ -n "$text_addr" ]]; then
local cmd="add-symbol-file $artifact $text_addr"
# Pre-relocate the .ko: write each section's runtime
# address into its sh_addr so BFD bakes correct addresses into DWARF.
local relocated="$gdb_dir/$target-$debug_method-$module_name-relocated.ko"
local objcopy_args=()
local existing
existing="$(objdump -h "$artifact" | awk '$1 ~ /^[0-9]+$/ {print $2}')"
while read -r sec addr; do
[[ "$sec" != ".text" && -n "$addr" ]] && cmd+=" -s $sec $addr"
[[ -z "$addr" || -z "$sec" ]] && continue
grep -qxF "$sec" <<< "$existing" || continue
objcopy_args+=("--change-section-address" "$sec=$addr")
done < "$tmp"
rm -f "$relocated"
objcopy --no-change-warnings "${objcopy_args[@]}" \
"$artifact" "$relocated" \
|| die "objcopy failed to produce $relocated"
{
echo "$cmd"
printf 'add-symbol-file %s %s\n' "$relocated" "$text_addr"
printf 'echo loaded %s module symbols for %s\\n\n' "$module_name" "$target"
} > "$symbols_file"
rm -f "$tmp"
Expand Down Expand Up @@ -273,7 +284,7 @@ grep -vE '^(target remote |set mi-async |set target-async |set tcp connect-timeo

ln -sfn "$target-$debug_method.gdb" "$gdb_dir/current-debug.gdb"
ln -sfn "$target-$debug_method-attached.gdb" "$gdb_dir/current-debug-attached.gdb"
ln -sfn "../.kernel-cache/$target/vmlinux" "$gdb_dir/current-vmlinux"
ln -sfn "../kernel-cache/$target/vmlinux" "$gdb_dir/current-vmlinux"

echo
echo "ready. GDB endpoint: $debug_endpoint"
Expand Down
Loading