Maintaining own custom kernel
Maintaining own custom kernel
This page walks through the whole flow of building a custom kernel on Argent and keeping it up to date: our kernel sources with a different config, or a different patched source (linux-tkg, a vanilla kernel with your patches, ...) with your config.
Your kernel becomes two packages in your overlay, built by the same argent-kernel eclass as ours, and installed next to our kernel, not over it. You don't edit our ebuilds, epkg update resets them.
All of it happens in devmode, so read Mixing Binaries and Compiling first if you haven't yet.
How it works
The eclass doesn't download a kernel from kernel.org or from git. It takes a source tarball, unpacks it, finds the kernel config inside it, and builds the kernel with that config. For our kernel, the tarball is linux-6.12.114-argent.tar.xz, downloaded from our server. For yours, it's a tarball you make and keep in /var/cache/distfiles.
That decides the order:
- switch to devmode
- prepare the source tree and the tarball
- create your overlay
- write the ebuilds
- make the manifests and install
- boot it
- keep it up to date
The source comes first. The ebuilds, the manifests and the eclass only read what you prepared in step 2. If the source tree, the config or the tarball is wrong, nothing after it works. When something fails later, step 2 is the first place to look.
Pick a name
Pick one name and use it everywhere. On this page it's mykernel, with our 6.12.114 sources:
| What | Name |
|---|---|
| packages | sys-kernel/linux-mykernel and sys-kernel/mykernel-sources
|
kernel (uname -r) |
6.12.114-mykernel
|
| source tree | /var/cache/distfiles/linux-6.12.114-mykernel/
|
| config in the source tree | mykernel/config/mykernel-6.12-amd64.config
|
| tarball | /var/cache/distfiles/linux-6.12.114-mykernel.tar.xz
|
| both ebuilds | K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
|
The eclass uses this name for the tarball, the config, the initramfs and the DKMS modules. If one of them still says argent, dracut builds the initramfs for our kernel instead of yours, and removing your kernel deletes ours.
Any name works, except argent, that one is ours.
Where your files are
| Path | What |
|---|---|
/var/cache/distfiles/linux-6.12.114-mykernel/ |
your source tree with your config, where you work |
/var/cache/distfiles/linux-6.12.114-mykernel.tar.xz |
the tarball portage builds your kernel from |
/var/db/repos/myoverlay/sys-kernel/ |
your ebuilds |
/etc/portage/repos.conf/eselect-repo.conf |
tells portage your overlay exists |
Keep the source tree and the tarball in /var/cache/distfiles. It's the DISTDIR in the make.conf of every mode, the only place where portage looks for source archives. Our ebuilds point to our server, yours point to a file that exists only on your disk, so portage has to find it there every time it builds or rebuilds your kernel.
Nothing of ours deletes it: epkg update, epkg clean, epkg wipe and the avasile mode switches leave /var/cache/distfiles alone. It's still the only copy of your kernel, so keep a backup of the source tree and the tarball on another disk.
Step 1: switch to devmode
avasile --devmode
Check it:
avasile --status
It has to say avasile is on --devmode!.
User mode doesn't work for this: it has no ebuilds, so no way to fetch our kernel sources, and it never compiles, while everything from your overlay gets compiled.
A mode switch deletes the whole /etc/portage, your files too. If you already have files there, copy them out before you switch, and put them back after. See Avasile System Management. If compiling fails right after the switch, see missing build tools in devmode.
Step 2: prepare the source
Do this before you write any ebuild. Everything in this step happens in /var/cache/distfiles, as root.
2.1 Get the source tree
From our sources. Download our tarball, unpack it, and give the tree your name:
epkg fetchsourcepkg =sys-kernel/argent-sources-6.12.114
cd /var/cache/distfiles
tar -xJf linux-6.12.114-argent.tar.xz
mv linux-6.12.114-argent linux-6.12.114-mykernel
From another source (linux-tkg, a vanilla kernel with your patches, ...). Put the patched tree in /var/cache/distfiles, named linux-<version>-mykernel. The version is the one the tree reports:
cd /var/cache/distfiles/linux-7.3.1-mykernel
make -s kernelversion
That version goes everywhere else on this page too. For 7.3.1, the ebuilds are linux-mykernel-7.3.1.ebuild and mykernel-sources-7.3.1.ebuild, with K_ROGKERNEL_FORCE_UPPERLEVEL="7.3" and K_ROGKERNEL_FORCE_SUBLEVEL="1", and the config is mykernel-7.3-amd64.config.
2.2 Make your config
cd /var/cache/distfiles/linux-6.12.114-mykernel
Start from our config. From our sources, it's already in the tree:
cp argent/config/argent-6.12-amd64.config .config
For another source, take it out of our tarball (download it with epkg fetchsourcepkg as above), and let the kernel adapt it to its version:
tar -xJOf /var/cache/distfiles/linux-6.12.114-argent.tar.xz linux-6.12.114-argent/argent/config/argent-6.12-amd64.config > .config
make olddefconfig
Then change what you want:
make menuconfig
2.3 Put the config where the eclass looks for it
The eclass looks for <name>-<major.minor>-amd64.config in the <name>/config/ directory of the tree:
mkdir -p mykernel/config
cp .config mykernel/config/mykernel-6.12-amd64.config
Remove our config directory (it's there only if you started from our sources), and clean the tree, so the tarball doesn't carry your build files:
rm -rf argent
make mrproper
2.4 Check the tree
ls /var/cache/distfiles/linux-6.12.114-mykernel/mykernel/config/
It has to show mykernel-6.12-amd64.config. The tree looks like this now:
/var/cache/distfiles/
└── linux-6.12.114-mykernel/
├── Makefile
├── arch/
├── ...
└── mykernel/
└── config/
└── mykernel-6.12-amd64.config
2.5 Pack the tarball
Pack it from /var/cache/distfiles, with a relative path, so the tarball starts with the tree:
cd /var/cache/distfiles
tar -pcJf linux-6.12.114-mykernel.tar.xz linux-6.12.114-mykernel
Check it, the first line has to be linux-6.12.114-mykernel/:
tar -tJf linux-6.12.114-mykernel.tar.xz | head -1
If it shows var/cache/distfiles/..., the tarball was packed with the full path, pack it again from /var/cache/distfiles as above.
Keep the tree next to the tarball, you need it for every config change.
Step 3: create your overlay
eselect repository create myoverlay
The overlay is in /var/db/repos/myoverlay. Your ebuilds use the argent-kernel eclass from argent-ws, so your overlay has to see it. /var/db/repos/myoverlay/metadata/layout.conf has to contain:
masters = gentoo argent-ws thin-manifests = true
eselect repository registers the overlay in /etc/portage/repos.conf/eselect-repo.conf. That file survives epkg update, but a mode switch removes it, so keep a copy.
Step 4: write the ebuilds
cd /var/db/repos/myoverlay
mkdir -p sys-kernel/linux-mykernel sys-kernel/mykernel-sources
sys-kernel/linux-mykernel/linux-mykernel-6.12.114.ebuild:
EAPI=8 K_ROGKERNEL_SELF_TARBALL_NAME="mykernel" K_REQUIRED_LINUX_FIRMWARE_VER="20260622" K_ROGKERNEL_FORCE_SUBLEVEL="114" K_ROGKERNEL_FORCE_UPPERLEVEL="6.12" K_ROGKERNEL_PATCH_UPSTREAM_TARBALL="0" K_KERNEL_NEW_VERSIONING="1" inherit argent-kernel KEYWORDS="amd64" DESCRIPTION="Custom kernel image" RESTRICT="mirror" IUSE="grub2"
sys-kernel/mykernel-sources/mykernel-sources-6.12.114.ebuild:
EAPI=8
K_ROGKERNEL_FORCE_SUBLEVEL="114"
K_ROGKERNEL_FORCE_UPPERLEVEL="6.12"
K_ROGKERNEL_NAME="mykernel"
K_ROGKERNEL_URI_CONFIG="yes"
K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
K_ONLY_SOURCES="1"
K_KERNEL_NEW_VERSIONING="1"
inherit argent-kernel
KEYWORDS="amd64"
DESCRIPTION="Custom kernel sources"
RESTRICT="mirror"
IUSE="grub2 sources_standalone"
DEPEND="${DEPEND}
sources_standalone? ( !=sys-kernel/linux-mykernel-${PVR} )
!sources_standalone? ( =sys-kernel/linux-mykernel-${PVR} )"
What's different from our linux-argent and argent-sources:
K_ROGKERNEL_SELF_TARBALL_NAMEismykernelin bothK_ROGKERNEL_NAMEismykernelin the sources ebuild (inlinux-mykernelit comes from the package name)- the sources depend on
linux-mykernel, not onlinux-argent
The download address in the ebuilds points to our server, where your tarball doesn't exist. That's fine, portage finds it in /var/cache/distfiles and doesn't download anything. It's also why the tarball has to stay there.
Optional: keep your config next to the ebuilds
The config inside the tarball is enough. If you'd rather change the config without packing the tarball again, keep a copy in files/ of both packages, and let src_prepare() copy it over the one from the tarball:
mkdir -p sys-kernel/linux-mykernel/files sys-kernel/mykernel-sources/files
cp /var/cache/distfiles/linux-6.12.114-mykernel/mykernel/config/mykernel-6.12-amd64.config sys-kernel/linux-mykernel/files/
cp /var/cache/distfiles/linux-6.12.114-mykernel/mykernel/config/mykernel-6.12-amd64.config sys-kernel/mykernel-sources/files/
And add this at the end of both ebuilds:
src_prepare() {
argent-kernel_src_prepare
cp "${FILESDIR}/mykernel-6.12-amd64.config" "${S}/mykernel/config/" || die
}
From now on, the file in files/ wins over the one in the tarball. Change it there, in both packages. Your overlay uses thin manifests, so it needs no new manifest for it. When the major version changes, the file name in src_prepare() changes too.
Step 5: manifest and install
The manifests are made from your tarball in /var/cache/distfiles. If it isn't there, go back to step 2.
cd /var/db/repos/myoverlay
ebuild sys-kernel/linux-mykernel/linux-mykernel-6.12.114.ebuild manifest
ebuild sys-kernel/mykernel-sources/mykernel-sources-6.12.114.ebuild manifest
epkg install sys-kernel/mykernel-sources
This pulls in linux-mykernel too, and compiles both, there is no binary of your kernel on our binhost. With USE=grub2, the grub menu is regenerated at the end, otherwise run:
grub-mkconfig -o /boot/grub/grub.cfg
And rebuild the external modules (nvidia, virtualbox, zfs, ...) for your kernel:
epkg module-rebuild
Step 6: boot it
Check that the kernel and the initramfs carry your name:
ls /boot/*mykernel*
The list has to include initramfs-genkernel-x86_64-6.12.114-mykernel. If the initramfs is missing, or it says argent, one of the names from Pick a name is wrong.
Reboot, pick your kernel in the GRUB menu, and check:
uname -r
It has to print 6.12.114-mykernel. Our kernel stays installed, so if yours doesn't boot, pick ours in the GRUB menu and fix yours from there.
Step 7: keep it up to date
Your kernel doesn't follow ours. When we move linux-argent to a new version, nothing changes for yours, you decide when to move.
Upgrading the system
With a custom kernel, never upgrade with just epkg upgrade. Always upgrade like this:
epkg update && epkg upgrade --keep-going y && epkg module-rebuild
or, with all the build dependencies too:
epkg update && epkg upgrade-full --keep-going y && epkg module-rebuild
epkg updatesyncsgentooandargent-wsfirst--keep-going y: in devmode some packages get compiled, and if one of them fails, portage goes on with the rest instead of stopping the whole upgradeepkg module-rebuild: the external modules on our binhost (nvidia, virtualbox, zfs, ...) are built for our kernel, so when an upgrade brings a new version of one, your kernel doesn't have it until you rebuild itupgrade-fullalso upgrades the build dependencies (--with-bdeps=y), the packages needed only for compiling, like the ones your kernel and its modules are built with
A new version
- Go through step 2 again with the new source,
linux-6.12.120-mykernelfor example. For the config, start from yours instead of ours: copy/var/cache/distfiles/linux-6.12.114-mykernel/mykernel/config/mykernel-6.12-amd64.configinto the new tree as.config, and runmake olddefconfig(ormake oldconfig, to answer the new options one by one). - Copy your ebuilds to the new version (
linux-mykernel-6.12.120.ebuild,mykernel-sources-6.12.120.ebuild), and changeK_ROGKERNEL_FORCE_SUBLEVEL. - Make the manifests and install, as in step 5.
Inside the same major version (6.12.x), the new version replaces the old one. A new major version (6.12 to 6.18 for example) installs next to the old one, and there K_ROGKERNEL_FORCE_UPPERLEVEL and the config name change too (mykernel-6.18-amd64.config, also in src_prepare() if you use it). When the new one boots, remove the old one:
epkg remove sys-kernel/linux-mykernel:6.12 sys-kernel/mykernel-sources:6.12
Once the new version works, you can delete the old tree, the old tarball and the old ebuilds.
Changing only the config
Same version, different config. There are two ways.
In the tarball. Change the config in the tree, which is still in /var/cache/distfiles:
cd /var/cache/distfiles/linux-6.12.114-mykernel
cp mykernel/config/mykernel-6.12-amd64.config .config
make menuconfig
cp .config mykernel/config/mykernel-6.12-amd64.config
make mrproper
Pack it again, as in 2.5. The checksums in the manifests don't match the new tarball anymore, so delete both manifests before you make them again, otherwise ebuild ... manifest moves your new tarball aside as a failed download:
cd /var/db/repos/myoverlay
rm sys-kernel/linux-mykernel/Manifest sys-kernel/mykernel-sources/Manifest
Then make them again, as in step 5.
In files/, if you use the optional config next to the ebuilds: change the file in files/ of both packages. No new tarball, no new manifest.
Either way, the version didn't change, and devmode saves every package it compiles in /var/cache/binpkgs, so portage would install the binary it saved last time, with the old config. Rebuild without it:
epkg install --getbinpkg=n --usepkg=n sys-kernel/mykernel-sources sys-kernel/linux-mykernel
After a mode switch
/var/cache/distfiles and /var/db/repos/myoverlay stay as they are. /etc/portage/repos.conf/eselect-repo.conf is gone, put your copy back, otherwise portage doesn't see your overlay anymore.
epkg update syncs only gentoo and argent-ws. Your overlay exists only on your disk, there is nothing to sync.
Removing your kernel
epkg remove sys-kernel/mykernel-sources sys-kernel/linux-mykernel
Because all the names match, this removes your kernel and its initramfs, and leaves ours alone. Without USE=grub2, regenerate the grub menu after it:
grub-mkconfig -o /boot/grub/grub.cfg
TL;DR Oneliners for Experts
avasile --devmode
avasile --status
export MY_CUSTOM_KERNEL_VERSION="6.12"
export MY_CUSTOM_KERNEL_SUBLEVEL="114"
export MY_CUSTOM_KERNEL_FULL_VERSION="${MY_CUSTOM_KERNEL_VERSION}.${MY_CUSTOM_KERNEL_SUBLEVEL}"
epkg fetchsourcepkg =sys-kernel/argent-sources-${MY_CUSTOM_KERNEL_FULL_VERSION}
cd /var/cache/distfiles
tar -xJf linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-argent.tar.xz
mv linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-argent linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
cd linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
cp argent/config/argent-${MY_CUSTOM_KERNEL_VERSION}-amd64.config .config
make menuconfig
mkdir -p mykernel/config
cp .config mykernel/config/mykernel-${MY_CUSTOM_KERNEL_VERSION}-amd64.config
rm -rf argent
make mrproper
cd /var/cache/distfiles
tar -pcJf linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel.tar.xz linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
tar -tJf linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel.tar.xz | head -1
eselect repository create myoverlay
sed -i 's|^masters = .*|masters = gentoo argent-ws|' /var/db/repos/myoverlay/metadata/layout.conf
mkdir -p /var/db/repos/myoverlay/sys-kernel/linux-mykernel /var/db/repos/myoverlay/sys-kernel/mykernel-sources
cat > /var/db/repos/myoverlay/sys-kernel/linux-mykernel/linux-mykernel-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild <<EOF
EAPI=8
K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
K_REQUIRED_LINUX_FIRMWARE_VER="20260622"
K_ROGKERNEL_FORCE_SUBLEVEL="${MY_CUSTOM_KERNEL_SUBLEVEL}"
K_ROGKERNEL_FORCE_UPPERLEVEL="${MY_CUSTOM_KERNEL_VERSION}"
K_ROGKERNEL_PATCH_UPSTREAM_TARBALL="0"
K_KERNEL_NEW_VERSIONING="1"
inherit argent-kernel
KEYWORDS="amd64"
DESCRIPTION="Custom kernel image"
RESTRICT="mirror"
IUSE="grub2"
EOF
cat > /var/db/repos/myoverlay/sys-kernel/mykernel-sources/mykernel-sources-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild <<EOF
EAPI=8
K_ROGKERNEL_FORCE_SUBLEVEL="${MY_CUSTOM_KERNEL_SUBLEVEL}"
K_ROGKERNEL_FORCE_UPPERLEVEL="${MY_CUSTOM_KERNEL_VERSION}"
K_ROGKERNEL_NAME="mykernel"
K_ROGKERNEL_URI_CONFIG="yes"
K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
K_ONLY_SOURCES="1"
K_KERNEL_NEW_VERSIONING="1"
inherit argent-kernel
KEYWORDS="amd64"
DESCRIPTION="Custom kernel sources"
RESTRICT="mirror"
IUSE="grub2 sources_standalone"
DEPEND="\${DEPEND}
sources_standalone? ( !=sys-kernel/linux-mykernel-\${PVR} )
!sources_standalone? ( =sys-kernel/linux-mykernel-\${PVR} )"
EOF
cd /var/db/repos/myoverlay
ebuild sys-kernel/linux-mykernel/linux-mykernel-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild manifest
ebuild sys-kernel/mykernel-sources/mykernel-sources-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild manifest
epkg install sys-kernel/mykernel-sources
grub-mkconfig -o /boot/grub/grub.cfg
epkg module-rebuild
ls /boot/*mykernel*
reboot
uname -r
epkg update && epkg upgrade --keep-going y && epkg module-rebuild
TL;DR Oneliners for Experts Using TKG kernel source
avasile --devmode
avasile --status
export MY_CUSTOM_KERNEL_VERSION="6.12"
export MY_CUSTOM_KERNEL_SUBLEVEL="114"
export MY_CUSTOM_KERNEL_FULL_VERSION="${MY_CUSTOM_KERNEL_VERSION}.${MY_CUSTOM_KERNEL_SUBLEVEL}"
cd /root
git clone https://github.com/Frogging-Family/linux-tkg.git
cd linux-tkg
sed -i -e 's|^_distro=.*|_distro="Gentoo"|' -e "s|^_version=.*|_version=\"v${MY_CUSTOM_KERNEL_FULL_VERSION}\"|" -e 's|^_configfile=.*|_configfile="running-kernel"|' customization.cfg
./install.sh config
cp -a linux-src-git /var/cache/distfiles/linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
cd /var/cache/distfiles/linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
rm -rf .git
make menuconfig
mkdir -p mykernel/config
cp .config mykernel/config/mykernel-${MY_CUSTOM_KERNEL_VERSION}-amd64.config
make mrproper
cd /var/cache/distfiles
tar -pcJf linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel.tar.xz linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel
tar -tJf linux-${MY_CUSTOM_KERNEL_FULL_VERSION}-mykernel.tar.xz | head -1
eselect repository create myoverlay
sed -i 's|^masters = .*|masters = gentoo argent-ws|' /var/db/repos/myoverlay/metadata/layout.conf
mkdir -p /var/db/repos/myoverlay/sys-kernel/linux-mykernel /var/db/repos/myoverlay/sys-kernel/mykernel-sources
cat > /var/db/repos/myoverlay/sys-kernel/linux-mykernel/linux-mykernel-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild <<EOF
EAPI=8
K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
K_REQUIRED_LINUX_FIRMWARE_VER="20260622"
K_ROGKERNEL_FORCE_SUBLEVEL="${MY_CUSTOM_KERNEL_SUBLEVEL}"
K_ROGKERNEL_FORCE_UPPERLEVEL="${MY_CUSTOM_KERNEL_VERSION}"
K_ROGKERNEL_PATCH_UPSTREAM_TARBALL="0"
K_KERNEL_NEW_VERSIONING="1"
inherit argent-kernel
KEYWORDS="amd64"
DESCRIPTION="Custom kernel image"
RESTRICT="mirror"
IUSE="grub2"
EOF
cat > /var/db/repos/myoverlay/sys-kernel/mykernel-sources/mykernel-sources-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild <<EOF
EAPI=8
K_ROGKERNEL_FORCE_SUBLEVEL="${MY_CUSTOM_KERNEL_SUBLEVEL}"
K_ROGKERNEL_FORCE_UPPERLEVEL="${MY_CUSTOM_KERNEL_VERSION}"
K_ROGKERNEL_NAME="mykernel"
K_ROGKERNEL_URI_CONFIG="yes"
K_ROGKERNEL_SELF_TARBALL_NAME="mykernel"
K_ONLY_SOURCES="1"
K_KERNEL_NEW_VERSIONING="1"
inherit argent-kernel
KEYWORDS="amd64"
DESCRIPTION="Custom kernel sources"
RESTRICT="mirror"
IUSE="grub2 sources_standalone"
DEPEND="\${DEPEND}
sources_standalone? ( !=sys-kernel/linux-mykernel-\${PVR} )
!sources_standalone? ( =sys-kernel/linux-mykernel-\${PVR} )"
EOF
cd /var/db/repos/myoverlay
ebuild sys-kernel/linux-mykernel/linux-mykernel-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild manifest
ebuild sys-kernel/mykernel-sources/mykernel-sources-${MY_CUSTOM_KERNEL_FULL_VERSION}.ebuild manifest
epkg install sys-kernel/mykernel-sources
grub-mkconfig -o /boot/grub/grub.cfg
epkg module-rebuild
ls /boot/*mykernel*
reboot
uname -r
epkg update && epkg upgrade --keep-going y && epkg module-rebuild
All the steps above, in both TL;DR sections, are done only once. After that, maintaining your custom kernel means:
- Archiving the new version of the kernel: the new tree with your config, packed as
linux-6.12.120-mykernel.tar.xzin/var/cache/distfiles - Copying the ebuilds to the new version
- Changing the versions of the kernel in the new ebuilds (
K_ROGKERNEL_FORCE_SUBLEVEL, andK_ROGKERNEL_FORCE_UPPERLEVELfor a new major version)