Imported from pentago/linux-custom (
AGENTS.md). Install upstream withnpx skills add pentago/linux-custom. Copyright stays with the author.
AGENTS.md
Repository scope
- Workspace root:
/home/dzhi/linux-custom - This is not a conventional app repo.
- Relevant root-level items include:
custom.patch— currently emptylinux/— a nested Arch Linux kernel packaging repository
- Most meaningful changes will happen in
linux/, especially:linux/PKGBUILDlinux/.SRCINFOlinux/config.x86_64linux/.nvchecker.tomllinux/REUSE.toml
- The outer
.gitignoreignoreslinux/, so always confirm whether you are editing the outer repo or the nestedlinux/repo.
Existing editor/agent rules
- No
.cursorrulesfile is present in this workspace. - No
.cursor/rules/directory is present in this workspace. - No
.github/copilot-instructions.mdfile is present in this workspace. - This file is the primary repository instruction file for coding agents.
What this repo does
This repo has two layers:
Outer repo (workspace root)
- Contains
build.sh— an automated script that fetches the stock ArchlinuxPKGBUILD, patches it inline to create a customizedlinux-customkernel, and builds it withmakepkg -s. - Contains
custom.patch— currently empty and unused. - The outer
.gitignoreignoreslinux/.
Inner repo (linux/)
- A nested Arch Linux kernel packaging repository (separate git history).
linux/PKGBUILDpackages the stock Archlinuxkernel.- Sources come from
kernel.org; Arch's release patch is fetched from GitHub. prepare()sets local version markers, applies patch files, copiesconfig.$CARCH, and runsmake olddefconfig.build()runs:make allmake -C tools/bpf/bpftool vmlinux.h feature-clang-bpf-co-re=1make htmldocs SPHINXOPTS=-QT
- Packaging logic lives in
_package(),_package-headers(), and_package-docs().
build.sh — custom kernel build script
What it does
- Runs
modprobed-db storeto refresh the module database - Fetches a fresh Arch
linuxPKGBUILD viaparu -G linuxinto./linux(replacing any existing contents) - Patches the PKGBUILD inline with sed/awk (content-matching patterns only, no line numbers)
- Runs 29 post-patch grep assertions to verify all modifications applied
- Runs
makepkg -sto build the customized kernel
PKGBUILD modifications applied (in order)
- Rename
pkgbase=linux→pkgbase=linux-custom - Remove htmldocs makedepends block (
# htmldocscomment throughtexlive-latexextra) - Remove
make htmldocsfrombuild() - Remove
_package-docs()function entirely - Remove
"$pkgbase-docs"frompkgnamearray - Inject into
prepare()after the firstmake olddefconfig:yes "" | make LSMOD=$HOME/.config/modprobed.db localmodconfig(trim to used modules, auto-accept defaults for new config options)scripts/configcalls for 12 kernel config options (see below)scripts/config --modulefor 2 initramfs-critical modules (CRYPTO_LZ4,DM_INTEGRITY) missed bylocalmodconfigscripts/config --modulefor 15 Docker/container modules (BRIDGE,VETH,OVERLAY_FS,NF_CONNTRACK,NF_NAT,VXLAN,MACVLAN,IPVLAN,XFRM_USER, and iptables modules) missed bylocalmodconfig- A second
make olddefconfigto resolve dependencies
Kernel config optimizations
| Option | Action | Rationale |
|---|---|---|
CC_OPTIMIZE_FOR_PERFORMANCE |
disable | Replaced by -O3 below |
CC_OPTIMIZE_FOR_PERFORMANCE_O3 |
enable | Clang -O3 optimization (default is -O2). ~1-3% improvement in kernel-heavy workloads |
X86_NATIVE_CPU |
enable | -march=native at kernel level (mainline 6.16+) |
CPU_MITIGATIONS |
disable | Single toggle cascades to all 25 MITIGATION_* options |
TRANSPARENT_HUGEPAGE_ALWAYS |
disable | Switch THP to madvise-only |
TRANSPARENT_HUGEPAGE_MADVISE |
enable | Better for gaming/desktop workloads |
TCP_CONG_BBR |
enable | Built-in (was module) |
DEFAULT_TCP_CONG |
set "bbr" |
BBR as default congestion control |
NET_SCH_FQ |
enable | Fair queueing scheduler (BBR companion) |
NR_CPUS |
set 64 |
Down from 8192 (Ryzen 9 9955HX = 16 cores) |
DEBUG_INFO_BTF |
enable | Explicit BTF data for BPF tooling (bpftool vmlinux.h). Keeps stock DWARF5 |
LTO_CLANG_THIN |
enable | ThinLTO via Clang. Cross-TU link-time optimization, ~3-5% improvement |
CRYPTO_LZ4 |
module | Required by mkinitcpio systemd hook. Missed by localmodconfig (loaded on-demand by crypto subsystem) |
DM_INTEGRITY |
module | Required by mkinitcpio sd-encrypt hook. Missed by localmodconfig |
BRIDGE |
module | Docker container networking (docker0 bridge). Missed by localmodconfig |
VETH |
module | Virtual ethernet pairs for containers. Missed by localmodconfig |
OVERLAY_FS |
enable | Docker default storage driver. Missed by localmodconfig |
NF_CONNTRACK |
module | Connection tracking for container NAT. Missed by localmodconfig |
NF_NAT |
module | NAT for container internet access. Missed by localmodconfig |
NETFILTER_XT_MATCH_ADDRTYPE |
module | iptables address type matching for Docker |
NETFILTER_XT_MATCH_CONNTRACK |
module | iptables conntrack matching for Docker |
NETFILTER_XT_MARK |
module | Packet marking for Docker networking |
IP_NF_NAT |
module | IPv4 NAT for Docker |
IP_NF_TARGET_MASQUERADE |
module | NAT masquerade for container internet access |
IP_NF_TARGET_REJECT |
module | REJECT target for Docker firewall rules |
IP_NF_MANGLE |
module | Packet mangling for Docker networking |
VXLAN |
module | Overlay networking (Docker Swarm/Compose) |
MACVLAN |
module | macvlan network driver for Docker |
IPVLAN |
module | ipvlan network driver for Docker |
XFRM_USER |
module | IPsec for encrypted overlay networks |
Key design decisions
- sed/awk not unified diff: Patches via content-matching sed/awk patterns, not a
.patchfile. This is resilient to upstream PKGBUILD line number changes across kernel releases. - Build in
./linux: Script fetches into./linuxrelative tobuild.shlocation. Thelinux/directory is.gitignored and replaced fresh on every run. $HOMEfor paths: Variables use$HOME(not~— tilde doesn't expand inside double-quoted assignments).- makepkg.conf BUILDDIR respected: The user's
makepkg.confBUILDDIR(tmpfs) is used bymakepkgfor actual compilation. - No graysky2 patch needed:
CONFIG_X86_NATIVE_CPUis in mainline since 6.16. - BBRv1/v2 not v3: BBRv3 is not in mainline as of 6.19.
- localmodconfig ordering: Must be after
make olddefconfig(needs a valid.config), andscripts/configmust be afterlocalmodconfig(to override any module decisions). Usesyes "" |to auto-accept defaults for new config options introduced in kernel updates, preventing interactive prompts. - ThinLTO via Clang:
CONFIG_LTO_CLANG_THINenabled. Cross-TU link-time optimization for ~3-5% improvement. Requires LLVM toolchain (export LLVM=1+ clang/llvm/lld makedepends). - Source caching:
SRCDESTis exported inbuild.sh(not in makepkg.conf) to$SCRIPT_DIR/sources. Avoids re-downloading kernel source tarballs on subsequent runs. Thesources/directory is gitignored. - DEBUG_INFO_BTF required: Cannot use
DEBUG_INFO_NONE— Arch'sbuild()runsbpftool vmlinux.hwhich needs BTF data in vmlinux, which requires DWARF debug info. StockDEBUG_INFO_DWARF5is kept andDEBUG_INFO_BTFis explicitly enabled.
Modifying build.sh
- All sed/awk patterns match CONTENT, not line numbers — verify patterns still match if the upstream Arch PKGBUILD changes.
- The single awk pass handles htmldocs makedepends block removal,
_package-docs()removal, and config injection aftermake olddefconfig— if Arch changes function formatting or makedepends block structure, the awk patterns may need updating. - After modifying, always run:
bash -n build.shand re-verify grep assertion expected counts. - The 29 grep assertions in the script itself catch broken patches at runtime — keep them in sync with any sed/awk changes.
Environment requirements
paru(AUR helper) installedmodprobed-dbinstalled with database at$HOME/.config/modprobed.dbmakepkgand kernel build dependencies (bc, rust-bindgen, etc.)clang,llvm,lld(Clang toolchain, required for ThinLTO)- Interactive sudo available (for
makepkg -sdependency installation) - User's
makepkg.confalready has-march=native,-j$(nproc), ccache, mold — these apply automatically
Command reference
Run these from linux/ unless stated otherwise.
Build/package
- Full package build with dependency install:
makepkg -s
- Full package build without dependency resolution:
makepkg
- Prepare only (download, extract, patch, config):
makepkg -o
- Reuse prepared sources and continue:
makepkg -e
- Force rebuild:
makepkg -f
Metadata maintenance
- Regenerate
.SRCINFOafter changingPKGBUILDin any way that affects generated package metadata or sources:makepkg --printsrcinfo > .SRCINFO
- Refresh checksums when any referenced source entry or local source file changes:
updpkgsums
Lint/test reality
- There is no repo-defined linter.
- There is no repo-defined unit test framework.
- There is no built-in single-test command.
- The nearest valid verification steps are:
makepkg -ofor patch/config preparation checksmakepkgfor full build verificationmakepkg -eonly when reusing an already extracted/prepared source tree
“Run a single test” guidance
- If asked to run a single test, explain that this repository does not define test cases or a test runner.
- Use the narrowest real validation available:
makepkg -owhen validating patch application or config refresh- full
makepkgwhen validating the actual package build
- If finer validation is needed for a kernel-specific change, use upstream kernel
maketargets inside the prepared source tree and document exactly what you ran. Those commands are not standardized by this repo.
Files and ownership
build.sh- custom kernel build script at repo root; fetches, patches, and builds the kernel
- uses sed/awk content patterns — no line-number-based modifications
- contains 29 grep assertions that self-verify all patches applied correctly
linux/PKGBUILD- source of truth for package metadata, sources, and build/package phases
- build.sh fetches a fresh copy via
paru -G linuxinto./linux, replacing any existing contents
linux/.SRCINFO- generated from
PKGBUILD; keep in sync
- generated from
linux/config.x86_64- kernel configuration input; preserve format and treat its generated style as authoritative
custom.patch- root-level patch file; currently empty, and not referenced by
linux/PKGBUILDas checked today
- root-level patch file; currently empty, and not referenced by
linux/.nvchecker.toml- version-tracking config for Arch kernel tags from GitHub
linux/REUSE.toml- REUSE license annotation config for package files and configs
Style guide
These conventions come from the actual files in this workspace, especially linux/PKGBUILD.
Shell / PKGBUILD style
- Use 2-space indentation.
- Keep function braces on the same line:
prepare() {
- Prefer lowercase names for variables and functions.
- Helper/private names may use a leading underscore:
_srcname_package()
- Reserve uppercase for environment variables and established build variables:
KBUILD_BUILD_HOSTKBUILD_BUILD_USERSOURCE_DATE_EPOCHCARCH
Arrays and quoting
- Follow standard PKGBUILD multiline arrays:
makedepends=( ... )pkgname=( ... )
- Keep one item per line for longer arrays.
- Preserve existing quoting style.
- Quote paths and parameter expansions unless the current shell pattern intentionally depends on word splitting.
Shell idioms already used here
- Prefer
localfor function-scoped variables. - Use
$(<file)for concise file reads when matching existing style. - Use
[[ ... ]]for tests. - Use
casefor architecture branching. - Iterate arrays in the normal Bash style:
for src in "${source[@]}"; do
- Keep status output explicit with short
echomessages before important phases.
Error handling
- Let command exit status fail fast by default.
- Add explicit guards only when a clearer message is needed.
- Follow existing patterns such as:
echo "Unknown CARCH $CARCH"; exit 1diff -u ../config.$CARCH .config || :
- Do not swallow real failures silently.
Naming conventions
- Keep Arch PKGBUILD variable names exact:
pkgbase,pkgver,pkgrel,pkgname,makedepends,optdepends
- Keep helper names descriptive and aligned with package phases.
- Leave kernel config naming untouched:
CONFIG_FOO=y# CONFIG_BAR is not set
Config and generated files
config.x86_64declares itself automatically generated; avoid cosmetic rewrites and keep manual deltas minimal..SRCINFOshould be regenerated instead of manually reformatted..nvchecker.tomlandREUSE.tomluse simple TOML; keep changes minimal and consistent with existing layout.
Change rules
- If you edit
PKGBUILDin a way that affects generated metadata, sources, dependencies, or package relationships, regenerate.SRCINFO. - If you change source declarations or any referenced local source file such as
config.x86_64, update checksums as needed. - If you change architecture behavior, re-check the
case $CARCH inlogic. - If you change packaging paths, inspect all package functions, not only
_package(). - If you change kernel config, make the smallest necessary delta.
What not to assume
- Do not invent Node, Python, Cargo, or Rust project commands for this repo.
- Do not claim lint/test commands exist when they do not.
- Do not apply generic app-repo guidelines here.
- Do not hand-edit generated files when regeneration is the right workflow.
- Do not assume
custom.patchis active in the build unlessPKGBUILDreferences it.
Recommended verification checklist
- After
build.shedits:- run
bash -n build.shfor syntax check - verify grep assertion expected counts still match (run the sed/awk on a copy of
linux/PKGBUILDand count) - if adding new sed/awk patterns, add corresponding grep assertions
- run
- After
PKGBUILDedits:- reread the edited functions
- regenerate
.SRCINFOif required - run
makepkg -oat minimum for patch/config logic changes
- After packaging/build changes:
- run
makepkgif feasible
- run
- After config-only changes:
- preserve
config.x86_64syntax and formatting - prefer
makepkg -oor a full build when feasible
- preserve
- After metadata-only changes:
- confirm
.SRCINFOmatchesPKGBUILD
- confirm
Practical summary
- Start by deciding whether the change belongs at repo root or under
linux/. - Read
linux/PKGBUILDbefore making build assumptions. - Use Arch packaging conventions, not generic software-project conventions.
- Prefer minimal, surgical edits.
- Keep generated files synchronized.
- When asked for “tests”, explain the absence of a test framework and run the closest valid packaging/build verification instead.