A quick rundown of how I do Linux kernel development in Emacs.
I have an iMac as my main desktop computer and I am a heavy Emacs user. I do a lot of work with the Linux kernel which I do remotely on a Linux PC and I use Eglot with the clangd language server over TRAMP. Here is an overview of my setup.
My desktop
My desktop computer is a 27" Intel iMac running macOS Sonoma (14.7) which I use for the majority of tasks.
I use Emacs as my main editor / development environment, whether it be for C, Go, Python, Raku, shell, yaml, json, or any number of other languages and file types that Emacs has a mode for.
I lean heavily on language servers when they are available and use Eglot, the Emacs built-in LSP client.
My Linux host
I used to do Linux hosted development in a VM running on my mac and sometimes this is still desirable, e.g. when I am on the road with my laptop. But performance really sucked for large projects like the Linux kernel so I have a 12 core AMD Ryzen host that I use as a Linux development server.
My Linux development server currently runs Fedora 41 and it has clangd
installed from the
clang-tools-extra
package.
Building Linux
A prerequisite for running clangd
in the kernel project is to first prepare a
compile_commands.json
file. There is a target in the kernel Makefile
for this and I
typically include it in every build command:
time make -j 24 bzImage modules compile_commands.json
Editing files
Emacs runs on my desktop mac and I open files remotely on the Linux host using the Emacs
built-in transparent remote access (TRAMP). For example, here I remotely open
net/core/rtnetlink.c
in my net-next
git worktree:
C-x C-f /ssh:linux-host:net-next/net/core/rtnetlink.c
Once I have a kernel project file open in Emacs, I can use Eglot to start the clangd
language
server:
M-x eglot
The Emacs modeline now shows a status indicator for Eglot: [eglot:net-next:5%]
. When indexing
is complete, the progress percentage is no longer displayed.

These are the most common navigation commands (when using the default key bindings):
M-.
– find definitions (go to definition if there is only one candidate)M-,
– go backM-?
– find references
Emacs configuration
There are a few essential C mode configuration settings for working on the Linux kernel
project, and I always want to run Eglot when I open kernel files. I have this configuration in
my .emacs
file:
(add-hook 'c-mode-common-hook
(lambda ()
(setq c-basic-offset 8)
(setq indent-tabs-mode t)
(setq tab-width 8)
(eglot-ensure)))
Preparing patches
When it comes to preparing a patch series for sending upstream, Magit is indispensable. It has great UX for interactively staging individual hunks and for preparing commit messages.

When a patch series needs to be refactored, interactive rebase is available within Magit. This makes it a breeze for ordering, editing, squashing or whatever else is needed to modify the patches.

Magit is incredibly powerful and I cannot do it justice here. Have a read of this Magit walk through to learn more.
Formatting and sending patches
When I am ready to generate a patch set for sending upstream, I use the git format-patch
command like this:
git format-patch -v1 --cover-letter --subject-prefix "PATCH net-next" "HEAD~10"
This creates a series of patch files, with a cover letter, named v1-0000-cover-letter.patch
,
and patches named v1-0001-...
, etc. The subject line of each email message has a prefix that
declares it is a patch targeting the net-next
tree.
I check that the patch series meets submission guidelines by running checkpatch.pl
:
./scripts/checkpatch.pl v1-00*
-------------------------------------------------------------------------------
/net/imac/Users/donaldh/git/kernel-patches/ynl/wiphy/v1-0000-cover-letter.patch
-------------------------------------------------------------------------------
total: 0 errors, 0 warnings, 0 lines checked
/net/imac/Users/donaldh/git/kernel-patches/ynl/wiphy/v1-0000-cover-letter.patch has no obvious style problems and is ready for submission.
--------------------------------------------------------------------------------------------------------------------
/net/imac/Users/donaldh/git/kernel-patches/ynl/wiphy/v1-0001-tools-net-ynl-remove-extraneous-plural-from-varia.patch
--------------------------------------------------------------------------------------------------------------------
total: 0 errors, 0 warnings, 21 lines checked
/net/imac/Users/donaldh/git/kernel-patches/ynl/wiphy/v1-0001-tools-net-ynl-remove-extraneous-plural-from-varia.patch has no obvious style problems and is ready for submission.
...
The get_maintainer.pl
script is used to identify the maintainers, reviewers and relevant
mailing lists that should be recipients of the patch series when it gets sent.
./scripts/get_maintainer.pl v1-00*
I then use git send-email
to send the patch series to the maintainers, reviewers and mailing
lists.
Expectations for contributions to the kernel networking subsystem can be found at https://docs.kernel.org/process/maintainer-netdev.html